1*1c60b9acSAndroid Build Coastguard Worker /* 2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation 3*1c60b9acSAndroid Build Coastguard Worker * 4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2019 Andy Green <[email protected]> 5*1c60b9acSAndroid Build Coastguard Worker * 6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy 7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to 8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the 9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is 11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions: 12*1c60b9acSAndroid Build Coastguard Worker * 13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in 14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software. 15*1c60b9acSAndroid Build Coastguard Worker * 16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE. 23*1c60b9acSAndroid Build Coastguard Worker */ 24*1c60b9acSAndroid Build Coastguard Worker 25*1c60b9acSAndroid Build Coastguard Worker /*! \defgroup jws JSON Web Signature 26*1c60b9acSAndroid Build Coastguard Worker * ## JSON Web Signature API 27*1c60b9acSAndroid Build Coastguard Worker * 28*1c60b9acSAndroid Build Coastguard Worker * Lws provides an API to check and create RFC7515 JSON Web Signatures 29*1c60b9acSAndroid Build Coastguard Worker * 30*1c60b9acSAndroid Build Coastguard Worker * SHA256/384/512 HMAC, and RSA 256/384/512 are supported. 31*1c60b9acSAndroid Build Coastguard Worker * 32*1c60b9acSAndroid Build Coastguard Worker * The API uses your TLS library crypto, but works exactly the same no matter 33*1c60b9acSAndroid Build Coastguard Worker * what your TLS backend is. 34*1c60b9acSAndroid Build Coastguard Worker */ 35*1c60b9acSAndroid Build Coastguard Worker ///@{ 36*1c60b9acSAndroid Build Coastguard Worker 37*1c60b9acSAndroid Build Coastguard Worker /* 38*1c60b9acSAndroid Build Coastguard Worker * The maps are built to work with both JWS (LJWS_) and JWE (LJWE_), and are 39*1c60b9acSAndroid Build Coastguard Worker * sized to the slightly larger JWE case. 40*1c60b9acSAndroid Build Coastguard Worker */ 41*1c60b9acSAndroid Build Coastguard Worker 42*1c60b9acSAndroid Build Coastguard Worker enum enum_jws_sig_elements { 43*1c60b9acSAndroid Build Coastguard Worker 44*1c60b9acSAndroid Build Coastguard Worker /* JWS block namespace */ 45*1c60b9acSAndroid Build Coastguard Worker LJWS_JOSE, 46*1c60b9acSAndroid Build Coastguard Worker LJWS_PYLD, 47*1c60b9acSAndroid Build Coastguard Worker LJWS_SIG, 48*1c60b9acSAndroid Build Coastguard Worker LJWS_UHDR, 49*1c60b9acSAndroid Build Coastguard Worker 50*1c60b9acSAndroid Build Coastguard Worker /* JWE block namespace */ 51*1c60b9acSAndroid Build Coastguard Worker LJWE_JOSE = 0, 52*1c60b9acSAndroid Build Coastguard Worker LJWE_EKEY, 53*1c60b9acSAndroid Build Coastguard Worker LJWE_IV, 54*1c60b9acSAndroid Build Coastguard Worker LJWE_CTXT, 55*1c60b9acSAndroid Build Coastguard Worker LJWE_ATAG, 56*1c60b9acSAndroid Build Coastguard Worker LJWE_AAD, 57*1c60b9acSAndroid Build Coastguard Worker 58*1c60b9acSAndroid Build Coastguard Worker LWS_JWS_MAX_COMPACT_BLOCKS 59*1c60b9acSAndroid Build Coastguard Worker }; 60*1c60b9acSAndroid Build Coastguard Worker 61*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map { 62*1c60b9acSAndroid Build Coastguard Worker const char *buf[LWS_JWS_MAX_COMPACT_BLOCKS]; 63*1c60b9acSAndroid Build Coastguard Worker uint32_t len[LWS_JWS_MAX_COMPACT_BLOCKS]; 64*1c60b9acSAndroid Build Coastguard Worker }; 65*1c60b9acSAndroid Build Coastguard Worker 66*1c60b9acSAndroid Build Coastguard Worker #define LWS_JWS_MAX_SIGS 3 67*1c60b9acSAndroid Build Coastguard Worker 68*1c60b9acSAndroid Build Coastguard Worker struct lws_jws { 69*1c60b9acSAndroid Build Coastguard Worker struct lws_jwk *jwk; /* the struct lws_jwk containing the signing key */ 70*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context; /* the lws context (used to get random) */ 71*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map map, map_b64; 72*1c60b9acSAndroid Build Coastguard Worker }; 73*1c60b9acSAndroid Build Coastguard Worker 74*1c60b9acSAndroid Build Coastguard Worker /* jws EC signatures do not have ASN.1 in them, meaning they're incompatible 75*1c60b9acSAndroid Build Coastguard Worker * with generic signatures. 76*1c60b9acSAndroid Build Coastguard Worker */ 77*1c60b9acSAndroid Build Coastguard Worker 78*1c60b9acSAndroid Build Coastguard Worker /** 79*1c60b9acSAndroid Build Coastguard Worker * lws_jws_init() - initialize a jws for use 80*1c60b9acSAndroid Build Coastguard Worker * 81*1c60b9acSAndroid Build Coastguard Worker * \param jws: pointer to the jws to initialize 82*1c60b9acSAndroid Build Coastguard Worker * \param jwk: the jwk to use with this jws 83*1c60b9acSAndroid Build Coastguard Worker * \param context: the lws_context to use 84*1c60b9acSAndroid Build Coastguard Worker */ 85*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN void 86*1c60b9acSAndroid Build Coastguard Worker lws_jws_init(struct lws_jws *jws, struct lws_jwk *jwk, 87*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context); 88*1c60b9acSAndroid Build Coastguard Worker 89*1c60b9acSAndroid Build Coastguard Worker /** 90*1c60b9acSAndroid Build Coastguard Worker * lws_jws_destroy() - scrub a jws 91*1c60b9acSAndroid Build Coastguard Worker * 92*1c60b9acSAndroid Build Coastguard Worker * \param jws: pointer to the jws to destroy 93*1c60b9acSAndroid Build Coastguard Worker * 94*1c60b9acSAndroid Build Coastguard Worker * Call before the jws goes out of scope. 95*1c60b9acSAndroid Build Coastguard Worker * 96*1c60b9acSAndroid Build Coastguard Worker * Elements defined in the jws are zeroed. 97*1c60b9acSAndroid Build Coastguard Worker */ 98*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN void 99*1c60b9acSAndroid Build Coastguard Worker lws_jws_destroy(struct lws_jws *jws); 100*1c60b9acSAndroid Build Coastguard Worker 101*1c60b9acSAndroid Build Coastguard Worker /** 102*1c60b9acSAndroid Build Coastguard Worker * lws_jws_sig_confirm_compact() - check signature 103*1c60b9acSAndroid Build Coastguard Worker * 104*1c60b9acSAndroid Build Coastguard Worker * \param map: pointers and lengths for each of the unencoded JWS elements 105*1c60b9acSAndroid Build Coastguard Worker * \param jwk: public key 106*1c60b9acSAndroid Build Coastguard Worker * \param context: lws_context 107*1c60b9acSAndroid Build Coastguard Worker * \param temp: scratchpad 108*1c60b9acSAndroid Build Coastguard Worker * \param temp_len: length of scratchpad 109*1c60b9acSAndroid Build Coastguard Worker * 110*1c60b9acSAndroid Build Coastguard Worker * Confirms the signature on a JWS. Use if you have non-b64 plain JWS elements 111*1c60b9acSAndroid Build Coastguard Worker * in a map... it'll make a temp b64 version needed for comparison. See below 112*1c60b9acSAndroid Build Coastguard Worker * for other variants. 113*1c60b9acSAndroid Build Coastguard Worker * 114*1c60b9acSAndroid Build Coastguard Worker * Returns 0 on match, else nonzero. 115*1c60b9acSAndroid Build Coastguard Worker */ 116*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 117*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_compact(struct lws_jws_map *map, struct lws_jwk *jwk, 118*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context, 119*1c60b9acSAndroid Build Coastguard Worker char *temp, int *temp_len); 120*1c60b9acSAndroid Build Coastguard Worker 121*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 122*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_compact_b64_map(struct lws_jws_map *map_b64, 123*1c60b9acSAndroid Build Coastguard Worker struct lws_jwk *jwk, 124*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context, 125*1c60b9acSAndroid Build Coastguard Worker char *temp, int *temp_len); 126*1c60b9acSAndroid Build Coastguard Worker 127*1c60b9acSAndroid Build Coastguard Worker /** 128*1c60b9acSAndroid Build Coastguard Worker * lws_jws_sig_confirm_compact_b64() - check signature on b64 compact JWS 129*1c60b9acSAndroid Build Coastguard Worker * 130*1c60b9acSAndroid Build Coastguard Worker * \param in: pointer to b64 jose.payload[.hdr].sig 131*1c60b9acSAndroid Build Coastguard Worker * \param len: bytes available at \p in 132*1c60b9acSAndroid Build Coastguard Worker * \param map: map to take decoded non-b64 content 133*1c60b9acSAndroid Build Coastguard Worker * \param jwk: public key 134*1c60b9acSAndroid Build Coastguard Worker * \param context: lws_context 135*1c60b9acSAndroid Build Coastguard Worker * \param temp: scratchpad 136*1c60b9acSAndroid Build Coastguard Worker * \param temp_len: size of scratchpad 137*1c60b9acSAndroid Build Coastguard Worker * 138*1c60b9acSAndroid Build Coastguard Worker * Confirms the signature on a JWS. Use if you have you have b64 compact layout 139*1c60b9acSAndroid Build Coastguard Worker * (jose.payload.hdr.sig) as an aggregated string... it'll make a temp plain 140*1c60b9acSAndroid Build Coastguard Worker * version needed for comparison. 141*1c60b9acSAndroid Build Coastguard Worker * 142*1c60b9acSAndroid Build Coastguard Worker * Returns 0 on match, else nonzero. 143*1c60b9acSAndroid Build Coastguard Worker */ 144*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 145*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_compact_b64(const char *in, size_t len, 146*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map *map, 147*1c60b9acSAndroid Build Coastguard Worker struct lws_jwk *jwk, 148*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context, 149*1c60b9acSAndroid Build Coastguard Worker char *temp, int *temp_len); 150*1c60b9acSAndroid Build Coastguard Worker 151*1c60b9acSAndroid Build Coastguard Worker /** 152*1c60b9acSAndroid Build Coastguard Worker * lws_jws_sig_confirm() - check signature on plain + b64 JWS elements 153*1c60b9acSAndroid Build Coastguard Worker * 154*1c60b9acSAndroid Build Coastguard Worker * \param map_b64: pointers and lengths for each of the b64-encoded JWS elements 155*1c60b9acSAndroid Build Coastguard Worker * \param map: pointers and lengths for each of the unencoded JWS elements 156*1c60b9acSAndroid Build Coastguard Worker * \param jwk: public key 157*1c60b9acSAndroid Build Coastguard Worker * \param context: lws_context 158*1c60b9acSAndroid Build Coastguard Worker * 159*1c60b9acSAndroid Build Coastguard Worker * Confirms the signature on a JWS. Use if you have you already have both b64 160*1c60b9acSAndroid Build Coastguard Worker * compact layout (jose.payload.hdr.sig) and decoded JWS elements in maps. 161*1c60b9acSAndroid Build Coastguard Worker * 162*1c60b9acSAndroid Build Coastguard Worker * If you had the b64 string and called lws_jws_compact_decode() on it, you 163*1c60b9acSAndroid Build Coastguard Worker * will end up with both maps, and can use this api version, saving needlessly 164*1c60b9acSAndroid Build Coastguard Worker * regenerating any temp map. 165*1c60b9acSAndroid Build Coastguard Worker * 166*1c60b9acSAndroid Build Coastguard Worker * Returns 0 on match, else nonzero. 167*1c60b9acSAndroid Build Coastguard Worker */ 168*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 169*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm(struct lws_jws_map *map_b64, /* b64-encoded */ 170*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map *map, /* non-b64 */ 171*1c60b9acSAndroid Build Coastguard Worker struct lws_jwk *jwk, struct lws_context *context); 172*1c60b9acSAndroid Build Coastguard Worker 173*1c60b9acSAndroid Build Coastguard Worker /** 174*1c60b9acSAndroid Build Coastguard Worker * lws_jws_sign_from_b64() - add b64 sig to b64 hdr + payload 175*1c60b9acSAndroid Build Coastguard Worker * 176*1c60b9acSAndroid Build Coastguard Worker * \param jose: jose header information 177*1c60b9acSAndroid Build Coastguard Worker * \param jws: information to include in the signature 178*1c60b9acSAndroid Build Coastguard Worker * \param b64_sig: output buffer for b64 signature 179*1c60b9acSAndroid Build Coastguard Worker * \param sig_len: size of \p b64_sig output buffer 180*1c60b9acSAndroid Build Coastguard Worker * 181*1c60b9acSAndroid Build Coastguard Worker * This adds a b64-coded JWS signature of the b64-encoded protected header 182*1c60b9acSAndroid Build Coastguard Worker * and b64-encoded payload, at \p b64_sig. The signature will be as large 183*1c60b9acSAndroid Build Coastguard Worker * as the N element of the RSA key when the RSA key is used, eg, 512 bytes for 184*1c60b9acSAndroid Build Coastguard Worker * a 4096-bit key, and then b64-encoding on top. 185*1c60b9acSAndroid Build Coastguard Worker * 186*1c60b9acSAndroid Build Coastguard Worker * In some special cases, there is only payload to sign and no header, in that 187*1c60b9acSAndroid Build Coastguard Worker * case \p b64_hdr may be NULL, and only the payload will be hashed before 188*1c60b9acSAndroid Build Coastguard Worker * signing. 189*1c60b9acSAndroid Build Coastguard Worker * 190*1c60b9acSAndroid Build Coastguard Worker * If successful, returns the length of the encoded signature written to 191*1c60b9acSAndroid Build Coastguard Worker * \p b64_sig. If the jose signing type is unknown, 0 is returned. Otherwise 192*1c60b9acSAndroid Build Coastguard Worker * -1 indicates failure. 193*1c60b9acSAndroid Build Coastguard Worker */ 194*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 195*1c60b9acSAndroid Build Coastguard Worker lws_jws_sign_from_b64(struct lws_jose *jose, struct lws_jws *jws, char *b64_sig, 196*1c60b9acSAndroid Build Coastguard Worker size_t sig_len); 197*1c60b9acSAndroid Build Coastguard Worker 198*1c60b9acSAndroid Build Coastguard Worker /** 199*1c60b9acSAndroid Build Coastguard Worker * lws_jws_compact_decode() - converts and maps compact serialization b64 sections 200*1c60b9acSAndroid Build Coastguard Worker * 201*1c60b9acSAndroid Build Coastguard Worker * \param in: the incoming compact serialized b64 202*1c60b9acSAndroid Build Coastguard Worker * \param len: the length of the incoming compact serialized b64 203*1c60b9acSAndroid Build Coastguard Worker * \param map: pointer to the results structure 204*1c60b9acSAndroid Build Coastguard Worker * \param map_b64: NULL, or pointer to a second results structure taking block 205*1c60b9acSAndroid Build Coastguard Worker * information about the undecoded b64 206*1c60b9acSAndroid Build Coastguard Worker * \param out: buffer to hold decoded results 207*1c60b9acSAndroid Build Coastguard Worker * \param out_len: size of out in bytes 208*1c60b9acSAndroid Build Coastguard Worker * 209*1c60b9acSAndroid Build Coastguard Worker * Returns number of sections (2 if "none", else 3), or -1 if illegal. 210*1c60b9acSAndroid Build Coastguard Worker * 211*1c60b9acSAndroid Build Coastguard Worker * map is set to point to the start and hold the length of each decoded block. 212*1c60b9acSAndroid Build Coastguard Worker * If map_b64 is non-NULL, then it's set with information about the input b64 213*1c60b9acSAndroid Build Coastguard Worker * blocks. 214*1c60b9acSAndroid Build Coastguard Worker */ 215*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 216*1c60b9acSAndroid Build Coastguard Worker lws_jws_compact_decode(const char *in, int len, struct lws_jws_map *map, 217*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map *map_b64, char *out, int *out_len); 218*1c60b9acSAndroid Build Coastguard Worker 219*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 220*1c60b9acSAndroid Build Coastguard Worker lws_jws_compact_encode(struct lws_jws_map *map_b64, /* b64-encoded */ 221*1c60b9acSAndroid Build Coastguard Worker const struct lws_jws_map *map, /* non-b64 */ 222*1c60b9acSAndroid Build Coastguard Worker char *buf, int *out_len); 223*1c60b9acSAndroid Build Coastguard Worker 224*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 225*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_json(const char *in, size_t len, 226*1c60b9acSAndroid Build Coastguard Worker struct lws_jws *jws, struct lws_jwk *jwk, 227*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context, 228*1c60b9acSAndroid Build Coastguard Worker char *temp, int *temp_len); 229*1c60b9acSAndroid Build Coastguard Worker 230*1c60b9acSAndroid Build Coastguard Worker /** 231*1c60b9acSAndroid Build Coastguard Worker * lws_jws_write_flattened_json() - create flattened JSON sig 232*1c60b9acSAndroid Build Coastguard Worker * 233*1c60b9acSAndroid Build Coastguard Worker * \param jws: information to include in the signature 234*1c60b9acSAndroid Build Coastguard Worker * \param flattened: output buffer for JSON 235*1c60b9acSAndroid Build Coastguard Worker * \param len: size of \p flattened output buffer 236*1c60b9acSAndroid Build Coastguard Worker * 237*1c60b9acSAndroid Build Coastguard Worker */ 238*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 239*1c60b9acSAndroid Build Coastguard Worker lws_jws_write_flattened_json(struct lws_jws *jws, char *flattened, size_t len); 240*1c60b9acSAndroid Build Coastguard Worker 241*1c60b9acSAndroid Build Coastguard Worker /** 242*1c60b9acSAndroid Build Coastguard Worker * lws_jws_write_compact() - create flattened JSON sig 243*1c60b9acSAndroid Build Coastguard Worker * 244*1c60b9acSAndroid Build Coastguard Worker * \param jws: information to include in the signature 245*1c60b9acSAndroid Build Coastguard Worker * \param compact: output buffer for compact format 246*1c60b9acSAndroid Build Coastguard Worker * \param len: size of \p flattened output buffer 247*1c60b9acSAndroid Build Coastguard Worker * 248*1c60b9acSAndroid Build Coastguard Worker */ 249*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 250*1c60b9acSAndroid Build Coastguard Worker lws_jws_write_compact(struct lws_jws *jws, char *compact, size_t len); 251*1c60b9acSAndroid Build Coastguard Worker 252*1c60b9acSAndroid Build Coastguard Worker 253*1c60b9acSAndroid Build Coastguard Worker 254*1c60b9acSAndroid Build Coastguard Worker /* 255*1c60b9acSAndroid Build Coastguard Worker * below apis are not normally needed if dealing with whole JWS... they're 256*1c60b9acSAndroid Build Coastguard Worker * useful for creating from scratch 257*1c60b9acSAndroid Build Coastguard Worker */ 258*1c60b9acSAndroid Build Coastguard Worker 259*1c60b9acSAndroid Build Coastguard Worker 260*1c60b9acSAndroid Build Coastguard Worker /** 261*1c60b9acSAndroid Build Coastguard Worker * lws_jws_dup_element() - allocate space for an element and copy data into it 262*1c60b9acSAndroid Build Coastguard Worker * 263*1c60b9acSAndroid Build Coastguard Worker * \param map: map to create the element in 264*1c60b9acSAndroid Build Coastguard Worker * \param idx: index of element in the map to create 265*1c60b9acSAndroid Build Coastguard Worker * \param temp: space to allocate in 266*1c60b9acSAndroid Build Coastguard Worker * \param temp_len: available space at temp 267*1c60b9acSAndroid Build Coastguard Worker * \param in: data to duplicate into element 268*1c60b9acSAndroid Build Coastguard Worker * \param in_len: length of data to duplicate 269*1c60b9acSAndroid Build Coastguard Worker * \param actual_alloc: 0 for same as in_len, else actual allocation size 270*1c60b9acSAndroid Build Coastguard Worker * 271*1c60b9acSAndroid Build Coastguard Worker * Copies in_len from in to temp, if temp_len is sufficient. 272*1c60b9acSAndroid Build Coastguard Worker * 273*1c60b9acSAndroid Build Coastguard Worker * Returns 0 or -1 if not enough space in temp / temp_len. 274*1c60b9acSAndroid Build Coastguard Worker * 275*1c60b9acSAndroid Build Coastguard Worker * Over-allocation can be acheived by setting actual_alloc to the real 276*1c60b9acSAndroid Build Coastguard Worker * allocation desired... in_len will be copied into it. 277*1c60b9acSAndroid Build Coastguard Worker * 278*1c60b9acSAndroid Build Coastguard Worker * *temp_len is reduced by actual_alloc if successful. 279*1c60b9acSAndroid Build Coastguard Worker */ 280*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 281*1c60b9acSAndroid Build Coastguard Worker lws_jws_dup_element(struct lws_jws_map *map, int idx, 282*1c60b9acSAndroid Build Coastguard Worker char *temp, int *temp_len, const void *in, size_t in_len, 283*1c60b9acSAndroid Build Coastguard Worker size_t actual_alloc); 284*1c60b9acSAndroid Build Coastguard Worker 285*1c60b9acSAndroid Build Coastguard Worker /** 286*1c60b9acSAndroid Build Coastguard Worker * lws_jws_randomize_element() - create an element and fill with random 287*1c60b9acSAndroid Build Coastguard Worker * 288*1c60b9acSAndroid Build Coastguard Worker * \param context: lws_context used for random 289*1c60b9acSAndroid Build Coastguard Worker * \param map: map to create the element in 290*1c60b9acSAndroid Build Coastguard Worker * \param idx: index of element in the map to create 291*1c60b9acSAndroid Build Coastguard Worker * \param temp: space to allocate in 292*1c60b9acSAndroid Build Coastguard Worker * \param temp_len: available space at temp 293*1c60b9acSAndroid Build Coastguard Worker * \param random_len: length of data to fill with random 294*1c60b9acSAndroid Build Coastguard Worker * \param actual_alloc: 0 for same as random_len, else actual allocation size 295*1c60b9acSAndroid Build Coastguard Worker * 296*1c60b9acSAndroid Build Coastguard Worker * Randomize random_len bytes at temp, if temp_len is sufficient. 297*1c60b9acSAndroid Build Coastguard Worker * 298*1c60b9acSAndroid Build Coastguard Worker * Returns 0 or -1 if not enough space in temp / temp_len. 299*1c60b9acSAndroid Build Coastguard Worker * 300*1c60b9acSAndroid Build Coastguard Worker * Over-allocation can be acheived by setting actual_alloc to the real 301*1c60b9acSAndroid Build Coastguard Worker * allocation desired... the first random_len will be filled with random. 302*1c60b9acSAndroid Build Coastguard Worker * 303*1c60b9acSAndroid Build Coastguard Worker * *temp_len is reduced by actual_alloc if successful. 304*1c60b9acSAndroid Build Coastguard Worker */ 305*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 306*1c60b9acSAndroid Build Coastguard Worker lws_jws_randomize_element(struct lws_context *context, 307*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map *map, 308*1c60b9acSAndroid Build Coastguard Worker int idx, char *temp, int *temp_len, size_t random_len, 309*1c60b9acSAndroid Build Coastguard Worker size_t actual_alloc); 310*1c60b9acSAndroid Build Coastguard Worker 311*1c60b9acSAndroid Build Coastguard Worker /** 312*1c60b9acSAndroid Build Coastguard Worker * lws_jws_alloc_element() - create an element and reserve space for content 313*1c60b9acSAndroid Build Coastguard Worker * 314*1c60b9acSAndroid Build Coastguard Worker * \param map: map to create the element in 315*1c60b9acSAndroid Build Coastguard Worker * \param idx: index of element in the map to create 316*1c60b9acSAndroid Build Coastguard Worker * \param temp: space to allocate in 317*1c60b9acSAndroid Build Coastguard Worker * \param temp_len: available space at temp 318*1c60b9acSAndroid Build Coastguard Worker * \param len: logical length of element 319*1c60b9acSAndroid Build Coastguard Worker * \param actual_alloc: 0 for same as len, else actual allocation size 320*1c60b9acSAndroid Build Coastguard Worker * 321*1c60b9acSAndroid Build Coastguard Worker * Allocate len bytes at temp, if temp_len is sufficient. 322*1c60b9acSAndroid Build Coastguard Worker * 323*1c60b9acSAndroid Build Coastguard Worker * Returns 0 or -1 if not enough space in temp / temp_len. 324*1c60b9acSAndroid Build Coastguard Worker * 325*1c60b9acSAndroid Build Coastguard Worker * Over-allocation can be acheived by setting actual_alloc to the real 326*1c60b9acSAndroid Build Coastguard Worker * allocation desired... the element logical length will be set to len. 327*1c60b9acSAndroid Build Coastguard Worker * 328*1c60b9acSAndroid Build Coastguard Worker * *temp_len is reduced by actual_alloc if successful. 329*1c60b9acSAndroid Build Coastguard Worker */ 330*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 331*1c60b9acSAndroid Build Coastguard Worker lws_jws_alloc_element(struct lws_jws_map *map, int idx, char *temp, 332*1c60b9acSAndroid Build Coastguard Worker int *temp_len, size_t len, size_t actual_alloc); 333*1c60b9acSAndroid Build Coastguard Worker 334*1c60b9acSAndroid Build Coastguard Worker /** 335*1c60b9acSAndroid Build Coastguard Worker * lws_jws_encode_b64_element() - create an b64-encoded element 336*1c60b9acSAndroid Build Coastguard Worker * 337*1c60b9acSAndroid Build Coastguard Worker * \param map: map to create the element in 338*1c60b9acSAndroid Build Coastguard Worker * \param idx: index of element in the map to create 339*1c60b9acSAndroid Build Coastguard Worker * \param temp: space to allocate in 340*1c60b9acSAndroid Build Coastguard Worker * \param temp_len: available space at temp 341*1c60b9acSAndroid Build Coastguard Worker * \param in: pointer to unencoded input 342*1c60b9acSAndroid Build Coastguard Worker * \param in_len: length of unencoded input 343*1c60b9acSAndroid Build Coastguard Worker * 344*1c60b9acSAndroid Build Coastguard Worker * Allocate len bytes at temp, if temp_len is sufficient. 345*1c60b9acSAndroid Build Coastguard Worker * 346*1c60b9acSAndroid Build Coastguard Worker * Returns 0 or -1 if not enough space in temp / temp_len. 347*1c60b9acSAndroid Build Coastguard Worker * 348*1c60b9acSAndroid Build Coastguard Worker * Over-allocation can be acheived by setting actual_alloc to the real 349*1c60b9acSAndroid Build Coastguard Worker * allocation desired... the element logical length will be set to len. 350*1c60b9acSAndroid Build Coastguard Worker * 351*1c60b9acSAndroid Build Coastguard Worker * *temp_len is reduced by actual_alloc if successful. 352*1c60b9acSAndroid Build Coastguard Worker */ 353*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 354*1c60b9acSAndroid Build Coastguard Worker lws_jws_encode_b64_element(struct lws_jws_map *map, int idx, 355*1c60b9acSAndroid Build Coastguard Worker char *temp, int *temp_len, const void *in, 356*1c60b9acSAndroid Build Coastguard Worker size_t in_len); 357*1c60b9acSAndroid Build Coastguard Worker 358*1c60b9acSAndroid Build Coastguard Worker 359*1c60b9acSAndroid Build Coastguard Worker /** 360*1c60b9acSAndroid Build Coastguard Worker * lws_jws_b64_compact_map() - find block starts and lengths in compact b64 361*1c60b9acSAndroid Build Coastguard Worker * 362*1c60b9acSAndroid Build Coastguard Worker * \param in: pointer to b64 jose.payload[.hdr].sig 363*1c60b9acSAndroid Build Coastguard Worker * \param len: bytes available at \p in 364*1c60b9acSAndroid Build Coastguard Worker * \param map: output struct with pointers and lengths for each JWS element 365*1c60b9acSAndroid Build Coastguard Worker * 366*1c60b9acSAndroid Build Coastguard Worker * Scans a jose.payload[.hdr].sig b64 string and notes where the blocks start 367*1c60b9acSAndroid Build Coastguard Worker * and their length into \p map. 368*1c60b9acSAndroid Build Coastguard Worker * 369*1c60b9acSAndroid Build Coastguard Worker * Returns number of blocks if OK. May return <0 if malformed. 370*1c60b9acSAndroid Build Coastguard Worker * May not fill all map entries. 371*1c60b9acSAndroid Build Coastguard Worker */ 372*1c60b9acSAndroid Build Coastguard Worker 373*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 374*1c60b9acSAndroid Build Coastguard Worker lws_jws_b64_compact_map(const char *in, int len, struct lws_jws_map *map); 375*1c60b9acSAndroid Build Coastguard Worker 376*1c60b9acSAndroid Build Coastguard Worker 377*1c60b9acSAndroid Build Coastguard Worker /** 378*1c60b9acSAndroid Build Coastguard Worker * lws_jws_base64_enc() - encode input data into b64url data 379*1c60b9acSAndroid Build Coastguard Worker * 380*1c60b9acSAndroid Build Coastguard Worker * \param in: the incoming plaintext 381*1c60b9acSAndroid Build Coastguard Worker * \param in_len: the length of the incoming plaintext in bytes 382*1c60b9acSAndroid Build Coastguard Worker * \param out: the buffer to store the b64url encoded data to 383*1c60b9acSAndroid Build Coastguard Worker * \param out_max: the length of \p out in bytes 384*1c60b9acSAndroid Build Coastguard Worker * 385*1c60b9acSAndroid Build Coastguard Worker * Returns either -1 if problems, or the number of bytes written to \p out. 386*1c60b9acSAndroid Build Coastguard Worker */ 387*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 388*1c60b9acSAndroid Build Coastguard Worker lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max); 389*1c60b9acSAndroid Build Coastguard Worker 390*1c60b9acSAndroid Build Coastguard Worker /** 391*1c60b9acSAndroid Build Coastguard Worker * lws_jws_encode_section() - encode input data into b64url data, 392*1c60b9acSAndroid Build Coastguard Worker * prepending . if not first 393*1c60b9acSAndroid Build Coastguard Worker * 394*1c60b9acSAndroid Build Coastguard Worker * \param in: the incoming plaintext 395*1c60b9acSAndroid Build Coastguard Worker * \param in_len: the length of the incoming plaintext in bytes 396*1c60b9acSAndroid Build Coastguard Worker * \param first: nonzero if the first section 397*1c60b9acSAndroid Build Coastguard Worker * \param p: the buffer to store the b64url encoded data to 398*1c60b9acSAndroid Build Coastguard Worker * \param end: just past the end of p 399*1c60b9acSAndroid Build Coastguard Worker * 400*1c60b9acSAndroid Build Coastguard Worker * Returns either -1 if problems, or the number of bytes written to \p out. 401*1c60b9acSAndroid Build Coastguard Worker * If the section is not the first one, '.' is prepended. 402*1c60b9acSAndroid Build Coastguard Worker */ 403*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 404*1c60b9acSAndroid Build Coastguard Worker lws_jws_encode_section(const char *in, size_t in_len, int first, char **p, 405*1c60b9acSAndroid Build Coastguard Worker char *end); 406*1c60b9acSAndroid Build Coastguard Worker 407*1c60b9acSAndroid Build Coastguard Worker /** 408*1c60b9acSAndroid Build Coastguard Worker * lws_jwt_signed_validate() - check a compact JWT against a key and alg 409*1c60b9acSAndroid Build Coastguard Worker * 410*1c60b9acSAndroid Build Coastguard Worker * \param ctx: the lws_context 411*1c60b9acSAndroid Build Coastguard Worker * \param jwk: the key for checking the signature 412*1c60b9acSAndroid Build Coastguard Worker * \param alg_list: the expected alg name, like "ES512" 413*1c60b9acSAndroid Build Coastguard Worker * \param com: the compact JWT 414*1c60b9acSAndroid Build Coastguard Worker * \param len: the length of com 415*1c60b9acSAndroid Build Coastguard Worker * \param temp: a temp scratchpad 416*1c60b9acSAndroid Build Coastguard Worker * \param tl: available length of temp scratchpad 417*1c60b9acSAndroid Build Coastguard Worker * \param out: the output buffer to hold the validated plaintext 418*1c60b9acSAndroid Build Coastguard Worker * \param out_len: on entry, max length of out; on exit, used length of out 419*1c60b9acSAndroid Build Coastguard Worker * 420*1c60b9acSAndroid Build Coastguard Worker * Returns nonzero if the JWT cannot be validated or the plaintext can't fit the 421*1c60b9acSAndroid Build Coastguard Worker * provided output buffer, or 0 if it is validated as being signed by the 422*1c60b9acSAndroid Build Coastguard Worker * provided jwk. 423*1c60b9acSAndroid Build Coastguard Worker * 424*1c60b9acSAndroid Build Coastguard Worker * If validated, the plaintext in the JWT is copied into out and out_len set to 425*1c60b9acSAndroid Build Coastguard Worker * the used length. 426*1c60b9acSAndroid Build Coastguard Worker * 427*1c60b9acSAndroid Build Coastguard Worker * temp can be discarded or reused after the call returned, it's used to hold 428*1c60b9acSAndroid Build Coastguard Worker * transformations of the B64 JWS in the JWT. 429*1c60b9acSAndroid Build Coastguard Worker */ 430*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 431*1c60b9acSAndroid Build Coastguard Worker lws_jwt_signed_validate(struct lws_context *ctx, struct lws_jwk *jwk, 432*1c60b9acSAndroid Build Coastguard Worker const char *alg_list, const char *com, size_t len, 433*1c60b9acSAndroid Build Coastguard Worker char *temp, int tl, char *out, size_t *out_len); 434*1c60b9acSAndroid Build Coastguard Worker 435*1c60b9acSAndroid Build Coastguard Worker /** 436*1c60b9acSAndroid Build Coastguard Worker * lws_jwt_sign_compact() - generate a compact JWT using a key and alg 437*1c60b9acSAndroid Build Coastguard Worker * 438*1c60b9acSAndroid Build Coastguard Worker * \param ctx: the lws_context 439*1c60b9acSAndroid Build Coastguard Worker * \param jwk: the signing key 440*1c60b9acSAndroid Build Coastguard Worker * \param alg: the signing alg name, like "ES512" 441*1c60b9acSAndroid Build Coastguard Worker * \param out: the output buffer to hold the signed JWT in compact form 442*1c60b9acSAndroid Build Coastguard Worker * \param out_len: on entry, the length of out; on exit, the used amount of out 443*1c60b9acSAndroid Build Coastguard Worker * \param temp: a temp scratchpad 444*1c60b9acSAndroid Build Coastguard Worker * \param tl: available length of temp scratchpad 445*1c60b9acSAndroid Build Coastguard Worker * \param format: a printf style format specification 446*1c60b9acSAndroid Build Coastguard Worker * \param ...: zero or more args for the format specification 447*1c60b9acSAndroid Build Coastguard Worker * 448*1c60b9acSAndroid Build Coastguard Worker * Creates a JWT in a single step, from the format string and args through to 449*1c60b9acSAndroid Build Coastguard Worker * outputting a well-formed compact JWT representation in out. 450*1c60b9acSAndroid Build Coastguard Worker * 451*1c60b9acSAndroid Build Coastguard Worker * Returns 0 if all is well and *out_len is the amount of data in out, else 452*1c60b9acSAndroid Build Coastguard Worker * nonzero if failed. Temp must be large enough to hold various intermediate 453*1c60b9acSAndroid Build Coastguard Worker * representations. 454*1c60b9acSAndroid Build Coastguard Worker */ 455*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 456*1c60b9acSAndroid Build Coastguard Worker lws_jwt_sign_compact(struct lws_context *ctx, struct lws_jwk *jwk, 457*1c60b9acSAndroid Build Coastguard Worker const char *alg, char *out, size_t *out_len, char *temp, 458*1c60b9acSAndroid Build Coastguard Worker int tl, const char *format, ...) LWS_FORMAT(8); 459*1c60b9acSAndroid Build Coastguard Worker 460*1c60b9acSAndroid Build Coastguard Worker struct lws_jwt_sign_info { 461*1c60b9acSAndroid Build Coastguard Worker const char *alg; 462*1c60b9acSAndroid Build Coastguard Worker /**< entry: signing alg name, like "RS256" */ 463*1c60b9acSAndroid Build Coastguard Worker const char *jose_hdr; 464*1c60b9acSAndroid Build Coastguard Worker /**< entry: optional JOSE hdr; if present, alg field is ignored; instead the 465*1c60b9acSAndroid Build Coastguard Worker * whole claim object has to be provided in this parameter */ 466*1c60b9acSAndroid Build Coastguard Worker size_t jose_hdr_len; 467*1c60b9acSAndroid Build Coastguard Worker /**< entry: if jose_hdr is not NULL, JOSE header length without terminating '\0' */ 468*1c60b9acSAndroid Build Coastguard Worker char *out; 469*1c60b9acSAndroid Build Coastguard Worker /**< exit: signed JWT in compact form*/ 470*1c60b9acSAndroid Build Coastguard Worker size_t *out_len; 471*1c60b9acSAndroid Build Coastguard Worker /**< entry,exit: buffer size of out; actual size of JWT on exit */ 472*1c60b9acSAndroid Build Coastguard Worker char *temp; 473*1c60b9acSAndroid Build Coastguard Worker /**< exit undefined content, used by the function as a temporary scratchpad; MUST 474*1c60b9acSAndroid Build Coastguard Worker * be large enogh to store various intermediate representations */ 475*1c60b9acSAndroid Build Coastguard Worker int tl; 476*1c60b9acSAndroid Build Coastguard Worker /**< entry: size of temp buffer */ 477*1c60b9acSAndroid Build Coastguard Worker }; 478*1c60b9acSAndroid Build Coastguard Worker 479*1c60b9acSAndroid Build Coastguard Worker /** 480*1c60b9acSAndroid Build Coastguard Worker * lws_jwt_sign_compact() - generate a compact JWT using a key and JOSE header 481*1c60b9acSAndroid Build Coastguard Worker * 482*1c60b9acSAndroid Build Coastguard Worker * \param ctx: the lws_context 483*1c60b9acSAndroid Build Coastguard Worker * \param jwk: the signing key 484*1c60b9acSAndroid Build Coastguard Worker * \param info: info describing the JWT's content and output/temp buffers 485*1c60b9acSAndroid Build Coastguard Worker * \param format: a printf style format specification of the claims object 486*1c60b9acSAndroid Build Coastguard Worker * \param ...: zero or more args for the format specification 487*1c60b9acSAndroid Build Coastguard Worker * 488*1c60b9acSAndroid Build Coastguard Worker * Creates a JWT in a single step, from the format string and args through to 489*1c60b9acSAndroid Build Coastguard Worker * outputting a well-formed compact JWT representation in out. The provided 490*1c60b9acSAndroid Build Coastguard Worker * JOSE header's syntax is checked before it is added to the JWT. 491*1c60b9acSAndroid Build Coastguard Worker * 492*1c60b9acSAndroid Build Coastguard Worker * Returns 0 if all is well and *out_len is the amount of data in out, else 493*1c60b9acSAndroid Build Coastguard Worker * nonzero if failed. Temp must be large enough to hold various intermediate 494*1c60b9acSAndroid Build Coastguard Worker * representations. 495*1c60b9acSAndroid Build Coastguard Worker */ 496*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 497*1c60b9acSAndroid Build Coastguard Worker lws_jwt_sign_via_info(struct lws_context *ctx, struct lws_jwk *jwk, 498*1c60b9acSAndroid Build Coastguard Worker const struct lws_jwt_sign_info *info, const char *format, ...) LWS_FORMAT(4); 499*1c60b9acSAndroid Build Coastguard Worker 500*1c60b9acSAndroid Build Coastguard Worker /** 501*1c60b9acSAndroid Build Coastguard Worker * lws_jwt_token_sanity() - check a validated jwt payload for sanity 502*1c60b9acSAndroid Build Coastguard Worker * 503*1c60b9acSAndroid Build Coastguard Worker * \param in: the JWT payload 504*1c60b9acSAndroid Build Coastguard Worker * \param in_len: the length of the JWT payload 505*1c60b9acSAndroid Build Coastguard Worker * \param iss: the expected issuer of the token 506*1c60b9acSAndroid Build Coastguard Worker * \param aud: the expected audience of the token 507*1c60b9acSAndroid Build Coastguard Worker * \param csrf_in: NULL, or the csrf token that came in on a URL 508*1c60b9acSAndroid Build Coastguard Worker * \param sub: a buffer to hold the subject name in the JWT (eg, account name) 509*1c60b9acSAndroid Build Coastguard Worker * \param sub_len: the max length of the sub buffer 510*1c60b9acSAndroid Build Coastguard Worker * \param secs_left: set to the number of seconds of valid auth left if valid 511*1c60b9acSAndroid Build Coastguard Worker * 512*1c60b9acSAndroid Build Coastguard Worker * This performs some generic sanity tests on validated JWT payload... 513*1c60b9acSAndroid Build Coastguard Worker * 514*1c60b9acSAndroid Build Coastguard Worker * - the issuer is as expected 515*1c60b9acSAndroid Build Coastguard Worker * - the audience is us 516*1c60b9acSAndroid Build Coastguard Worker * - current time is OK for nbf ("not before") in the token 517*1c60b9acSAndroid Build Coastguard Worker * - current time is OK for exp ("expiry") in the token 518*1c60b9acSAndroid Build Coastguard Worker * - if csrf_in is not NULL, that the JWK has a csrf and it matches it 519*1c60b9acSAndroid Build Coastguard Worker * - if sub is not NULL, that the JWK provides a subject (and copies it to sub) 520*1c60b9acSAndroid Build Coastguard Worker * 521*1c60b9acSAndroid Build Coastguard Worker * If the tests pass, *secs_left is set to the number of remaining seconds the 522*1c60b9acSAndroid Build Coastguard Worker * auth is valid. 523*1c60b9acSAndroid Build Coastguard Worker * 524*1c60b9acSAndroid Build Coastguard Worker * Returns 0 if no inconsistency, else nonzero. 525*1c60b9acSAndroid Build Coastguard Worker */ 526*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 527*1c60b9acSAndroid Build Coastguard Worker lws_jwt_token_sanity(const char *in, size_t in_len, 528*1c60b9acSAndroid Build Coastguard Worker const char *iss, const char *aud, const char *csrf_in, 529*1c60b9acSAndroid Build Coastguard Worker char *sub, size_t sub_len, unsigned long *exp_unix_time); 530*1c60b9acSAndroid Build Coastguard Worker 531*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 532*1c60b9acSAndroid Build Coastguard Worker 533*1c60b9acSAndroid Build Coastguard Worker struct lws_jwt_sign_set_cookie { 534*1c60b9acSAndroid Build Coastguard Worker struct lws_jwk *jwk; 535*1c60b9acSAndroid Build Coastguard Worker /**< entry: required signing key */ 536*1c60b9acSAndroid Build Coastguard Worker const char *alg; 537*1c60b9acSAndroid Build Coastguard Worker /**< entry: required signing alg, eg, "ES512" */ 538*1c60b9acSAndroid Build Coastguard Worker const char *iss; 539*1c60b9acSAndroid Build Coastguard Worker /**< entry: issuer name to use */ 540*1c60b9acSAndroid Build Coastguard Worker const char *aud; 541*1c60b9acSAndroid Build Coastguard Worker /**< entry: audience */ 542*1c60b9acSAndroid Build Coastguard Worker const char *cookie_name; 543*1c60b9acSAndroid Build Coastguard Worker /**< entry: the name of the cookie */ 544*1c60b9acSAndroid Build Coastguard Worker char sub[33]; 545*1c60b9acSAndroid Build Coastguard Worker /**< sign-entry, validate-exit: subject */ 546*1c60b9acSAndroid Build Coastguard Worker const char *extra_json; 547*1c60b9acSAndroid Build Coastguard Worker /**< sign-entry, validate-exit: 548*1c60b9acSAndroid Build Coastguard Worker * optional "ext" JSON object contents for the JWT */ 549*1c60b9acSAndroid Build Coastguard Worker size_t extra_json_len; 550*1c60b9acSAndroid Build Coastguard Worker /**< validate-exit: 551*1c60b9acSAndroid Build Coastguard Worker * length of optional "ext" JSON object contents for the JWT */ 552*1c60b9acSAndroid Build Coastguard Worker const char *csrf_in; 553*1c60b9acSAndroid Build Coastguard Worker /**< validate-entry: 554*1c60b9acSAndroid Build Coastguard Worker * NULL, or an external CSRF token to check against what is in the JWT */ 555*1c60b9acSAndroid Build Coastguard Worker unsigned long expiry_unix_time; 556*1c60b9acSAndroid Build Coastguard Worker /**< sign-entry: seconds the JWT and cookie may live, 557*1c60b9acSAndroid Build Coastguard Worker * validate-exit: expiry unix time */ 558*1c60b9acSAndroid Build Coastguard Worker }; 559*1c60b9acSAndroid Build Coastguard Worker 560*1c60b9acSAndroid Build Coastguard Worker /** 561*1c60b9acSAndroid Build Coastguard Worker * lws_jwt_sign_token_set_http_cookie() - creates sets a JWT in a wsi cookie 562*1c60b9acSAndroid Build Coastguard Worker * 563*1c60b9acSAndroid Build Coastguard Worker * \param wsi: the wsi to create the cookie header on 564*1c60b9acSAndroid Build Coastguard Worker * \param i: structure describing what should be in the JWT 565*1c60b9acSAndroid Build Coastguard Worker * \param p: wsi headers area 566*1c60b9acSAndroid Build Coastguard Worker * \param end: end of wsi headers area 567*1c60b9acSAndroid Build Coastguard Worker * 568*1c60b9acSAndroid Build Coastguard Worker * Creates a JWT specified \p i, and attaches it to the outgoing headers on 569*1c60b9acSAndroid Build Coastguard Worker * wsi. Returns 0 if successful. 570*1c60b9acSAndroid Build Coastguard Worker * 571*1c60b9acSAndroid Build Coastguard Worker * Best-practice security restrictions are applied to the cookie set action, 572*1c60b9acSAndroid Build Coastguard Worker * including forcing httponly, and __Host- prefix. As required by __Host-, the 573*1c60b9acSAndroid Build Coastguard Worker * cookie Path is set to /. __Host- is applied by the function, the cookie_name 574*1c60b9acSAndroid Build Coastguard Worker * should just be "xyz" for "__Host-xyz". 575*1c60b9acSAndroid Build Coastguard Worker * 576*1c60b9acSAndroid Build Coastguard Worker * \p extra_json should just be the bare JSON, a { } is provided around it by 577*1c60b9acSAndroid Build Coastguard Worker * the function if it's non-NULL. For example, "\"authorization\": 1". 578*1c60b9acSAndroid Build Coastguard Worker * 579*1c60b9acSAndroid Build Coastguard Worker * It's recommended the secs parameter is kept as small as consistent with one 580*1c60b9acSAndroid Build Coastguard Worker * user session on the site if possible, eg, 10 minutes or 20 minutes. At the 581*1c60b9acSAndroid Build Coastguard Worker * server, it can determine how much time is left in the auth and inform the 582*1c60b9acSAndroid Build Coastguard Worker * client; if the JWT validity expires, the page should reload so the UI always 583*1c60b9acSAndroid Build Coastguard Worker * reflects what's possible to do with the authorization state correctly. If 584*1c60b9acSAndroid Build Coastguard Worker * the JWT expires, the user can log back in using credentials usually stored in 585*1c60b9acSAndroid Build Coastguard Worker * the browser and auto-filled-in, so this is not very inconvenient. 586*1c60b9acSAndroid Build Coastguard Worker * 587*1c60b9acSAndroid Build Coastguard Worker * This is a helper on top of the other JOSE and JWT apis that somewhat crosses 588*1c60b9acSAndroid Build Coastguard Worker * over between JWT and HTTP, since it knows about cookies. So it is only built 589*1c60b9acSAndroid Build Coastguard Worker * if both LWS_WITH_JOSE and one of the http-related roles enabled. 590*1c60b9acSAndroid Build Coastguard Worker */ 591*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 592*1c60b9acSAndroid Build Coastguard Worker lws_jwt_sign_token_set_http_cookie(struct lws *wsi, 593*1c60b9acSAndroid Build Coastguard Worker const struct lws_jwt_sign_set_cookie *i, 594*1c60b9acSAndroid Build Coastguard Worker uint8_t **p, uint8_t *end); 595*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int 596*1c60b9acSAndroid Build Coastguard Worker lws_jwt_get_http_cookie_validate_jwt(struct lws *wsi, 597*1c60b9acSAndroid Build Coastguard Worker struct lws_jwt_sign_set_cookie *i, 598*1c60b9acSAndroid Build Coastguard Worker char *out, size_t *out_len); 599*1c60b9acSAndroid Build Coastguard Worker #endif 600*1c60b9acSAndroid Build Coastguard Worker 601*1c60b9acSAndroid Build Coastguard Worker ///@} 602