Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1600810423, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"f5f5502f983cc6be2aaab8f3c1478c10", "oid":{ "oid": "9bff4d84eddb7f793c04947c259a948523641920", "alias": [ "refs/heads/master"]},"blobname": "include/libwebsockets/lws-jws.h", "blob": "/*\n * libwebsockets - small server side websockets and web server implementation\n *\n * Copyright (C) 2010 - 2019 Andy Green \u003candy@warmcat.com\u003e\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \u0022Software\u0022), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \u0022AS IS\u0022, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/*! \u005cdefgroup jws JSON Web Signature\n * ## JSON Web Signature API\n *\n * Lws provides an API to check and create RFC7515 JSON Web Signatures\n *\n * SHA256/384/512 HMAC, and RSA 256/384/512 are supported.\n *\n * The API uses your TLS library crypto, but works exactly the same no matter\n * what your TLS backend is.\n */\n///@{\n\n/*\n * The maps are built to work with both JWS (LJWS_) and JWE (LJWE_), and are\n * sized to the slightly larger JWE case.\n */\n\nenum enum_jws_sig_elements {\n\n\t/* JWS block namespace */\n\tLJWS_JOSE,\n\tLJWS_PYLD,\n\tLJWS_SIG,\n\tLJWS_UHDR,\n\n\t/* JWE block namespace */\n\tLJWE_JOSE \u003d 0,\n\tLJWE_EKEY,\n\tLJWE_IV,\n\tLJWE_CTXT,\n\tLJWE_ATAG,\n\tLJWE_AAD,\n\n\tLWS_JWS_MAX_COMPACT_BLOCKS\n};\n\nstruct lws_jws_map {\n\tconst char *buf[LWS_JWS_MAX_COMPACT_BLOCKS];\n\tuint32_t len[LWS_JWS_MAX_COMPACT_BLOCKS];\n};\n\n#define LWS_JWS_MAX_SIGS 3\n\nstruct lws_jws {\n\tstruct lws_jwk *jwk; /* the struct lws_jwk containing the signing key */\n\tstruct lws_context *context; /* the lws context (used to get random) */\n\tstruct lws_jws_map map, map_b64;\n};\n\n/* jws EC signatures do not have ASN.1 in them, meaning they're incompatible\n * with generic signatures.\n */\n\n/**\n * lws_jws_init() - initialize a jws for use\n *\n * \u005cparam jws: pointer to the jws to initialize\n * \u005cparam jwk: the jwk to use with this jws\n * \u005cparam context: the lws_context to use\n */\nLWS_VISIBLE LWS_EXTERN void\nlws_jws_init(struct lws_jws *jws, struct lws_jwk *jwk,\n\t struct lws_context *context);\n\n/**\n * lws_jws_destroy() - scrub a jws\n *\n * \u005cparam jws: pointer to the jws to destroy\n *\n * Call before the jws goes out of scope.\n *\n * Elements defined in the jws are zeroed.\n */\nLWS_VISIBLE LWS_EXTERN void\nlws_jws_destroy(struct lws_jws *jws);\n\n/**\n * lws_jws_sig_confirm_compact() - check signature\n *\n * \u005cparam map: pointers and lengths for each of the unencoded JWS elements\n * \u005cparam jwk: public key\n * \u005cparam context: lws_context\n * \u005cparam temp: scratchpad\n * \u005cparam temp_len: length of scratchpad\n *\n * Confirms the signature on a JWS. Use if you have non-b64 plain JWS elements\n * in a map... it'll make a temp b64 version needed for comparison. See below\n * for other variants.\n *\n * Returns 0 on match.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_sig_confirm_compact(struct lws_jws_map *map, struct lws_jwk *jwk,\n\t\t\t struct lws_context *context,\n\t\t\t char *temp, int *temp_len);\n\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_sig_confirm_compact_b64_map(struct lws_jws_map *map_b64,\n\t\t\t\t struct lws_jwk *jwk,\n\t\t\t struct lws_context *context,\n\t\t\t char *temp, int *temp_len);\n\n/**\n * lws_jws_sig_confirm_compact_b64() - check signature on b64 compact JWS\n *\n * \u005cparam in: pointer to b64 jose.payload[.hdr].sig\n * \u005cparam len: bytes available at \u005cp in\n * \u005cparam map: map to take decoded non-b64 content\n * \u005cparam jwk: public key\n * \u005cparam context: lws_context\n * \u005cparam temp: scratchpad\n * \u005cparam temp_len: size of scratchpad\n *\n * Confirms the signature on a JWS. Use if you have you have b64 compact layout\n * (jose.payload.hdr.sig) as an aggregated string... it'll make a temp plain\n * version needed for comparison.\n *\n * Returns 0 on match.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_sig_confirm_compact_b64(const char *in, size_t len,\n\t\t\t\tstruct lws_jws_map *map,\n\t\t\t\tstruct lws_jwk *jwk,\n\t\t\t\tstruct lws_context *context,\n\t\t\t\tchar *temp, int *temp_len);\n\n/**\n * lws_jws_sig_confirm() - check signature on plain + b64 JWS elements\n *\n * \u005cparam map_b64: pointers and lengths for each of the b64-encoded JWS elements\n * \u005cparam map: pointers and lengths for each of the unencoded JWS elements\n * \u005cparam jwk: public key\n * \u005cparam context: lws_context\n *\n * Confirms the signature on a JWS. Use if you have you already have both b64\n * compact layout (jose.payload.hdr.sig) and decoded JWS elements in maps.\n *\n * If you had the b64 string and called lws_jws_compact_decode() on it, you\n * will end up with both maps, and can use this api version, saving needlessly\n * regenerating any temp map.\n *\n * Returns 0 on match.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_sig_confirm(struct lws_jws_map *map_b64, /* b64-encoded */\n\t\t struct lws_jws_map *map,\t/* non-b64 */\n\t\t struct lws_jwk *jwk, struct lws_context *context);\n\n/**\n * lws_jws_sign_from_b64() - add b64 sig to b64 hdr + payload\n *\n * \u005cparam jose: jose header information\n * \u005cparam jws: information to include in the signature\n * \u005cparam b64_sig: output buffer for b64 signature\n * \u005cparam sig_len: size of \u005cp b64_sig output buffer\n *\n * This adds a b64-coded JWS signature of the b64-encoded protected header\n * and b64-encoded payload, at \u005cp b64_sig. The signature will be as large\n * as the N element of the RSA key when the RSA key is used, eg, 512 bytes for\n * a 4096-bit key, and then b64-encoding on top.\n *\n * In some special cases, there is only payload to sign and no header, in that\n * case \u005cp b64_hdr may be NULL, and only the payload will be hashed before\n * signing.\n *\n * Returns the length of the encoded signature written to \u005cp b64_sig, or -1.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_sign_from_b64(struct lws_jose *jose, struct lws_jws *jws, char *b64_sig,\n\t\t\tsize_t sig_len);\n\n/**\n * lws_jws_compact_decode() - converts and maps compact serialization b64 sections\n *\n * \u005cparam in: the incoming compact serialized b64\n * \u005cparam len: the length of the incoming compact serialized b64\n * \u005cparam map: pointer to the results structure\n * \u005cparam map_b64: NULL, or pointer to a second results structure taking block\n *\t\t information about the undecoded b64\n * \u005cparam out: buffer to hold decoded results\n * \u005cparam out_len: size of out in bytes\n *\n * Returns number of sections (2 if \u0022none\u0022, else 3), or -1 if illegal.\n *\n * map is set to point to the start and hold the length of each decoded block.\n * If map_b64 is non-NULL, then it's set with information about the input b64\n * blocks.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_compact_decode(const char *in, int len, struct lws_jws_map *map,\n\t\tstruct lws_jws_map *map_b64, char *out, int *out_len);\n\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_compact_encode(struct lws_jws_map *map_b64, /* b64-encoded */\n\t\t const struct lws_jws_map *map,\t/* non-b64 */\n\t\t char *buf, int *out_len);\n\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_sig_confirm_json(const char *in, size_t len,\n\t\t\t struct lws_jws *jws, struct lws_jwk *jwk,\n\t\t\t struct lws_context *context,\n\t\t\t char *temp, int *temp_len);\n\n/**\n * lws_jws_write_flattened_json() - create flattened JSON sig\n *\n * \u005cparam jws: information to include in the signature\n * \u005cparam flattened: output buffer for JSON\n * \u005cparam len: size of \u005cp flattened output buffer\n *\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_write_flattened_json(struct lws_jws *jws, char *flattened, size_t len);\n\n/**\n * lws_jws_write_compact() - create flattened JSON sig\n *\n * \u005cparam jws: information to include in the signature\n * \u005cparam compact: output buffer for compact format\n * \u005cparam len: size of \u005cp flattened output buffer\n *\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_write_compact(struct lws_jws *jws, char *compact, size_t len);\n\n\n\n/*\n * below apis are not normally needed if dealing with whole JWS... they're\n * useful for creating from scratch\n */\n\n\n/**\n * lws_jws_dup_element() - allocate space for an element and copy data into it\n *\n * \u005cparam map: map to create the element in\n * \u005cparam idx: index of element in the map to create\n * \u005cparam temp: space to allocate in\n * \u005cparam temp_len: available space at temp\n * \u005cparam in: data to duplicate into element\n * \u005cparam in_len: length of data to duplicate\n * \u005cparam actual_alloc: 0 for same as in_len, else actual allocation size\n *\n * Copies in_len from in to temp, if temp_len is sufficient.\n *\n * Returns 0 or -1 if not enough space in temp / temp_len.\n *\n * Over-allocation can be acheived by setting actual_alloc to the real\n * allocation desired... in_len will be copied into it.\n *\n * *temp_len is reduced by actual_alloc if successful.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_dup_element(struct lws_jws_map *map, int idx,\n\t\t char *temp, int *temp_len, const void *in, size_t in_len,\n\t\t size_t actual_alloc);\n\n/**\n * lws_jws_randomize_element() - create an element and fill with random\n *\n * \u005cparam context: lws_context used for random\n * \u005cparam map: map to create the element in\n * \u005cparam idx: index of element in the map to create\n * \u005cparam temp: space to allocate in\n * \u005cparam temp_len: available space at temp\n * \u005cparam random_len: length of data to fill with random\n * \u005cparam actual_alloc: 0 for same as random_len, else actual allocation size\n *\n * Randomize random_len bytes at temp, if temp_len is sufficient.\n *\n * Returns 0 or -1 if not enough space in temp / temp_len.\n *\n * Over-allocation can be acheived by setting actual_alloc to the real\n * allocation desired... the first random_len will be filled with random.\n *\n * *temp_len is reduced by actual_alloc if successful.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_randomize_element(struct lws_context *context,\n\t\t\t struct lws_jws_map *map,\n\t\t\t int idx, char *temp, int *temp_len, size_t random_len,\n\t\t\t size_t actual_alloc);\n\n/**\n * lws_jws_alloc_element() - create an element and reserve space for content\n *\n * \u005cparam map: map to create the element in\n * \u005cparam idx: index of element in the map to create\n * \u005cparam temp: space to allocate in\n * \u005cparam temp_len: available space at temp\n * \u005cparam len: logical length of element\n * \u005cparam actual_alloc: 0 for same as len, else actual allocation size\n *\n * Allocate len bytes at temp, if temp_len is sufficient.\n *\n * Returns 0 or -1 if not enough space in temp / temp_len.\n *\n * Over-allocation can be acheived by setting actual_alloc to the real\n * allocation desired... the element logical length will be set to len.\n *\n * *temp_len is reduced by actual_alloc if successful.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_alloc_element(struct lws_jws_map *map, int idx, char *temp,\n\t\t int *temp_len, size_t len, size_t actual_alloc);\n\n/**\n * lws_jws_encode_b64_element() - create an b64-encoded element\n *\n * \u005cparam map: map to create the element in\n * \u005cparam idx: index of element in the map to create\n * \u005cparam temp: space to allocate in\n * \u005cparam temp_len: available space at temp\n * \u005cparam in: pointer to unencoded input\n * \u005cparam in_len: length of unencoded input\n *\n * Allocate len bytes at temp, if temp_len is sufficient.\n *\n * Returns 0 or -1 if not enough space in temp / temp_len.\n *\n * Over-allocation can be acheived by setting actual_alloc to the real\n * allocation desired... the element logical length will be set to len.\n *\n * *temp_len is reduced by actual_alloc if successful.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_encode_b64_element(struct lws_jws_map *map, int idx,\n\t\t\t char *temp, int *temp_len, const void *in,\n\t\t\t size_t in_len);\n\n\n/**\n * lws_jws_b64_compact_map() - find block starts and lengths in compact b64\n *\n * \u005cparam in: pointer to b64 jose.payload[.hdr].sig\n * \u005cparam len: bytes available at \u005cp in\n * \u005cparam map: output struct with pointers and lengths for each JWS element\n *\n * Scans a jose.payload[.hdr].sig b64 string and notes where the blocks start\n * and their length into \u005cp map.\n *\n * Returns number of blocks if OK. May return \u003c0 if malformed.\n * May not fill all map entries.\n */\n\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_b64_compact_map(const char *in, int len, struct lws_jws_map *map);\n\n\n/**\n * lws_jws_base64_enc() - encode input data into b64url data\n *\n * \u005cparam in: the incoming plaintext\n * \u005cparam in_len: the length of the incoming plaintext in bytes\n * \u005cparam out: the buffer to store the b64url encoded data to\n * \u005cparam out_max: the length of \u005cp out in bytes\n *\n * Returns either -1 if problems, or the number of bytes written to \u005cp out.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);\n\n/**\n * lws_jws_encode_section() - encode input data into b64url data,\n *\t\t\t\tprepending . if not first\n *\n * \u005cparam in: the incoming plaintext\n * \u005cparam in_len: the length of the incoming plaintext in bytes\n * \u005cparam first: nonzero if the first section\n * \u005cparam p: the buffer to store the b64url encoded data to\n * \u005cparam end: just past the end of p\n *\n * Returns either -1 if problems, or the number of bytes written to \u005cp out.\n * If the section is not the first one, '.' is prepended.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jws_encode_section(const char *in, size_t in_len, int first, char **p,\n\t\t char *end);\n\n/**\n * lws_jwt_signed_validate() - check a compact JWT against a key and alg\n *\n * \u005cparam ctx: the lws_context\n * \u005cparam jwk: the key for checking the signature\n * \u005cparam alg_list: the expected alg name, like \u0022ES512\u0022\n * \u005cparam com: the compact JWT\n * \u005cparam len: the length of com\n * \u005cparam temp: a temp scratchpad\n * \u005cparam tl: available length of temp scratchpad\n * \u005cparam out: the output buffer to hold the validated plaintext\n * \u005cparam out_len: on entry, max length of out; on exit, used length of out\n *\n * Returns nonzero if the JWT cannot be validated or the plaintext can't fit the\n * provided output buffer, or 0 if it is validated as being signed by the\n * provided jwk.\n *\n * If validated, the plaintext in the JWT is copied into out and out_len set to\n * the used length.\n *\n * temp can be discarded or reused after the call returned, it's used to hold\n * transformations of the B64 JWS in the JWT.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jwt_signed_validate(struct lws_context *ctx, struct lws_jwk *jwk,\n\t\t\tconst char *alg_list, const char *com, size_t len,\n\t\t\tchar *temp, int tl, char *out, size_t *out_len);\n\n/**\n * lws_jwt_sign_compact() - generate a compact JWT using a key and alg\n *\n * \u005cparam ctx: the lws_context\n * \u005cparam jwk: the signing key\n * \u005cparam alg: the signing alg name, like \u0022ES512\u0022\n * \u005cparam out: the output buffer to hold the signed JWT in compact form\n * \u005cparam out_len: on entry, the length of out; on exit, the used amount of out\n * \u005cparam temp: a temp scratchpad\n * \u005cparam tl: available length of temp scratchpad\n * \u005cparam format: a printf style format specification\n * \u005cparam ...: zero or more args for the format specification\n *\n * Creates a JWT in a single step, from the format string and args through to\n * outputting a well-formed compact JWT representation in out.\n *\n * Returns 0 if all is well and *out_len is the amount of data in out, else\n * nonzero if failed. Temp must be large enough to hold various intermediate\n * representations.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jwt_sign_compact(struct lws_context *ctx, struct lws_jwk *jwk,\n\t\t const char *alg, char *out, size_t *out_len, char *temp,\n\t\t int tl, const char *format, ...) LWS_FORMAT(8);\n\n/**\n * lws_jwt_token_sanity() - check a validated jwt payload for sanity\n *\n * \u005cparam in: the JWT payload\n * \u005cparam in_len: the length of the JWT payload\n * \u005cparam iss: the expected issuer of the token\n * \u005cparam aud: the expected audience of the token\n * \u005cparam csrf_in: NULL, or the csrf token that came in on a URL\n * \u005cparam sub: a buffer to hold the subject name in the JWT (eg, account name)\n * \u005cparam sub_len: the max length of the sub buffer\n * \u005cparam secs_left: set to the number of seconds of valid auth left if valid\n *\n * This performs some generic sanity tests on validated JWT payload...\n *\n * - the issuer is as expected\n * - the audience is us\n * - current time is OK for nbf (\u0022not before\u0022) in the token\n * - current time is OK for exp (\u0022expiry\u0022) in the token\n * - if csrf_in is not NULL, that the JWK has a csrf and it matches it\n * - if sub is not NULL, that the JWK provides a subject (and copies it to sub)\n *\n * If the tests pass, *secs_left is set to the number of remaining seconds the\n * auth is valid.\n *\n * Returns 0 if no inconsistency, else nonzero.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jwt_token_sanity(const char *in, size_t in_len,\n\t\t const char *iss, const char *aud, const char *csrf_in,\n\t\t char *sub, size_t sub_len, unsigned long *exp_unix_time);\n\n#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n\nstruct lws_jwt_sign_set_cookie {\n\tstruct lws_jwk\t\t\t*jwk;\n\t/**\u003c entry: required signing key */\n\tconst char\t\t\t*alg;\n\t/**\u003c entry: required signing alg, eg, \u0022ES512\u0022 */\n\tconst char \t\t\t*iss;\n\t/**\u003c entry: issuer name to use */\n\tconst char\t\t\t*aud;\n\t/**\u003c entry: audience */\n\tconst char\t\t\t*cookie_name;\n\t/**\u003c entry: the name of the cookie */\n\tchar\t\t\t\tsub[33];\n\t/**\u003c sign-entry, validate-exit: subject */\n\tconst char\t\t\t*extra_json;\n\t/**\u003c sign-entry, validate-exit:\n\t * optional \u0022ext\u0022 JSON object contents for the JWT */\n\tsize_t\t\t\t\textra_json_len;\n\t/**\u003c validate-exit:\n\t * length of optional \u0022ext\u0022 JSON object contents for the JWT */\n\tconst char\t\t\t*csrf_in;\n\t/**\u003c validate-entry:\n\t * NULL, or an external CSRF token to check against what is in the JWT */\n\tunsigned long\t\t\texpiry_unix_time;\n\t/**\u003c sign-entry: seconds the JWT and cookie may live,\n\t * validate-exit: expiry unix time */\n};\n\n/**\n * lws_jwt_sign_token_set_cookie() - creates sets a JWT in a wsi cookie\n *\n * \u005cparam wsi: the wsi to create the cookie header on\n * \u005cparam i: structure describing what should be in the JWT\n * \u005cparam p: wsi headers area\n * \u005cparam end: end of wsi headers area\n *\n * Creates a JWT specified \u005cp i, and attaches it to the outgoing headers on\n * wsi. Returns 0 if successful.\n *\n * Best-practice security restrictions are applied to the cookie set action,\n * including forcing httponly, and __Host- prefix. As required by __Host-, the\n * cookie Path is set to /. __Host- is applied by the function, the cookie_name\n * should just be \u0022xyz\u0022 for \u0022__Host-xyz\u0022.\n *\n * \u005cp extra_json should just be the bare JSON, a { } is provided around it by\n * the function if it's non-NULL. For example, \u0022\u005c\u0022authorization\u005c\u0022: 1\u0022.\n *\n * It's recommended the secs parameter is kept as small as consistent with one\n * user session on the site if possible, eg, 10 minutes or 20 minutes. At the\n * server, it can determine how much time is left in the auth and inform the\n * client; if the JWT validity expires, the page should reload so the UI always\n * reflects what's possible to do with the authorization state correctly. If\n * the JWT expires, the user can log back in using credentials usually stored in\n * the browser and auto-filled-in, so this is not very inconvenient.\n *\n * This is a helper on top of the other JOSE and JWT apis that somewhat crosses\n * over between JWT and HTTP, since it knows about cookies. So it is only built\n * if both LWS_WITH_JOSE and one of the http-related roles enabled.\n */\nLWS_VISIBLE LWS_EXTERN int\nlws_jwt_sign_token_set_http_cookie(struct lws *wsi,\n\t\t\t\t const struct lws_jwt_sign_set_cookie *i,\n\t\t\t\t uint8_t **p, uint8_t *end);\nLWS_VISIBLE LWS_EXTERN int\nlws_jwt_get_http_cookie_validate_jwt(struct lws *wsi,\n\t\t\t\t struct lws_jwt_sign_set_cookie *i,\n\t\t\t\t char *out, size_t *out_len);\n#endif\n\n///@}\n","s":{"c":1600810423,"u": 747}} ],"g": 6305,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}