1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 /*! \defgroup jwk JSON Web Keys 26 * ## JSON Web Keys API 27 * 28 * Lws provides an API to parse JSON Web Keys into a struct lws_gencrypto_keyelem. 29 * 30 * "oct" and "RSA" type keys are supported. For "oct" keys, they are held in 31 * the "e" member of the struct lws_gencrypto_keyelem. 32 * 33 * Keys elements are allocated on the heap. You must destroy the allocations 34 * in the struct lws_gencrypto_keyelem by calling 35 * lws_genrsa_destroy_elements() when you are finished with it. 36 */ 37 ///@{ 38 39 enum enum_jwk_meta_tok { 40 JWK_META_KTY, 41 JWK_META_KID, 42 JWK_META_USE, 43 JWK_META_KEY_OPS, 44 JWK_META_X5C, 45 JWK_META_ALG, 46 47 LWS_COUNT_JWK_ELEMENTS 48 }; 49 50 struct lws_jwk { 51 /* key data elements */ 52 struct lws_gencrypto_keyelem e[LWS_GENCRYPTO_MAX_KEYEL_COUNT]; 53 /* generic meta key elements, like KID */ 54 struct lws_gencrypto_keyelem meta[LWS_COUNT_JWK_ELEMENTS]; 55 int kty; /**< one of LWS_GENCRYPTO_KTY_ */ 56 char private_key; /* nonzero = has private key elements */ 57 }; 58 59 typedef int (*lws_jwk_key_import_callback)(struct lws_jwk *s, void *user); 60 61 struct lws_jwk_parse_state { 62 struct lws_jwk *jwk; 63 char b64[(((8192 / 8) * 4) / 3) + 1]; /* enough for 8Kb key */ 64 lws_jwk_key_import_callback per_key_cb; 65 void *user; 66 int pos; 67 int cose_state; 68 int seen; 69 unsigned short possible; 70 }; 71 72 /** lws_jwk_import() - Create a JSON Web key from the textual representation 73 * 74 * \param jwk: the JWK object to create 75 * \param cb: callback for each jwk-processed key, or NULL if importing a single 76 * key with no parent "keys" JSON 77 * \param user: pointer to be passed to the callback, otherwise ignored by lws. 78 * NULL if importing a single key with no parent "keys" JSON 79 * \param in: a single JWK JSON stanza in utf-8 80 * \param len: the length of the JWK JSON stanza in bytes 81 * 82 * Creates an lws_jwk struct filled with data from the JSON representation. 83 * 84 * There are two ways to use this... with some protocols a single jwk is 85 * delivered with no parent "keys": [] array. If you call this with cb and 86 * user as NULL, then the input will be interpreted like that and the results 87 * placed in s. 88 * 89 * The second case is that you are dealing with a "keys":[] array with one or 90 * more keys in it. In this case, the function iterates through the keys using 91 * s as a temporary jwk, and calls the user-provided callback for each key in 92 * turn while it return 0 (nonzero return from the callback terminates the 93 * iteration through any further keys). 94 */ 95 LWS_VISIBLE LWS_EXTERN int 96 lws_jwk_import(struct lws_jwk *jwk, lws_jwk_key_import_callback cb, void *user, 97 const char *in, size_t len); 98 99 /** lws_jwk_destroy() - Destroy a JSON Web key 100 * 101 * \param jwk: the JWK object to destroy 102 * 103 * All allocations in the lws_jwk are destroyed 104 */ 105 LWS_VISIBLE LWS_EXTERN void 106 lws_jwk_destroy(struct lws_jwk *jwk); 107 108 /** lws_jwk_dup_oct() - Set a jwk to a dup'd binary OCT key 109 * 110 * \param jwk: the JWK object to set 111 * \param key: the JWK object to destroy 112 * \param len: the JWK object to destroy 113 * 114 * Sets the kty to OCT, allocates len bytes for K and copies len bytes of key 115 * into the allocation. 116 */ 117 LWS_VISIBLE LWS_EXTERN int 118 lws_jwk_dup_oct(struct lws_jwk *jwk, const void *key, int len); 119 120 #define LWSJWKF_EXPORT_PRIVATE (1 << 0) 121 #define LWSJWKF_EXPORT_NOCRLF (1 << 1) 122 123 /** lws_jwk_export() - Export a JSON Web key to a textual representation 124 * 125 * \param jwk: the JWK object to export 126 * \param flags: control export options 127 * \param p: the buffer to write the exported JWK to 128 * \param len: the length of the buffer \p p in bytes... reduced by used amount 129 * 130 * Returns length of the used part of the buffer if OK, or -1 for error. 131 * 132 * \p flags can be OR-ed together 133 * 134 * LWSJWKF_EXPORT_PRIVATE: default is only public part, set this to also export 135 * the private part 136 * 137 * LWSJWKF_EXPORT_NOCRLF: normally adds a CRLF at the end of the export, if 138 * you need to suppress it, set this flag 139 * 140 * Serializes the content of the JWK into a char buffer. 141 */ 142 LWS_VISIBLE LWS_EXTERN int 143 lws_jwk_export(struct lws_jwk *jwk, int flags, char *p, int *len); 144 145 /** lws_jwk_load() - Import a JSON Web key from a file 146 * 147 * \param jwk: the JWK object to load into 148 * \param filename: filename to load from 149 * \param cb: optional callback for each key 150 * \param user: opaque user pointer passed to cb if given 151 * 152 * Returns 0 for OK or -1 for failure 153 * 154 * There are two ways to use this... with some protocols a single jwk is 155 * delivered with no parent "keys": [] array. If you call this with cb and 156 * user as NULL, then the input will be interpreted like that and the results 157 * placed in s. 158 * 159 * The second case is that you are dealing with a "keys":[] array with one or 160 * more keys in it. In this case, the function iterates through the keys using 161 * s as a temporary jwk, and calls the user-provided callback for each key in 162 * turn while it return 0 (nonzero return from the callback terminates the 163 * iteration through any further keys, leaving the last one in s). 164 */ 165 LWS_VISIBLE LWS_EXTERN int 166 lws_jwk_load(struct lws_jwk *jwk, const char *filename, 167 lws_jwk_key_import_callback cb, void *user); 168 169 /** lws_jwk_save() - Export a JSON Web key to a file 170 * 171 * \param jwk: the JWK object to save from 172 * \param filename: filename to save to 173 * 174 * Returns 0 for OK or -1 for failure 175 */ 176 LWS_VISIBLE LWS_EXTERN int 177 lws_jwk_save(struct lws_jwk *jwk, const char *filename); 178 179 /** lws_jwk_rfc7638_fingerprint() - jwk to RFC7638 compliant fingerprint 180 * 181 * \param jwk: the JWK object to fingerprint 182 * \param digest32: buffer to take 32-byte digest 183 * 184 * Returns 0 for OK or -1 for failure 185 */ 186 LWS_VISIBLE LWS_EXTERN int 187 lws_jwk_rfc7638_fingerprint(struct lws_jwk *jwk, char *digest32); 188 189 /** lws_jwk_strdup_meta() - allocate a duplicated string meta element 190 * 191 * \param jwk: the JWK object to fingerprint 192 * \param idx: JWK_META_ element index 193 * \param in: string to copy 194 * \param len: length of string to copy 195 * 196 * Returns 0 for OK or nonzero for failure 197 */ 198 LWS_VISIBLE LWS_EXTERN int 199 lws_jwk_strdup_meta(struct lws_jwk *jwk, enum enum_jwk_meta_tok idx, 200 const char *in, int len); 201 202 203 LWS_VISIBLE LWS_EXTERN int 204 lws_jwk_dump(struct lws_jwk *jwk); 205 206 /** lws_jwk_generate() - create a new key of given type and characteristics 207 * 208 * \param context: the struct lws_context used for RNG 209 * \param jwk: the JWK object to fingerprint 210 * \param kty: One of the LWS_GENCRYPTO_KTY_ key types 211 * \param bits: for OCT and RSA keys, the number of bits 212 * \param curve: for EC keys, the name of the curve 213 * 214 * Returns 0 for OK or nonzero for failure 215 */ 216 LWS_VISIBLE int 217 lws_jwk_generate(struct lws_context *context, struct lws_jwk *jwk, 218 enum lws_gencrypto_kty kty, int bits, const char *curve); 219 220 ///@} 221