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 #define WIN32_LEAN_AND_MEAN
26 #include "private-lib-core.h"
27 #include "private-lib-tls-openssl.h"
28 
29 #if !defined(LWS_PLAT_OPTEE)
30 static int
dec(char c)31 dec(char c)
32 {
33 	return c - '0';
34 }
35 #endif
36 
37 static time_t
lws_tls_openssl_asn1time_to_unix(ASN1_TIME * as)38 lws_tls_openssl_asn1time_to_unix(ASN1_TIME *as)
39 {
40 #if !defined(LWS_PLAT_OPTEE)
41 
42 	const char *p = (const char *)as->data;
43 	struct tm t;
44 
45 	/* [YY]YYMMDDHHMMSSZ */
46 
47 	memset(&t, 0, sizeof(t));
48 
49 	if (strlen(p) == 13) {
50 		t.tm_year = (dec(p[0]) * 10) + dec(p[1]) + 100;
51 		p += 2;
52 	} else {
53 		t.tm_year = (dec(p[0]) * 1000) + (dec(p[1]) * 100) +
54 			    (dec(p[2]) * 10) + dec(p[3]);
55 		p += 4;
56 	}
57 	t.tm_mon = (dec(p[0]) * 10) + dec(p[1]) - 1;
58 	p += 2;
59 	t.tm_mday = (dec(p[0]) * 10) + dec(p[1]) - 1;
60 	p += 2;
61 	t.tm_hour = (dec(p[0]) * 10) + dec(p[1]);
62 	p += 2;
63 	t.tm_min = (dec(p[0]) * 10) + dec(p[1]);
64 	p += 2;
65 	t.tm_sec = (dec(p[0]) * 10) + dec(p[1]);
66 	t.tm_isdst = 0;
67 
68 	return mktime(&t);
69 #else
70 	return (time_t)-1;
71 #endif
72 }
73 
74 int
lws_tls_openssl_cert_info(X509 * x509,enum lws_tls_cert_info type,union lws_tls_cert_info_results * buf,size_t len)75 lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type,
76 			  union lws_tls_cert_info_results *buf, size_t len)
77 {
78 	X509_NAME *xn;
79 #if !defined(LWS_PLAT_OPTEE)
80 	char *p;
81 #endif
82 
83 	if (!x509)
84 		return -1;
85 
86 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(X509_get_notBefore)
87 #define X509_get_notBefore(x)	X509_getm_notBefore(x)
88 #define X509_get_notAfter(x)	X509_getm_notAfter(x)
89 #endif
90 
91 	switch (type) {
92 	case LWS_TLS_CERT_INFO_VALIDITY_FROM:
93 		buf->time = lws_tls_openssl_asn1time_to_unix(
94 					X509_get_notBefore(x509));
95 		if (buf->time == (time_t)-1)
96 			return -1;
97 		break;
98 
99 	case LWS_TLS_CERT_INFO_VALIDITY_TO:
100 		buf->time = lws_tls_openssl_asn1time_to_unix(
101 					X509_get_notAfter(x509));
102 		if (buf->time == (time_t)-1)
103 			return -1;
104 		break;
105 
106 	case LWS_TLS_CERT_INFO_COMMON_NAME:
107 #if defined(LWS_PLAT_OPTEE)
108 		return -1;
109 #else
110 		xn = X509_get_subject_name(x509);
111 		if (!xn)
112 			return -1;
113 		X509_NAME_oneline(xn, buf->ns.name, (int)len - 2);
114 		p = strstr(buf->ns.name, "/CN=");
115 		if (p)
116 			memmove(buf->ns.name, p + 4, strlen(p + 4) + 1);
117 		buf->ns.len = (int)strlen(buf->ns.name);
118 		return 0;
119 #endif
120 	case LWS_TLS_CERT_INFO_ISSUER_NAME:
121 		xn = X509_get_issuer_name(x509);
122 		if (!xn)
123 			return -1;
124 		X509_NAME_oneline(xn, buf->ns.name, (int)len - 1);
125 		buf->ns.len = (int)strlen(buf->ns.name);
126 		return 0;
127 
128 	case LWS_TLS_CERT_INFO_USAGE:
129 #if defined(LWS_HAVE_X509_get_key_usage)
130 		buf->usage = X509_get_key_usage(x509);
131 		break;
132 #else
133 		return -1;
134 #endif
135 
136 	case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY:
137 	{
138 #ifndef USE_WOLFSSL
139 		size_t klen = (unsigned int)i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x509), NULL);
140 		uint8_t *tmp, *ptmp;
141 
142 		if (!klen || klen > len)
143 			return -1;
144 
145 		tmp = (uint8_t *)OPENSSL_malloc(klen);
146 		if (!tmp)
147 			return -1;
148 
149 		ptmp = tmp;
150 		if (i2d_X509_PUBKEY(
151 			      X509_get_X509_PUBKEY(x509), &ptmp) != (int)klen ||
152 		    !ptmp || lws_ptr_diff(ptmp, tmp) != (int)klen) {
153 			lwsl_info("%s: cert public key extraction failed\n",
154 				  __func__);
155 			if (ptmp)
156 				OPENSSL_free(tmp);
157 
158 			return -1;
159 		}
160 
161 		buf->ns.len = (int)klen;
162 		memcpy(buf->ns.name, tmp, klen);
163 		OPENSSL_free(tmp);
164 #endif
165 		return 0;
166 	}
167 	case LWS_TLS_CERT_INFO_DER_RAW:
168 	{
169 		int der_len = i2d_X509(x509, NULL);
170 		uint8_t *tmp = (uint8_t *)buf->ns.name;
171 
172 		buf->ns.len = der_len < 0 ? 0 : der_len;
173 
174 		if (der_len < 0 || (size_t)der_len > len)
175 			return -1;
176 
177 		der_len = i2d_X509(x509, &tmp);
178 		if (der_len < 0)
179 			return -1;
180 
181 		return 0;
182 	}
183 	default:
184 		return -1;
185 	}
186 
187 	return 0;
188 }
189 
190 int
lws_x509_info(struct lws_x509_cert * x509,enum lws_tls_cert_info type,union lws_tls_cert_info_results * buf,size_t len)191 lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
192 	      union lws_tls_cert_info_results *buf, size_t len)
193 {
194 	return lws_tls_openssl_cert_info(x509->cert, type, buf, len);
195 }
196 
197 #if defined(LWS_WITH_NETWORK)
198 int
lws_tls_vhost_cert_info(struct lws_vhost * vhost,enum lws_tls_cert_info type,union lws_tls_cert_info_results * buf,size_t len)199 lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
200 		        union lws_tls_cert_info_results *buf, size_t len)
201 {
202 #if defined(LWS_HAVE_SSL_CTX_get0_certificate)
203 	X509 *x509 = SSL_CTX_get0_certificate(vhost->tls.ssl_ctx);
204 
205 	return lws_tls_openssl_cert_info(x509, type, buf, len);
206 #else
207 	lwsl_notice("openssl is too old to support %s\n", __func__);
208 
209 	return -1;
210 #endif
211 }
212 
213 
214 
215 int
lws_tls_peer_cert_info(struct lws * wsi,enum lws_tls_cert_info type,union lws_tls_cert_info_results * buf,size_t len)216 lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
217 		       union lws_tls_cert_info_results *buf, size_t len)
218 {
219 	int rc = 0;
220 	X509 *x509;
221 
222 	wsi = lws_get_network_wsi(wsi);
223 
224 	x509 = SSL_get_peer_certificate(wsi->tls.ssl);
225 
226 	if (!x509) {
227 		lwsl_debug("no peer cert\n");
228 
229 		return -1;
230 	}
231 
232 	switch (type) {
233 	case LWS_TLS_CERT_INFO_VERIFIED:
234 		buf->verified = SSL_get_verify_result(wsi->tls.ssl) ==
235 					X509_V_OK;
236 		break;
237 	default:
238 		rc = lws_tls_openssl_cert_info(x509, type, buf, len);
239 	}
240 
241 	X509_free(x509);
242 
243 	return rc;
244 }
245 #endif
246 
247 int
lws_x509_create(struct lws_x509_cert ** x509)248 lws_x509_create(struct lws_x509_cert **x509)
249 {
250 	*x509 = lws_malloc(sizeof(**x509), __func__);
251 	if (*x509)
252 		(*x509)->cert = NULL;
253 
254 	return !(*x509);
255 }
256 
257 int
lws_x509_parse_from_pem(struct lws_x509_cert * x509,const void * pem,size_t len)258 lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len)
259 {
260 	BIO* bio = BIO_new(BIO_s_mem());
261 
262 	BIO_write(bio, pem, (int)len);
263 	x509->cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
264 	BIO_free(bio);
265 	if (!x509->cert) {
266 		lwsl_err("%s: unable to parse PEM cert\n", __func__);
267 		lws_tls_err_describe_clear();
268 
269 		return -1;
270 	}
271 
272 	return 0;
273 }
274 
275 int
lws_x509_verify(struct lws_x509_cert * x509,struct lws_x509_cert * trusted,const char * common_name)276 lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted,
277 		const char *common_name)
278 {
279 	char c[32], *p;
280 	int ret;
281 
282 	if (common_name) {
283 		X509_NAME *xn = X509_get_subject_name(x509->cert);
284 		if (!xn)
285 			return -1;
286 		X509_NAME_oneline(xn, c, (int)sizeof(c) - 2);
287 		p = strstr(c, "/CN=");
288 		if (p)
289 			p = p + 4;
290 		else
291 			p = c;
292 
293 		if (strcmp(p, common_name)) {
294 			lwsl_err("%s: common name mismatch\n", __func__);
295 			return -1;
296 		}
297 	}
298 
299 	ret = X509_check_issued(trusted->cert, x509->cert);
300 	if (ret != X509_V_OK) {
301 		lwsl_err("%s: unable to verify cert relationship\n", __func__);
302 		lws_tls_err_describe_clear();
303 
304 		return -1;
305 	}
306 
307 	return 0;
308 }
309 
310 #if defined(LWS_WITH_JOSE)
311 int
lws_x509_public_to_jwk(struct lws_jwk * jwk,struct lws_x509_cert * x509,const char * curves,int rsa_min_bits)312 lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
313 		       const char *curves, int rsa_min_bits)
314 {
315 	int id, n, ret = -1, count;
316 	ASN1_OBJECT *obj = NULL;
317 	const EC_POINT *ecpoint;
318 	const EC_GROUP *ecgroup;
319 	EC_KEY *ecpub = NULL;
320 	X509_PUBKEY *pubkey;
321 	RSA *rsapub = NULL;
322 	BIGNUM *mpi[4];
323 	EVP_PKEY *pkey;
324 
325 	memset(jwk, 0, sizeof(*jwk));
326 
327 	pubkey = X509_get_X509_PUBKEY(x509->cert);
328 	if (!pubkey) {
329 		lwsl_err("%s: missing pubkey alg in cert\n", __func__);
330 
331 		goto bail;
332 	}
333 
334 	if (X509_PUBKEY_get0_param(&obj, NULL, NULL, NULL, pubkey) != 1) {
335 		lwsl_err("%s: missing pubkey alg in cert\n", __func__);
336 
337 		goto bail;
338 	}
339 
340 	id = OBJ_obj2nid(obj);
341 	if (id == NID_undef) {
342 		lwsl_err("%s: missing pubkey alg in cert\n", __func__);
343 
344 		goto bail;
345 	}
346 
347 	lwsl_debug("%s: key type %d \"%s\"\n", __func__, id, OBJ_nid2ln(id));
348 
349 	pkey = X509_get_pubkey(x509->cert);
350 	if (!pkey) {
351 		lwsl_notice("%s: unable to extract pubkey", __func__);
352 
353 		goto bail;
354 	}
355 
356 	switch (id) {
357 	case NID_X9_62_id_ecPublicKey:
358 		lwsl_debug("%s: EC key\n", __func__);
359 		jwk->kty = LWS_GENCRYPTO_KTY_EC;
360 
361 		if (!curves) {
362 			lwsl_err("%s: ec curves not allowed\n", __func__);
363 
364 			goto bail1;
365 		}
366 
367 		ecpub = EVP_PKEY_get1_EC_KEY(pkey);
368 		if (!ecpub) {
369 			lwsl_notice("%s: missing EC pubkey\n", __func__);
370 
371 			goto bail1;
372 		}
373 
374 		ecpoint = EC_KEY_get0_public_key(ecpub);
375 		if (!ecpoint) {
376 			lwsl_err("%s: EC_KEY_get0_public_key failed\n", __func__);
377 			goto bail2;
378 		}
379 
380 		ecgroup = EC_KEY_get0_group(ecpub);
381 		if (!ecgroup) {
382 			lwsl_err("%s: EC_KEY_get0_group failed\n", __func__);
383 			goto bail2;
384 		}
385 
386 		/* validate the curve against ones we allow */
387 
388 		if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
389 				EC_GROUP_get_curve_name(ecgroup), jwk))
390 			/* already logged */
391 			goto bail2;
392 
393 		mpi[LWS_GENCRYPTO_EC_KEYEL_CRV] = NULL;
394 		mpi[LWS_GENCRYPTO_EC_KEYEL_X] = BN_new(); /* X */
395 		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = NULL;
396 		mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = BN_new(); /* Y */
397 
398 #if defined(LWS_HAVE_EC_POINT_get_affine_coordinates)
399 		if (EC_POINT_get_affine_coordinates(ecgroup, ecpoint,
400 #else
401 		if (EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint,
402 #endif
403 						  mpi[LWS_GENCRYPTO_EC_KEYEL_X],
404 						  mpi[LWS_GENCRYPTO_EC_KEYEL_Y],
405 							  NULL) != 1) {
406 			BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
407 			BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
408 			lwsl_err("%s: EC_POINT_get_aff failed\n", __func__);
409 			goto bail2;
410 		}
411 		count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
412 		n = LWS_GENCRYPTO_EC_KEYEL_X;
413 		break;
414 
415 	case NID_rsaEncryption:
416 		lwsl_debug("%s: rsa key\n", __func__);
417 		jwk->kty = LWS_GENCRYPTO_KTY_RSA;
418 
419 		rsapub = EVP_PKEY_get1_RSA(pkey);
420 		if (!rsapub) {
421 			lwsl_notice("%s: missing RSA pubkey\n", __func__);
422 
423 			goto bail1;
424 		}
425 
426 		if ((size_t)RSA_size(rsapub) * 8 < (size_t)rsa_min_bits) {
427 			lwsl_err("%s: key bits %d less than minimum %d\n",
428 				 __func__, RSA_size(rsapub) * 8, rsa_min_bits);
429 
430 			goto bail2;
431 		}
432 
433 #if defined(LWS_HAVE_RSA_SET0_KEY)
434 		/* we don't need d... but the api wants to write it */
435 		RSA_get0_key(rsapub,
436 			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
437 			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_E],
438 			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
439 #else
440 		mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = rsapub->e;
441 		mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = rsapub->n;
442 		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = NULL;
443 #endif
444 		count = LWS_GENCRYPTO_RSA_KEYEL_D;
445 		n = LWS_GENCRYPTO_RSA_KEYEL_E;
446 		break;
447 	default:
448 		lwsl_err("%s: unknown NID\n", __func__);
449 		goto bail2;
450 	}
451 
452 	for (; n < count; n++) {
453 		if (!mpi[n])
454 			continue;
455 		jwk->e[n].len = (unsigned int)BN_num_bytes(mpi[n]);
456 		jwk->e[n].buf = lws_malloc(jwk->e[n].len, "certkeyimp");
457 		if (!jwk->e[n].buf) {
458 			if (id == NID_X9_62_id_ecPublicKey) {
459 				BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
460 				BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
461 			}
462 			goto bail2;
463 		}
464 		BN_bn2bin(mpi[n], jwk->e[n].buf);
465 	}
466 
467 	if (id == NID_X9_62_id_ecPublicKey) {
468 		BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
469 		BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
470 	}
471 
472 	ret = 0;
473 
474 bail2:
475 	if (id == NID_X9_62_id_ecPublicKey)
476 		EC_KEY_free(ecpub);
477 	else
478 		RSA_free(rsapub);
479 
480 bail1:
481 	EVP_PKEY_free(pkey);
482 bail:
483 	/* jwk destroy will clean any partial state */
484 	if (ret)
485 		lws_jwk_destroy(jwk);
486 
487 	return ret;
488 }
489 
490 static int
lws_x509_jwk_privkey_pem_pp_cb(char * buf,int size,int rwflag,void * u)491 lws_x509_jwk_privkey_pem_pp_cb(char *buf, int size, int rwflag, void *u)
492 {
493 	const char *pp = (const char *)u;
494 	size_t n = strlen(pp);
495 
496 	if ((int)n > size - 1)
497 		return -1;
498 
499 	memcpy(buf, pp, n + 1);
500 
501 	return (int)n;
502 }
503 
504 int
lws_x509_jwk_privkey_pem(struct lws_jwk * jwk,void * pem,size_t len,const char * passphrase)505 lws_x509_jwk_privkey_pem(struct lws_jwk *jwk, void *pem, size_t len,
506 			 const char *passphrase)
507 {
508 	BIO* bio = BIO_new(BIO_s_mem());
509 	BIGNUM *mpi, *dummy[6];
510 	EVP_PKEY *pkey = NULL;
511 	EC_KEY *ecpriv = NULL;
512 	RSA *rsapriv = NULL;
513 	const BIGNUM *cmpi;
514 	int n, m, ret = -1;
515 
516 	BIO_write(bio, pem, (int)len);
517 	PEM_read_bio_PrivateKey(bio, &pkey, lws_x509_jwk_privkey_pem_pp_cb,
518 				(void *)passphrase);
519 	BIO_free(bio);
520 	lws_explicit_bzero((void *)pem, len);
521 	if (!pkey) {
522 		lwsl_err("%s: unable to parse PEM privkey\n", __func__);
523 		lws_tls_err_describe_clear();
524 
525 		return -1;
526 	}
527 
528 	/* confirm the key type matches the existing jwk situation */
529 
530 	switch (jwk->kty) {
531 	case LWS_GENCRYPTO_KTY_EC:
532 		if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) {
533 			lwsl_err("%s: jwk is EC but privkey isn't\n", __func__);
534 
535 			goto bail;
536 		}
537 		ecpriv = EVP_PKEY_get1_EC_KEY(pkey);
538 		if (!ecpriv) {
539 			lwsl_notice("%s: missing EC key\n", __func__);
540 
541 			goto bail;
542 		}
543 
544 		cmpi = EC_KEY_get0_private_key(ecpriv);
545 
546 		/* quick size check first */
547 
548 		n = BN_num_bytes(cmpi);
549 		if (jwk->e[LWS_GENCRYPTO_EC_KEYEL_Y].len != (uint32_t)n) {
550 			lwsl_err("%s: jwk key size doesn't match\n", __func__);
551 
552 			goto bail1;
553 		}
554 
555 		/* TODO.. check public curve / group + point */
556 
557 		jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len = (unsigned int)n;
558 		jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf = lws_malloc((unsigned int)n, "ec");
559 		if (!jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf)
560 			goto bail1;
561 
562 		m = BN_bn2binpad(cmpi, jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf,
563 				      (int32_t)jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len);
564 		if ((unsigned int)m != (unsigned int)BN_num_bytes(cmpi))
565 			goto bail1;
566 
567 		break;
568 
569 	case LWS_GENCRYPTO_KTY_RSA:
570 		if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_RSA) {
571 			lwsl_err("%s: RSA jwk, non-RSA privkey\n", __func__);
572 
573 			goto bail;
574 		}
575 		rsapriv = EVP_PKEY_get1_RSA(pkey);
576 		if (!rsapriv) {
577 			lwsl_notice("%s: missing RSA key\n", __func__);
578 
579 			goto bail;
580 		}
581 
582 #if defined(LWS_HAVE_RSA_SET0_KEY)
583 		RSA_get0_key(rsapriv, (const BIGNUM **)&dummy[0], /* n */
584 				      (const BIGNUM **)&dummy[1], /* e */
585 				      (const BIGNUM **)&mpi);	  /* d */
586 		RSA_get0_factors(rsapriv, (const BIGNUM **)&dummy[4],  /* p */
587 					  (const BIGNUM **)&dummy[5]); /* q */
588 #else
589 		dummy[0] = rsapriv->n;
590 		dummy[1] = rsapriv->e;
591 		dummy[4] = rsapriv->p;
592 		dummy[5] = rsapriv->q;
593 		mpi = rsapriv->d;
594 #endif
595 
596 		/* quick size check first */
597 
598 		n = BN_num_bytes(mpi);
599 		if (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len != (uint32_t)n) {
600 			lwsl_err("%s: jwk key size doesn't match\n", __func__);
601 
602 			goto bail1;
603 		}
604 
605 		/* then check that n & e match what we got from the cert */
606 
607 		dummy[2] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].buf,
608 				     (int32_t)jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len,
609 				     NULL);
610 		dummy[3] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].buf,
611 				     (int32_t)jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].len,
612 				     NULL);
613 
614 		m = BN_cmp(dummy[2], dummy[0]) | BN_cmp(dummy[3], dummy[1]);
615 		BN_clear_free(dummy[2]);
616 		BN_clear_free(dummy[3]);
617 		if (m) {
618 			lwsl_err("%s: privkey doesn't match jwk pubkey\n",
619 				 __func__);
620 
621 			goto bail1;
622 		}
623 
624 		/* accept d from the PEM privkey into the JWK */
625 
626 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].len = (unsigned int)n;
627 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf = lws_malloc((unsigned int)n, "privjk");
628 		if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf)
629 			goto bail1;
630 
631 		BN_bn2bin(mpi, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
632 
633 		/* accept p and q from the PEM privkey into the JWK */
634 
635 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].len = (unsigned int)BN_num_bytes(dummy[4]);
636 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf = lws_malloc((unsigned int)n, "privjk");
637 		if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf) {
638 			lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
639 			goto bail1;
640 		}
641 		BN_bn2bin(dummy[4], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf);
642 
643 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].len = (unsigned int)BN_num_bytes(dummy[5]);
644 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf = lws_malloc((unsigned int)n, "privjk");
645 		if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf) {
646 			lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
647 			lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf);
648 			goto bail1;
649 		}
650 		BN_bn2bin(dummy[5], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf);
651 		break;
652 	default:
653 		lwsl_err("%s: JWK has unknown kty %d\n", __func__, jwk->kty);
654 		return -1;
655 	}
656 
657 	ret = 0;
658 
659 bail1:
660 	if (jwk->kty == LWS_GENCRYPTO_KTY_EC)
661 		EC_KEY_free(ecpriv);
662 	else
663 		RSA_free(rsapriv);
664 
665 bail:
666 	EVP_PKEY_free(pkey);
667 
668 	return ret;
669 }
670 #endif
671 
672 void
lws_x509_destroy(struct lws_x509_cert ** x509)673 lws_x509_destroy(struct lws_x509_cert **x509)
674 {
675 	if (!*x509)
676 		return;
677 
678 	if ((*x509)->cert) {
679 		X509_free((*x509)->cert);
680 		(*x509)->cert = NULL;
681 	}
682 
683 	lws_free_set_NULL(*x509);
684 }
685