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 enum lws_jws_jose_hdr_indexes { 26 LJJHI_ALG, /* REQUIRED */ 27 LJJHI_JKU, /* Optional: string */ 28 LJJHI_JWK, /* Optional: jwk JSON object: public key: */ 29 LJJHI_KID, /* Optional: string */ 30 LJJHI_X5U, /* Optional: string: url of public key cert / chain */ 31 LJJHI_X5C, /* Optional: base64 (NOT -url): actual cert */ 32 LJJHI_X5T, /* Optional: base64url: SHA-1 of actual cert */ 33 LJJHI_X5T_S256, /* Optional: base64url: SHA-256 of actual cert */ 34 LJJHI_TYP, /* Optional: string: media type */ 35 LJJHI_CTY, /* Optional: string: content media type */ 36 LJJHI_CRIT, /* Optional for send, REQUIRED: array of strings: 37 * mustn't contain standardized strings or null set */ 38 39 LJJHI_RECIPS_HDR, 40 LJJHI_RECIPS_HDR_ALG, 41 LJJHI_RECIPS_HDR_KID, 42 LJJHI_RECIPS_EKEY, 43 44 LJJHI_ENC, /* JWE only: Optional: string */ 45 LJJHI_ZIP, /* JWE only: Optional: string ("DEF" = deflate) */ 46 47 LJJHI_EPK, /* Additional arg for JWE ECDH: ephemeral public key */ 48 LJJHI_APU, /* Additional arg for JWE ECDH: base64url */ 49 LJJHI_APV, /* Additional arg for JWE ECDH: base64url */ 50 LJJHI_IV, /* Additional arg for JWE AES: base64url */ 51 LJJHI_TAG, /* Additional arg for JWE AES: base64url */ 52 LJJHI_P2S, /* Additional arg for JWE PBES2: base64url: salt */ 53 LJJHI_P2C, /* Additional arg for JWE PBES2: integer: count */ 54 55 LWS_COUNT_JOSE_HDR_ELEMENTS 56 }; 57 58 enum lws_jose_algtype { 59 LWS_JOSE_ENCTYPE_NONE, 60 61 LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5, 62 LWS_JOSE_ENCTYPE_RSASSA_PKCS1_OAEP, 63 LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS, 64 65 LWS_JOSE_ENCTYPE_ECDSA, 66 LWS_JOSE_ENCTYPE_ECDHES, 67 68 LWS_JOSE_ENCTYPE_AES_CBC, 69 LWS_JOSE_ENCTYPE_AES_CFB128, 70 LWS_JOSE_ENCTYPE_AES_CFB8, 71 LWS_JOSE_ENCTYPE_AES_CTR, 72 LWS_JOSE_ENCTYPE_AES_ECB, 73 LWS_JOSE_ENCTYPE_AES_OFB, 74 LWS_JOSE_ENCTYPE_AES_XTS, /* care: requires double-length key */ 75 LWS_JOSE_ENCTYPE_AES_GCM, 76 }; 77 78 /* there's a table of these defined in lws-gencrypto-common.c */ 79 80 struct lws_jose_jwe_alg { 81 enum lws_genhash_types hash_type; 82 enum lws_genhmac_types hmac_type; 83 enum lws_jose_algtype algtype_signing; /* the signing cipher */ 84 enum lws_jose_algtype algtype_crypto; /* the encryption cipher */ 85 const char *alg; /* the JWA enc alg name, eg "ES512" */ 86 const char *curve_name; /* NULL, or, eg, "P-256" */ 87 unsigned short keybits_min, keybits_fixed; 88 unsigned short ivbits; 89 }; 90 91 /* 92 * For JWS, "JOSE header" is defined to be the union of... 93 * 94 * o JWS Protected Header 95 * o JWS Unprotected Header 96 * 97 * For JWE, the "JOSE header" is the union of... 98 * 99 * o JWE Protected Header 100 * o JWE Shared Unprotected Header 101 * o JWE Per-Recipient Unprotected Header 102 */ 103 104 #define LWS_JWS_MAX_RECIPIENTS 3 105 106 struct lws_jws_recpient { 107 /* 108 * JOSE per-recipient unprotected header... for JWS this contains 109 * protected / header / signature 110 */ 111 struct lws_gencrypto_keyelem unprot[LWS_COUNT_JOSE_HDR_ELEMENTS]; 112 struct lws_jwk jwk_ephemeral; /* recipient ephemeral key if any */ 113 struct lws_jwk jwk; /* recipient "jwk" key if any */ 114 }; 115 116 struct lws_jose { 117 /* JOSE protected and unprotected header elements */ 118 struct lws_gencrypto_keyelem e[LWS_COUNT_JOSE_HDR_ELEMENTS]; 119 120 struct lws_jws_recpient recipient[LWS_JWS_MAX_RECIPIENTS]; 121 122 char typ[32]; 123 124 /* information from the protected header part */ 125 const struct lws_jose_jwe_alg *alg; 126 const struct lws_jose_jwe_alg *enc_alg; 127 128 int recipients; /* count of used recipient[] entries */ 129 }; 130 131 /** 132 * lws_jose_init() - prepare a struct lws_jose for use 133 * 134 * \param jose: the jose header struct to prepare 135 */ 136 LWS_VISIBLE LWS_EXTERN void 137 lws_jose_init(struct lws_jose *jose); 138 139 /** 140 * lws_jose_destroy() - retire a struct lws_jose from use 141 * 142 * \param jose: the jose header struct to destroy 143 */ 144 LWS_VISIBLE LWS_EXTERN void 145 lws_jose_destroy(struct lws_jose *jose); 146 147 /** 148 * lws_gencrypto_jws_alg_to_definition() - look up a jws alg name 149 * 150 * \param alg: the jws alg name 151 * \param jose: pointer to the pointer to the info struct to set on success 152 * 153 * Returns 0 if *jose set, else nonzero for failure 154 */ 155 LWS_VISIBLE LWS_EXTERN int 156 lws_gencrypto_jws_alg_to_definition(const char *alg, 157 const struct lws_jose_jwe_alg **jose); 158 159 /** 160 * lws_gencrypto_jwe_alg_to_definition() - look up a jwe alg name 161 * 162 * \param alg: the jwe alg name 163 * \param jose: pointer to the pointer to the info struct to set on success 164 * 165 * Returns 0 if *jose set, else nonzero for failure 166 */ 167 LWS_VISIBLE LWS_EXTERN int 168 lws_gencrypto_jwe_alg_to_definition(const char *alg, 169 const struct lws_jose_jwe_alg **jose); 170 171 /** 172 * lws_gencrypto_jwe_enc_to_definition() - look up a jwe enc name 173 * 174 * \param alg: the jwe enc name 175 * \param jose: pointer to the pointer to the info struct to set on success 176 * 177 * Returns 0 if *jose set, else nonzero for failure 178 */ 179 LWS_VISIBLE LWS_EXTERN int 180 lws_gencrypto_jwe_enc_to_definition(const char *enc, 181 const struct lws_jose_jwe_alg **jose); 182 183 /** 184 * lws_jws_parse_jose() - parse a JWS JOSE header 185 * 186 * \param jose: the jose struct to set to parsing results 187 * \param buf: the raw JOSE header 188 * \param len: the length of the raw JOSE header 189 * \param temp: parent-owned buffer to "allocate" elements into 190 * \param temp_len: amount of space available in temp 191 * 192 * returns the amount of temp used, or -1 for error 193 */ 194 LWS_VISIBLE LWS_EXTERN int 195 lws_jws_parse_jose(struct lws_jose *jose, 196 const char *buf, int len, char *temp, int *temp_len); 197 198 /** 199 * lws_jwe_parse_jose() - parse a JWE JOSE header 200 * 201 * \param jose: the jose struct to set to parsing results 202 * \param buf: the raw JOSE header 203 * \param len: the length of the raw JOSE header 204 * \param temp: parent-owned buffer to "allocate" elements into 205 * \param temp_len: amount of space available in temp 206 * 207 * returns the amount of temp used, or -1 for error 208 */ 209 LWS_VISIBLE LWS_EXTERN int 210 lws_jwe_parse_jose(struct lws_jose *jose, 211 const char *buf, int len, char *temp, int *temp_len); 212 213