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