jwk.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  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. #include "private-lib-core.h"
  25. #include "private-lib-jose.h"
  26. #if !defined(LWS_PLAT_OPTEE) && !defined(OPTEE_DEV_KIT)
  27. #include <fcntl.h>
  28. #endif
  29. static const char * const kty_names[] = {
  30. "unknown", /* LWS_GENCRYPTO_KTY_UNKNOWN */
  31. "oct", /* LWS_GENCRYPTO_KTY_OCT */
  32. "RSA", /* LWS_GENCRYPTO_KTY_RSA */
  33. "EC" /* LWS_GENCRYPTO_KTY_EC */
  34. };
  35. /*
  36. * These are the entire legal token set for names in jwk.
  37. *
  38. * The first version is used to parse a detached single jwk that don't have any
  39. * parent JSON context. The second version is used to parse full jwk objects
  40. * that has a "keys": [ ] array containing the keys.
  41. */
  42. static const char * const jwk_tok[] = {
  43. "keys[]", /* dummy */
  44. "e", "n", "d", "p", "q", "dp", "dq", "qi", /* RSA */
  45. "kty", /* generic */
  46. "k", /* symmetric key data */
  47. "crv", "x", "y", /* EC (also "D") */
  48. "kid", /* generic */
  49. "use" /* mutually exclusive with "key_ops" */,
  50. "key_ops" /* mutually exclusive with "use" */,
  51. "x5c", /* generic */
  52. "alg" /* generic */
  53. }, * const jwk_outer_tok[] = {
  54. "keys[]",
  55. "keys[].e", "keys[].n", "keys[].d", "keys[].p", "keys[].q", "keys[].dp",
  56. "keys[].dq", "keys[].qi",
  57. "keys[].kty", "keys[].k", /* generic */
  58. "keys[].crv", "keys[].x", "keys[].y", /* EC (also "D") */
  59. "keys[].kid", "keys[].use" /* mutually exclusive with "key_ops" */,
  60. "keys[].key_ops", /* mutually exclusive with "use" */
  61. "keys[].x5c", "keys[].alg"
  62. };
  63. /* information about each token declared above */
  64. #define F_M (1 << 9) /* Mandatory for key type */
  65. #define F_B64 (1 << 10) /* Base64 coded octets */
  66. #define F_B64U (1 << 11) /* Base64 Url coded octets */
  67. #define F_META (1 << 12) /* JWK key metainformation */
  68. #define F_RSA (1 << 13) /* RSA key */
  69. #define F_EC (1 << 14) /* Elliptic curve key */
  70. #define F_OCT (1 << 15) /* octet key */
  71. static unsigned short tok_map[] = {
  72. F_RSA | F_EC | F_OCT | F_META | 0xff,
  73. F_RSA | F_B64U | F_M | LWS_GENCRYPTO_RSA_KEYEL_E,
  74. F_RSA | F_B64U | F_M | LWS_GENCRYPTO_RSA_KEYEL_N,
  75. F_RSA | F_EC | F_B64U | LWS_GENCRYPTO_RSA_KEYEL_D,
  76. F_RSA | F_B64U | LWS_GENCRYPTO_RSA_KEYEL_P,
  77. F_RSA | F_B64U | LWS_GENCRYPTO_RSA_KEYEL_Q,
  78. F_RSA | F_B64U | LWS_GENCRYPTO_RSA_KEYEL_DP,
  79. F_RSA | F_B64U | LWS_GENCRYPTO_RSA_KEYEL_DQ,
  80. F_RSA | F_B64U | LWS_GENCRYPTO_RSA_KEYEL_QI,
  81. F_RSA | F_EC | F_OCT | F_META | F_M | JWK_META_KTY,
  82. F_OCT | F_B64U | F_M | LWS_GENCRYPTO_OCT_KEYEL_K,
  83. F_EC | F_M | LWS_GENCRYPTO_EC_KEYEL_CRV,
  84. F_EC | F_B64U | F_M | LWS_GENCRYPTO_EC_KEYEL_X,
  85. F_EC | F_B64U | F_M | LWS_GENCRYPTO_EC_KEYEL_Y,
  86. F_RSA | F_EC | F_OCT | F_META | JWK_META_KID,
  87. F_RSA | F_EC | F_OCT | F_META | JWK_META_USE,
  88. F_RSA | F_EC | F_OCT | F_META | JWK_META_KEY_OPS,
  89. F_RSA | F_EC | F_OCT | F_META | F_B64 | JWK_META_X5C,
  90. F_RSA | F_EC | F_OCT | F_META | JWK_META_ALG,
  91. };
  92. static const char *meta_names[] = {
  93. "kty", "kid", "use", "key_ops", "x5c", "alg"
  94. };
  95. struct lexico {
  96. const char *name;
  97. int idx;
  98. char meta;
  99. } lexico_ec[] = {
  100. { "alg", JWK_META_ALG, 1 },
  101. { "crv", LWS_GENCRYPTO_EC_KEYEL_CRV, 0 },
  102. { "d", LWS_GENCRYPTO_EC_KEYEL_D, 2 | 0 },
  103. { "key_ops", JWK_META_KEY_OPS, 1 },
  104. { "kid", JWK_META_KID, 1 },
  105. { "kty", JWK_META_KTY, 1 },
  106. { "use", JWK_META_USE, 1 },
  107. { "x", LWS_GENCRYPTO_EC_KEYEL_X, 0 },
  108. { "x5c", JWK_META_X5C, 1 },
  109. { "y", LWS_GENCRYPTO_EC_KEYEL_Y, 0 }
  110. }, lexico_oct[] = {
  111. { "alg", JWK_META_ALG, 1 },
  112. { "k", LWS_GENCRYPTO_OCT_KEYEL_K, 0 },
  113. { "key_ops", JWK_META_KEY_OPS, 1 },
  114. { "kid", JWK_META_KID, 1 },
  115. { "kty", JWK_META_KTY, 1 },
  116. { "use", JWK_META_USE, 1 },
  117. { "x5c", JWK_META_X5C, 1 }
  118. }, lexico_rsa[] = {
  119. { "alg", JWK_META_ALG, 1 },
  120. { "d", LWS_GENCRYPTO_RSA_KEYEL_D, 2 | 0 },
  121. { "dp", LWS_GENCRYPTO_RSA_KEYEL_DP, 2 | 0 },
  122. { "dq", LWS_GENCRYPTO_RSA_KEYEL_DQ, 2 | 0 },
  123. { "e", LWS_GENCRYPTO_RSA_KEYEL_E, 0 },
  124. { "key_ops", JWK_META_KEY_OPS, 1 },
  125. { "kid", JWK_META_KID, 1 },
  126. { "kty", JWK_META_KTY, 1 },
  127. { "n", LWS_GENCRYPTO_RSA_KEYEL_N, 0 },
  128. { "p", LWS_GENCRYPTO_RSA_KEYEL_P, 2 | 0 },
  129. { "q", LWS_GENCRYPTO_RSA_KEYEL_Q, 2 | 0 },
  130. { "qi", LWS_GENCRYPTO_RSA_KEYEL_QI, 2 | 0 },
  131. { "use", JWK_META_USE, 1 },
  132. { "x5c", JWK_META_X5C, 1 }
  133. };
  134. static const char meta_b64[] = { 0, 0, 0, 0, 1, 0 };
  135. static const char *oct_names[] = {
  136. "k"
  137. };
  138. static const char oct_b64[] = { 1 };
  139. static const char *rsa_names[] = {
  140. "e", "n", "d", "p", "q", "dp", "dq", "qi"
  141. };
  142. static const char rsa_b64[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
  143. static const char *ec_names[] = {
  144. "crv", "x", "d", "y",
  145. };
  146. static const char ec_b64[] = { 0, 1, 1, 1 };
  147. int
  148. lws_jwk_dump(struct lws_jwk *jwk)
  149. {
  150. const char **enames, *b64;
  151. int elems;
  152. int n;
  153. (void)enames;
  154. (void)meta_names;
  155. switch (jwk->kty) {
  156. default:
  157. case LWS_GENCRYPTO_KTY_UNKNOWN:
  158. lwsl_err("%s: jwk %p: unknown type\n", __func__, jwk);
  159. return 1;
  160. case LWS_GENCRYPTO_KTY_OCT:
  161. elems = LWS_GENCRYPTO_OCT_KEYEL_COUNT;
  162. enames = oct_names;
  163. b64 = oct_b64;
  164. break;
  165. case LWS_GENCRYPTO_KTY_RSA:
  166. elems = LWS_GENCRYPTO_RSA_KEYEL_COUNT;
  167. enames = rsa_names;
  168. b64 = rsa_b64;
  169. break;
  170. case LWS_GENCRYPTO_KTY_EC:
  171. elems = LWS_GENCRYPTO_EC_KEYEL_COUNT;
  172. enames = ec_names;
  173. b64 = ec_b64;
  174. break;
  175. }
  176. lwsl_info("%s: jwk %p\n", __func__, jwk);
  177. for (n = 0; n < LWS_COUNT_JWK_ELEMENTS; n++) {
  178. if (jwk->meta[n].buf && meta_b64[n]) {
  179. lwsl_info(" meta: %s\n", meta_names[n]);
  180. lwsl_hexdump_info(jwk->meta[n].buf, jwk->meta[n].len);
  181. }
  182. if (jwk->meta[n].buf && !meta_b64[n])
  183. lwsl_info(" meta: %s: '%s'\n", meta_names[n],
  184. jwk->meta[n].buf);
  185. }
  186. for (n = 0; n < elems; n++) {
  187. if (jwk->e[n].buf && b64[n]) {
  188. lwsl_info(" e: %s\n", enames[n]);
  189. lwsl_hexdump_info(jwk->e[n].buf, jwk->e[n].len);
  190. }
  191. if (jwk->e[n].buf && !b64[n])
  192. lwsl_info(" e: %s: '%s'\n", enames[n], jwk->e[n].buf);
  193. }
  194. return 0;
  195. }
  196. static int
  197. _lws_jwk_set_el_jwk(struct lws_gencrypto_keyelem *e, char *in, int len)
  198. {
  199. e->buf = lws_malloc(len + 1, "jwk");
  200. if (!e->buf)
  201. return -1;
  202. memcpy(e->buf, in, len);
  203. e->buf[len] = '\0';
  204. e->len = len;
  205. return 0;
  206. }
  207. static int
  208. _lws_jwk_set_el_jwk_b64(struct lws_gencrypto_keyelem *e, char *in, int len)
  209. {
  210. int dec_size = lws_base64_size(len), n;
  211. e->buf = lws_malloc(dec_size, "jwk");
  212. if (!e->buf)
  213. return -1;
  214. /* same decoder accepts both url or original styles */
  215. n = lws_b64_decode_string_len(in, len, (char *)e->buf, dec_size - 1);
  216. if (n < 0)
  217. return -1;
  218. e->len = n;
  219. return 0;
  220. }
  221. static int
  222. _lws_jwk_set_el_jwk_b64u(struct lws_gencrypto_keyelem *e, char *in, int len)
  223. {
  224. int dec_size = lws_base64_size(len), n;
  225. e->buf = lws_malloc(dec_size, "jwk");
  226. if (!e->buf)
  227. return -1;
  228. /* same decoder accepts both url or original styles */
  229. n = lws_b64_decode_string_len(in, len, (char *)e->buf, dec_size - 1);
  230. if (n < 0)
  231. return -1;
  232. e->len = n;
  233. return 0;
  234. }
  235. void
  236. lws_jwk_destroy_elements(struct lws_gencrypto_keyelem *el, int m)
  237. {
  238. int n;
  239. for (n = 0; n < m; n++)
  240. if (el[n].buf) {
  241. /* wipe all key material when it goes out of scope */
  242. lws_explicit_bzero(el[n].buf, el[n].len);
  243. lws_free_set_NULL(el[n].buf);
  244. el[n].len = 0;
  245. }
  246. }
  247. void
  248. lws_jwk_destroy(struct lws_jwk *jwk)
  249. {
  250. lws_jwk_destroy_elements(jwk->e, LWS_ARRAY_SIZE(jwk->e));
  251. lws_jwk_destroy_elements(jwk->meta, LWS_ARRAY_SIZE(jwk->meta));
  252. }
  253. static signed char
  254. cb_jwk(struct lejp_ctx *ctx, char reason)
  255. {
  256. struct lws_jwk_parse_state *jps = (struct lws_jwk_parse_state *)ctx->user;
  257. struct lws_jwk *jwk = jps->jwk;
  258. unsigned int idx, poss, n;
  259. char dotstar[64];
  260. if (reason == LEJPCB_VAL_STR_START)
  261. jps->pos = 0;
  262. if (reason == LEJPCB_OBJECT_START && ctx->path_match == 0 + 1)
  263. /*
  264. * new keys[] member is starting
  265. *
  266. * Until we see some JSON names, it could be anything...
  267. * there is no requirement for kty to be given first and eg,
  268. * ACME specifies the keys must be ordered in lexographic
  269. * order - where kty is not first.
  270. */
  271. jps->possible = F_RSA | F_EC | F_OCT;
  272. if (reason == LEJPCB_OBJECT_END && ctx->path_match == 0 + 1) {
  273. /* we completed parsing a key */
  274. if (jps->per_key_cb && jps->possible) {
  275. if (jps->per_key_cb(jps->jwk, jps->user)) {
  276. lwsl_notice("%s: user cb halts import\n",
  277. __func__);
  278. return -2;
  279. }
  280. /* clear it down */
  281. lws_jwk_destroy(jps->jwk);
  282. jps->possible = 0;
  283. }
  284. }
  285. if (reason == LEJPCB_COMPLETE) {
  286. /*
  287. * Now we saw the whole jwk and know the key type, let'jwk insist
  288. * that as a whole, it must be consistent and complete.
  289. *
  290. * The tracking of ->possible bits from even before we know the
  291. * kty already makes certain we cannot have key element members
  292. * defined that are inconsistent with the key type.
  293. */
  294. for (n = 0; n < LWS_ARRAY_SIZE(tok_map); n++)
  295. /*
  296. * All mandataory elements for the key type
  297. * must be present
  298. */
  299. if ((tok_map[n] & jps->possible) && (
  300. ((tok_map[n] & (F_M | F_META)) == (F_M | F_META) &&
  301. !jwk->meta[tok_map[n] & 0xff].buf) ||
  302. ((tok_map[n] & (F_M | F_META)) == F_M &&
  303. !jwk->e[tok_map[n] & 0xff].buf))) {
  304. lwsl_notice("%s: missing %s\n", __func__,
  305. jwk_tok[n]);
  306. return -3;
  307. }
  308. /*
  309. * When the key may be public or public + private, ensure the
  310. * intra-key members related to that are consistent.
  311. *
  312. * Only RSA keys need extra care, since EC keys are already
  313. * confirmed by making CRV, X and Y mandatory and only D
  314. * (the singular private part) optional. For RSA, N and E are
  315. * also already known to be present using mandatory checking.
  316. */
  317. /*
  318. * If a private key, it must have all D, P and Q. Public key
  319. * must have none of them.
  320. */
  321. if (jwk->kty == LWS_GENCRYPTO_KTY_RSA &&
  322. !(((!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf) &&
  323. (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf) &&
  324. (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf)) ||
  325. (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf &&
  326. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf &&
  327. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf))
  328. ) {
  329. lwsl_notice("%s: RSA requires D, P and Q for private\n",
  330. __func__);
  331. return -3;
  332. }
  333. /*
  334. * If the precomputed private key terms appear, they must all
  335. * appear together.
  336. */
  337. if (jwk->kty == LWS_GENCRYPTO_KTY_RSA &&
  338. !(((!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_DP].buf) &&
  339. (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_DQ].buf) &&
  340. (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_QI].buf)) ||
  341. (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_DP].buf &&
  342. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_DQ].buf &&
  343. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_QI].buf))
  344. ) {
  345. lwsl_notice("%s: RSA DP, DQ, QI must all appear "
  346. "or none\n", __func__);
  347. return -3;
  348. }
  349. /*
  350. * The precomputed private key terms must not appear without
  351. * the private key itself also appearing.
  352. */
  353. if (jwk->kty == LWS_GENCRYPTO_KTY_RSA &&
  354. !jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf &&
  355. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_DQ].buf) {
  356. lwsl_notice("%s: RSA DP, DQ, QI can appear only with "
  357. "private key\n", __func__);
  358. return -3;
  359. }
  360. if ((jwk->kty == LWS_GENCRYPTO_KTY_RSA ||
  361. jwk->kty == LWS_GENCRYPTO_KTY_EC) &&
  362. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf)
  363. jwk->private_key = 1;
  364. }
  365. if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
  366. return 0;
  367. if (ctx->path_match == 0 + 1)
  368. return 0;
  369. idx = tok_map[ctx->path_match - 1];
  370. if ((idx & 0xff) == 0xff)
  371. return 0;
  372. switch (idx) {
  373. /* note: kty is not necessarily first... we have to keep track of
  374. * what could match given which element names have already been
  375. * seen. Once kty comes, we confirm it'jwk still possible (ie, it'jwk
  376. * not trying to tell us that it'jwk RSA now when we saw a "crv"
  377. * earlier) and then reduce the possibilities to just the one that
  378. * kty told. */
  379. case F_RSA | F_EC | F_OCT | F_META | F_M | JWK_META_KTY:
  380. if (ctx->npos == 3 && !strncmp(ctx->buf, "oct", 3)) {
  381. if (!(jps->possible & F_OCT))
  382. goto elements_mismatch;
  383. jwk->kty = LWS_GENCRYPTO_KTY_OCT;
  384. jps->possible = F_OCT;
  385. goto cont;
  386. }
  387. if (ctx->npos == 3 && !strncmp(ctx->buf, "RSA", 3)) {
  388. if (!(jps->possible & F_RSA))
  389. goto elements_mismatch;
  390. jwk->kty = LWS_GENCRYPTO_KTY_RSA;
  391. jps->possible = F_RSA;
  392. goto cont;
  393. }
  394. if (ctx->npos == 2 && !strncmp(ctx->buf, "EC", 2)) {
  395. if (!(jps->possible & F_EC))
  396. goto elements_mismatch;
  397. jwk->kty = LWS_GENCRYPTO_KTY_EC;
  398. jps->possible = F_EC;
  399. goto cont;
  400. }
  401. lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
  402. lwsl_err("%s: Unknown KTY '%s'\n", __func__, dotstar);
  403. return -1;
  404. default:
  405. cont:
  406. if (jps->pos + ctx->npos >= (int)sizeof(jps->b64))
  407. goto bail;
  408. memcpy(jps->b64 + jps->pos, ctx->buf, ctx->npos);
  409. jps->pos += ctx->npos;
  410. if (reason == LEJPCB_VAL_STR_CHUNK)
  411. return 0;
  412. /* chunking has been collated */
  413. poss = idx & (F_RSA | F_EC | F_OCT);
  414. jps->possible &= poss;
  415. if (!jps->possible)
  416. goto elements_mismatch;
  417. if (idx & F_META) {
  418. if (_lws_jwk_set_el_jwk(&jwk->meta[idx & 0x7f],
  419. jps->b64, jps->pos) < 0)
  420. goto bail;
  421. break;
  422. }
  423. if (idx & F_B64U) {
  424. /* key data... do the base64 decode as needed */
  425. if (_lws_jwk_set_el_jwk_b64u(&jwk->e[idx & 0x7f],
  426. jps->b64, jps->pos) < 0)
  427. goto bail;
  428. if (jwk->e[idx & 0x7f].len >
  429. LWS_JWE_LIMIT_KEY_ELEMENT_BYTES) {
  430. lwsl_notice("%s: oversize keydata\n", __func__);
  431. goto bail;
  432. }
  433. return 0;
  434. }
  435. if (idx & F_B64) {
  436. /* cert data... do non-urlcoded base64 decode */
  437. if (_lws_jwk_set_el_jwk_b64(&jwk->e[idx & 0x7f],
  438. jps->b64, jps->pos) < 0)
  439. goto bail;
  440. return 0;
  441. }
  442. if (_lws_jwk_set_el_jwk(&jwk->e[idx & 0x7f],
  443. jps->b64, jps->pos) < 0)
  444. goto bail;
  445. break;
  446. }
  447. return 0;
  448. elements_mismatch:
  449. lwsl_err("%s: jwk elements mismatch\n", __func__);
  450. bail:
  451. lwsl_err("%s: element failed\n", __func__);
  452. return -1;
  453. }
  454. void
  455. lws_jwk_init_jps(struct lejp_ctx *jctx, struct lws_jwk_parse_state *jps,
  456. struct lws_jwk *jwk, lws_jwk_key_import_callback cb,
  457. void *user)
  458. {
  459. if (jwk)
  460. memset(jwk, 0, sizeof(*jwk));
  461. jps->jwk = jwk;
  462. jps->possible = F_RSA | F_EC | F_OCT;
  463. jps->per_key_cb = cb;
  464. jps->user = user;
  465. jps->pos = 0;
  466. lejp_construct(jctx, cb_jwk, jps, cb ? jwk_outer_tok: jwk_tok,
  467. LWS_ARRAY_SIZE(jwk_tok));
  468. }
  469. int
  470. lws_jwk_dup_oct(struct lws_jwk *jwk, const void *key, int len)
  471. {
  472. jwk->e[LWS_GENCRYPTO_KTY_OCT].buf = lws_malloc(len, __func__);
  473. if (!jwk->e[LWS_GENCRYPTO_KTY_OCT].buf)
  474. return -1;
  475. jwk->kty = LWS_GENCRYPTO_KTY_OCT;
  476. jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].len = len;
  477. memcpy(jwk->e[LWS_GENCRYPTO_KTY_OCT].buf, key, len);
  478. return 0;
  479. }
  480. int
  481. lws_jwk_generate(struct lws_context *context, struct lws_jwk *jwk,
  482. enum lws_gencrypto_kty kty, int bits, const char *curve)
  483. {
  484. size_t sn;
  485. int n;
  486. memset(jwk, 0, sizeof(*jwk));
  487. jwk->kty = kty;
  488. jwk->private_key = 1;
  489. switch (kty) {
  490. case LWS_GENCRYPTO_KTY_RSA:
  491. {
  492. struct lws_genrsa_ctx ctx;
  493. lwsl_notice("%s: generating %d bit RSA key\n", __func__, bits);
  494. n = lws_genrsa_new_keypair(context, &ctx, LGRSAM_PKCS1_1_5,
  495. jwk->e, bits);
  496. lws_genrsa_destroy(&ctx);
  497. if (n) {
  498. lwsl_err("%s: problem generating RSA key\n", __func__);
  499. return 1;
  500. }
  501. }
  502. break;
  503. case LWS_GENCRYPTO_KTY_OCT:
  504. sn = lws_gencrypto_bits_to_bytes(bits);
  505. jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].buf = lws_malloc(sn, "oct");
  506. jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].len = (uint32_t)sn;
  507. if (lws_get_random(context,
  508. jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].buf, sn) != sn) {
  509. lwsl_err("%s: problem getting random\n", __func__);
  510. return 1;
  511. }
  512. break;
  513. case LWS_GENCRYPTO_KTY_EC:
  514. {
  515. struct lws_genec_ctx ctx;
  516. if (!curve) {
  517. lwsl_err("%s: must have a named curve\n", __func__);
  518. return 1;
  519. }
  520. if (lws_genecdsa_create(&ctx, context, NULL))
  521. return 1;
  522. lwsl_notice("%s: generating ECDSA key on curve %s\n", __func__,
  523. curve);
  524. n = lws_genecdsa_new_keypair(&ctx, curve, jwk->e);
  525. lws_genec_destroy(&ctx);
  526. if (n) {
  527. lwsl_err("%s: problem generating ECDSA key\n", __func__);
  528. return 1;
  529. }
  530. }
  531. break;
  532. case LWS_GENCRYPTO_KTY_UNKNOWN:
  533. default:
  534. lwsl_err("%s: unknown kty\n", __func__);
  535. return 1;
  536. }
  537. return 0;
  538. }
  539. int
  540. lws_jwk_import(struct lws_jwk *jwk, lws_jwk_key_import_callback cb, void *user,
  541. const char *in, size_t len)
  542. {
  543. struct lejp_ctx jctx;
  544. struct lws_jwk_parse_state jps;
  545. int m;
  546. lws_jwk_init_jps(&jctx, &jps, jwk, cb, user);
  547. m = lejp_parse(&jctx, (uint8_t *)in, (int)len);
  548. lejp_destruct(&jctx);
  549. if (m < 0) {
  550. lwsl_notice("%s: parse got %d\n", __func__, m);
  551. lws_jwk_destroy(jwk);
  552. return -1;
  553. }
  554. switch (jwk->kty) {
  555. case LWS_GENCRYPTO_KTY_UNKNOWN:
  556. lwsl_notice("%s: missing or unknown kyt\n", __func__);
  557. lws_jwk_destroy(jwk);
  558. return -1;
  559. default:
  560. break;
  561. }
  562. return 0;
  563. }
  564. int
  565. lws_jwk_export(struct lws_jwk *jwk, int flags, char *p, int *len)
  566. {
  567. char *start = p, *end = &p[*len - 1];
  568. int n, m, limit, first = 1, asym = 0;
  569. struct lexico *l;
  570. /* RFC7638 lexicographic order requires
  571. * RSA: e -> kty -> n
  572. * oct: k -> kty
  573. *
  574. * ie, meta and key data elements appear interleaved in name alpha order
  575. */
  576. p += lws_snprintf(p, end - p, "{");
  577. switch (jwk->kty) {
  578. case LWS_GENCRYPTO_KTY_OCT:
  579. l = lexico_oct;
  580. limit = LWS_ARRAY_SIZE(lexico_oct);
  581. break;
  582. case LWS_GENCRYPTO_KTY_RSA:
  583. l = lexico_rsa;
  584. limit = LWS_ARRAY_SIZE(lexico_rsa);
  585. asym = 1;
  586. break;
  587. case LWS_GENCRYPTO_KTY_EC:
  588. l = lexico_ec;
  589. limit = LWS_ARRAY_SIZE(lexico_ec);
  590. asym = 1;
  591. break;
  592. default:
  593. return -1;
  594. }
  595. for (n = 0; n < limit; n++) {
  596. const char *q, *q_end;
  597. char tok[12];
  598. int pos = 0, f = 1;
  599. if ((l->meta & 1) && (jwk->meta[l->idx].buf ||
  600. l->idx == (int)JWK_META_KTY)) {
  601. switch (l->idx) {
  602. case JWK_META_KTY:
  603. if (!first)
  604. *p++ = ',';
  605. first = 0;
  606. p += lws_snprintf(p, end - p, "\"%s\":\"%s\"",
  607. l->name, kty_names[jwk->kty]);
  608. break;
  609. case JWK_META_KEY_OPS:
  610. if (!first)
  611. *p++ = ',';
  612. first = 0;
  613. q = (const char *)jwk->meta[l->idx].buf;
  614. q_end = q + jwk->meta[l->idx].len;
  615. p += lws_snprintf(p, end - p,
  616. "\"%s\":[", l->name);
  617. /*
  618. * For the public version, usages that
  619. * require the private part must be
  620. * snipped
  621. */
  622. while (q < q_end) {
  623. if (*q != ' ' && pos < (int)sizeof(tok) - 1) {
  624. tok[pos++] = *q++;
  625. if (q != q_end)
  626. continue;
  627. }
  628. tok[pos] = '\0';
  629. pos = 0;
  630. if ((flags & LWSJWKF_EXPORT_PRIVATE) ||
  631. !asym || (strcmp(tok, "sign") &&
  632. strcmp(tok, "encrypt"))) {
  633. if (!f)
  634. *p++ = ',';
  635. f = 0;
  636. p += lws_snprintf(p, end - p,
  637. "\"%s\"", tok);
  638. }
  639. q++;
  640. }
  641. *p++ = ']';
  642. break;
  643. default:
  644. /* both sig and enc require asym private key */
  645. if (!(flags & LWSJWKF_EXPORT_PRIVATE) &&
  646. asym && l->idx == (int)JWK_META_USE)
  647. break;
  648. if (!first)
  649. *p++ = ',';
  650. first = 0;
  651. p += lws_snprintf(p, end - p, "\"%s\":\"",
  652. l->name);
  653. lws_strnncpy(p, (const char *)jwk->meta[l->idx].buf,
  654. jwk->meta[l->idx].len, end - p);
  655. p += strlen(p);
  656. p += lws_snprintf(p, end - p, "\"");
  657. break;
  658. }
  659. }
  660. if ((!(l->meta & 1)) && jwk->e[l->idx].buf &&
  661. ((flags & LWSJWKF_EXPORT_PRIVATE) || !(l->meta & 2))) {
  662. if (!first)
  663. *p++ = ',';
  664. first = 0;
  665. p += lws_snprintf(p, end - p, "\"%s\":\"", l->name);
  666. if (jwk->kty == LWS_GENCRYPTO_KTY_EC &&
  667. l->idx == (int)LWS_GENCRYPTO_EC_KEYEL_CRV) {
  668. lws_strnncpy(p,
  669. (const char *)jwk->e[l->idx].buf,
  670. jwk->e[l->idx].len, end - p);
  671. m = (int)strlen(p);
  672. } else
  673. m = lws_jws_base64_enc(
  674. (const char *)jwk->e[l->idx].buf,
  675. jwk->e[l->idx].len, p, end - p - 4);
  676. if (m < 0) {
  677. lwsl_notice("%s: enc failed\n", __func__);
  678. return -1;
  679. }
  680. p += m;
  681. p += lws_snprintf(p, end - p, "\"");
  682. }
  683. l++;
  684. }
  685. p += lws_snprintf(p, end - p,
  686. (flags & LWSJWKF_EXPORT_NOCRLF) ? "}" : "}\n");
  687. *len -= lws_ptr_diff(p, start);
  688. return lws_ptr_diff(p, start);
  689. }
  690. int
  691. lws_jwk_rfc7638_fingerprint(struct lws_jwk *jwk, char *digest32)
  692. {
  693. struct lws_genhash_ctx hash_ctx;
  694. int tmpsize = 2536, n;
  695. char *tmp;
  696. tmp = lws_malloc(tmpsize, "rfc7638 tmp");
  697. n = lws_jwk_export(jwk, LWSJWKF_EXPORT_NOCRLF, tmp, &tmpsize);
  698. if (n < 0)
  699. goto bail;
  700. if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256))
  701. goto bail;
  702. if (lws_genhash_update(&hash_ctx, tmp, n)) {
  703. lws_genhash_destroy(&hash_ctx, NULL);
  704. goto bail;
  705. }
  706. lws_free(tmp);
  707. if (lws_genhash_destroy(&hash_ctx, digest32))
  708. return -1;
  709. return 0;
  710. bail:
  711. lws_free(tmp);
  712. return -1;
  713. }
  714. int
  715. lws_jwk_strdup_meta(struct lws_jwk *jwk, enum enum_jwk_meta_tok idx,
  716. const char *in, int len)
  717. {
  718. jwk->meta[idx].buf = lws_malloc(len, __func__);
  719. if (!jwk->meta[idx].buf)
  720. return 1;
  721. jwk->meta[idx].len = len;
  722. memcpy(jwk->meta[idx].buf, in, len);
  723. return 0;
  724. }
  725. int
  726. lws_jwk_load(struct lws_jwk *jwk, const char *filename,
  727. lws_jwk_key_import_callback cb, void *user)
  728. {
  729. int buflen = 4096;
  730. char *buf = lws_malloc(buflen, "jwk-load");
  731. int n;
  732. if (!buf)
  733. return -1;
  734. n = lws_plat_read_file(filename, buf, buflen);
  735. if (n < 0)
  736. goto bail;
  737. n = lws_jwk_import(jwk, cb, user, buf, n);
  738. lws_free(buf);
  739. return n;
  740. bail:
  741. lws_free(buf);
  742. return -1;
  743. }
  744. int
  745. lws_jwk_save(struct lws_jwk *jwk, const char *filename)
  746. {
  747. int buflen = 4096;
  748. char *buf = lws_malloc(buflen, "jwk-save");
  749. int n, m;
  750. if (!buf)
  751. return -1;
  752. n = lws_jwk_export(jwk, LWSJWKF_EXPORT_PRIVATE, buf, &buflen);
  753. if (n < 0)
  754. goto bail;
  755. m = lws_plat_write_file(filename, buf, n);
  756. lws_free(buf);
  757. if (m)
  758. return -1;
  759. return 0;
  760. bail:
  761. lws_free(buf);
  762. return -1;
  763. }