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_JWK_ */ 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 unsigned short possible; 68 }; 69 70 /** lws_jwk_import() - Create a JSON Web key from the textual representation 71 * 72 * \param jwk: the JWK object to create 73 * \param cb: callback for each jwk-processed key, or NULL if importing a single 74 * key with no parent "keys" JSON 75 * \param user: pointer to be passed to the callback, otherwise ignored by lws. 76 * NULL if importing a single key with no parent "keys" JSON 77 * \param in: a single JWK JSON stanza in utf-8 78 * \param len: the length of the JWK JSON stanza in bytes 79 * 80 * Creates an lws_jwk struct filled with data from the JSON representation. 81 * 82 * There are two ways to use this... with some protocols a single jwk is 83 * delivered with no parent "keys": [] array. If you call this with cb and 84 * user as NULL, then the input will be interpreted like that and the results 85 * placed in s. 86 * 87 * The second case is that you are dealing with a "keys":[] array with one or 88 * more keys in it. In this case, the function iterates through the keys using 89 * s as a temporary jwk, and calls the user-provided callback for each key in 90 * turn while it return 0 (nonzero return from the callback terminates the 91 * iteration through any further keys). 92 */ 93 LWS_VISIBLE LWS_EXTERN int 94 lws_jwk_import(struct lws_jwk *jwk, lws_jwk_key_import_callback cb, void *user, 95 const char *in, size_t len); 96 97 /** lws_jwk_destroy() - Destroy a JSON Web key 98 * 99 * \param jwk: the JWK object to destroy 100 * 101 * All allocations in the lws_jwk are destroyed 102 */ 103 LWS_VISIBLE LWS_EXTERN void 104 lws_jwk_destroy(struct lws_jwk *jwk); 105 106 /** lws_jwk_dup_oct() - Set a jwk to a dup'd binary OCT key 107 * 108 * \param jwk: the JWK object to set 109 * \param key: the JWK object to destroy 110 * \param len: the JWK object to destroy 111 * 112 * Sets the kty to OCT, allocates len bytes for K and copies len bytes of key 113 * into the allocation. 114 */ 115 LWS_VISIBLE LWS_EXTERN int 116 lws_jwk_dup_oct(struct lws_jwk *jwk, const void *key, int len); 117 118 #define LWSJWKF_EXPORT_PRIVATE (1 << 0) 119 #define LWSJWKF_EXPORT_NOCRLF (1 << 1) 120 121 /** lws_jwk_export() - Export a JSON Web key to a textual representation 122 * 123 * \param jwk: the JWK object to export 124 * \param flags: control export options 125 * \param p: the buffer to write the exported JWK to 126 * \param len: the length of the buffer \p p in bytes... reduced by used amount 127 * 128 * Returns length of the used part of the buffer if OK, or -1 for error. 129 * 130 * \p flags can be OR-ed together 131 * 132 * LWSJWKF_EXPORT_PRIVATE: default is only public part, set this to also export 133 * the private part 134 * 135 * LWSJWKF_EXPORT_NOCRLF: normally adds a CRLF at the end of the export, if 136 * you need to suppress it, set this flag 137 * 138 * Serializes the content of the JWK into a char buffer. 139 */ 140 LWS_VISIBLE LWS_EXTERN int 141 lws_jwk_export(struct lws_jwk *jwk, int flags, char *p, int *len); 142 143 /** lws_jwk_load() - Import a JSON Web key from a file 144 * 145 * \param jwk: the JWK object to load into 146 * \param filename: filename to load from 147 * \param cb: optional callback for each key 148 * \param user: opaque user pointer passed to cb if given 149 * 150 * Returns 0 for OK or -1 for failure 151 * 152 * There are two ways to use this... with some protocols a single jwk is 153 * delivered with no parent "keys": [] array. If you call this with cb and 154 * user as NULL, then the input will be interpreted like that and the results 155 * placed in s. 156 * 157 * The second case is that you are dealing with a "keys":[] array with one or 158 * more keys in it. In this case, the function iterates through the keys using 159 * s as a temporary jwk, and calls the user-provided callback for each key in 160 * turn while it return 0 (nonzero return from the callback terminates the 161 * iteration through any further keys, leaving the last one in s). 162 */ 163 LWS_VISIBLE LWS_EXTERN int 164 lws_jwk_load(struct lws_jwk *jwk, const char *filename, 165 lws_jwk_key_import_callback cb, void *user); 166 167 /** lws_jwk_save() - Export a JSON Web key to a file 168 * 169 * \param jwk: the JWK object to save from 170 * \param filename: filename to save to 171 * 172 * Returns 0 for OK or -1 for failure 173 */ 174 LWS_VISIBLE LWS_EXTERN int 175 lws_jwk_save(struct lws_jwk *jwk, const char *filename); 176 177 /** lws_jwk_rfc7638_fingerprint() - jwk to RFC7638 compliant fingerprint 178 * 179 * \param jwk: the JWK object to fingerprint 180 * \param digest32: buffer to take 32-byte digest 181 * 182 * Returns 0 for OK or -1 for failure 183 */ 184 LWS_VISIBLE LWS_EXTERN int 185 lws_jwk_rfc7638_fingerprint(struct lws_jwk *jwk, char *digest32); 186 187 /** lws_jwk_strdup_meta() - allocate a duplicated string meta element 188 * 189 * \param jwk: the JWK object to fingerprint 190 * \param idx: JWK_META_ element index 191 * \param in: string to copy 192 * \param len: length of string to copy 193 * 194 * Returns 0 for OK or -1 for failure 195 */ 196 LWS_VISIBLE LWS_EXTERN int 197 lws_jwk_strdup_meta(struct lws_jwk *jwk, enum enum_jwk_meta_tok idx, 198 const char *in, int len); 199 200 201 LWS_VISIBLE LWS_EXTERN int 202 lws_jwk_dump(struct lws_jwk *jwk); 203 204 /** lws_jwk_generate() - create a new key of given type and characteristics 205 * 206 * \param context: the struct lws_context used for RNG 207 * \param jwk: the JWK object to fingerprint 208 * \param kty: One of the LWS_GENCRYPTO_KTY_ key types 209 * \param bits: for OCT and RSA keys, the number of bits 210 * \param curve: for EC keys, the name of the curve 211 * 212 * Returns 0 for OK or -1 for failure 213 */ 214 LWS_VISIBLE int 215 lws_jwk_generate(struct lws_context *context, struct lws_jwk *jwk, 216 enum lws_gencrypto_kty kty, int bits, const char *curve); 217 218 ///@} 219