• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if defined(USE_WOLFSSL)
75 #define AUTHORITY_KEYID WOLFSSL_AUTHORITY_KEYID
76 #endif
77 
78 int
lws_tls_openssl_cert_info(X509 * x509,enum lws_tls_cert_info type,union lws_tls_cert_info_results * buf,size_t len)79 lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type,
80 			  union lws_tls_cert_info_results *buf, size_t len)
81 {
82 #ifndef USE_WOLFSSL
83 	const unsigned char *dp;
84 	ASN1_OCTET_STRING *val;
85 	AUTHORITY_KEYID *akid;
86 	X509_EXTENSION *ext;
87 	int tag, xclass, r = 1;
88 	long xlen, loc;
89 #endif
90 	X509_NAME *xn;
91 #if !defined(LWS_PLAT_OPTEE)
92 	char *p;
93 #endif
94 
95 	buf->ns.len = 0;
96 
97 	if (!x509)
98 		return -1;
99 	if (!len)
100 		len = sizeof(buf->ns.name);
101 
102 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(X509_get_notBefore)
103 #define X509_get_notBefore(x)	X509_getm_notBefore(x)
104 #define X509_get_notAfter(x)	X509_getm_notAfter(x)
105 #endif
106 
107 	switch (type) {
108 	case LWS_TLS_CERT_INFO_VALIDITY_FROM:
109 		buf->time = lws_tls_openssl_asn1time_to_unix(
110 					X509_get_notBefore(x509));
111 		if (buf->time == (time_t)-1)
112 			return -1;
113 		break;
114 
115 	case LWS_TLS_CERT_INFO_VALIDITY_TO:
116 		buf->time = lws_tls_openssl_asn1time_to_unix(
117 					X509_get_notAfter(x509));
118 		if (buf->time == (time_t)-1)
119 			return -1;
120 		break;
121 
122 	case LWS_TLS_CERT_INFO_COMMON_NAME:
123 #if defined(LWS_PLAT_OPTEE)
124 		return -1;
125 #else
126 		xn = X509_get_subject_name(x509);
127 		if (!xn)
128 			return -1;
129 		X509_NAME_oneline(xn, buf->ns.name, (int)len - 2);
130 		p = strstr(buf->ns.name, "/CN=");
131 		if (p)
132 			memmove(buf->ns.name, p + 4, strlen(p + 4) + 1);
133 		buf->ns.len = (int)strlen(buf->ns.name);
134 		return 0;
135 #endif
136 	case LWS_TLS_CERT_INFO_ISSUER_NAME:
137 		xn = X509_get_issuer_name(x509);
138 		if (!xn)
139 			return -1;
140 		X509_NAME_oneline(xn, buf->ns.name, (int)len - 1);
141 		buf->ns.len = (int)strlen(buf->ns.name);
142 		return 0;
143 
144 	case LWS_TLS_CERT_INFO_USAGE:
145 #if defined(LWS_HAVE_X509_get_key_usage)
146 		buf->usage = X509_get_key_usage(x509);
147 		break;
148 #else
149 		return -1;
150 #endif
151 
152 	case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY:
153 	{
154 #ifndef USE_WOLFSSL
155 		size_t klen = (unsigned int)i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x509), NULL);
156 		uint8_t *tmp, *ptmp;
157 
158 		if (!klen || klen > len)
159 			return -1;
160 
161 		tmp = (uint8_t *)OPENSSL_malloc(klen);
162 		if (!tmp)
163 			return -1;
164 
165 		ptmp = tmp;
166 		if (i2d_X509_PUBKEY(
167 			      X509_get_X509_PUBKEY(x509), &ptmp) != (int)klen ||
168 		    !ptmp || lws_ptr_diff(ptmp, tmp) != (int)klen) {
169 			lwsl_info("%s: cert public key extraction failed\n",
170 				  __func__);
171 			if (ptmp)
172 				OPENSSL_free(tmp);
173 
174 			return -1;
175 		}
176 
177 		buf->ns.len = (int)klen;
178 		memcpy(buf->ns.name, tmp, klen);
179 		OPENSSL_free(tmp);
180 #endif
181 		return 0;
182 	}
183 	case LWS_TLS_CERT_INFO_DER_RAW:
184 	{
185 		int der_len = i2d_X509(x509, NULL);
186 		uint8_t *tmp = (uint8_t *)buf->ns.name;
187 
188 		buf->ns.len = der_len < 0 ? 0 : der_len;
189 
190 		if (der_len < 0 || (size_t)der_len > len)
191 			return -1;
192 
193 		der_len = i2d_X509(x509, &tmp);
194 		if (der_len < 0)
195 			return -1;
196 
197 		return 0;
198 	}
199 
200 #ifndef USE_WOLFSSL
201 
202 	case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID:
203 		loc = X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1);
204 		if (loc < 0)
205 			return 1;
206 
207 		ext = X509_get_ext(x509, (int)loc);
208 		if (!ext)
209 			return 1;
210 #ifndef USE_WOLFSSL
211 		akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
212 #else
213 		akid = (AUTHORITY_KEYID *)wolfSSL_X509V3_EXT_d2i(ext);
214 #endif
215 		if (!akid || !akid->keyid)
216 			return 1;
217 		val = akid->keyid;
218 		dp = (const unsigned char *)val->data;
219 		xlen = val->length;
220 
221 		buf->ns.len = (int)xlen;
222 		if (len < (size_t)buf->ns.len)
223 			return -1;
224 
225 		memcpy(buf->ns.name, dp, (size_t)buf->ns.len);
226 
227 		AUTHORITY_KEYID_free(akid);
228 		break;
229 
230 	case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_ISSUER:
231 		loc = X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1);
232 		if (loc < 0)
233 			return 1;
234 
235 		ext = X509_get_ext(x509, (int)loc);
236 		if (!ext)
237 			return 1;
238 
239 #ifndef USE_WOLFSSL
240 		akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
241 #else
242 		akid = (AUTHORITY_KEYID *)wolfSSL_X509V3_EXT_d2i(ext);
243 #endif
244 		if (!akid || !akid->issuer)
245 			return 1;
246 
247 #if defined(LWS_HAVE_OPENSSL_STACK)
248 		{
249 			const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
250 			STACK_OF(CONF_VALUE) *cv;
251 			int j;
252 
253 			cv = i2v_GENERAL_NAMES((X509V3_EXT_METHOD*)method, akid->issuer, NULL);
254 			if (!cv)
255 				goto bail_ak;
256 
257 		        for (j = 0; j < OPENSSL_sk_num((const OPENSSL_STACK *)&cv); j++) {
258 		            CONF_VALUE *nval = OPENSSL_sk_value((const OPENSSL_STACK *)&cv, j);
259 		            size_t ln = (nval->name ? strlen(nval->name) : 0),
260 		        	   lv = (nval->value ? strlen(nval->value) : 0),
261 		        	   l = ln + lv;
262 
263 		            if (len > l) {
264 		        	    if (nval->name)
265 		        		    memcpy(buf->ns.name + buf->ns.len, nval->name, ln);
266 		        	    if (nval->value)
267 		        		    memcpy(buf->ns.name + buf->ns.len + ln, nval->value, lv);
268 		        	    buf->ns.len = (int)((size_t)buf->ns.len + l);
269 		        	    len -= l;
270 		        	    buf->ns.name[buf->ns.len] = '\0';
271 
272 		        	    r = 0;
273 		            }
274 		        }
275 		}
276 
277 bail_ak:
278 #endif
279 		AUTHORITY_KEYID_free(akid);
280 
281 		return r;
282 
283 	case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_SERIAL:
284 		loc = X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1);
285 		if (loc < 0)
286 			return 1;
287 
288 		ext = X509_get_ext(x509, (int)loc);
289 		if (!ext)
290 			return 1;
291 		akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
292 		if (!akid || !akid->serial)
293 			return 1;
294 
295 #if 0
296 		// need to handle blobs, and ASN1_INTEGER_get_uint64 not
297 		// available on older openssl
298 		{
299 			uint64_t res;
300 			if (ASN1_INTEGER_get_uint64(&res, akid->serial) != 1)
301 				break;
302 			buf->ns.len = lws_snprintf(buf->ns.name, len, "%llu",
303 					(unsigned long long)res);
304 		}
305 #endif
306 		break;
307 
308 	case LWS_TLS_CERT_INFO_SUBJECT_KEY_ID:
309 
310 		loc = X509_get_ext_by_NID(x509, NID_subject_key_identifier, -1);
311 		if (loc < 0)
312 			return 1;
313 
314 		ext = X509_get_ext(x509, (int)loc);
315 		if (!ext)
316 			return 1;
317 
318 		val = X509_EXTENSION_get_data(ext);
319 		if (!val)
320 			return 1;
321 
322 #if defined(USE_WOLFSSL)
323 		return 1;
324 #else
325 		dp = (const unsigned char *)val->data;
326 
327 		if (ASN1_get_object(&dp, &xlen,
328 				    &tag, &xclass, val->length) & 0x80)
329 			return -1;
330 
331 		if (tag != V_ASN1_OCTET_STRING) {
332 			lwsl_notice("not octet string %d\n", (int)tag);
333 			return 1;
334 		}
335 #endif
336 		buf->ns.len = (int)xlen;
337 		if (len < (size_t)buf->ns.len)
338 			return -1;
339 
340 		memcpy(buf->ns.name, dp, (size_t)buf->ns.len);
341 		break;
342 #endif
343 
344 	default:
345 		return -1;
346 	}
347 
348 	return 0;
349 }
350 
351 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)352 lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
353 	      union lws_tls_cert_info_results *buf, size_t len)
354 {
355 	return lws_tls_openssl_cert_info(x509->cert, type, buf, len);
356 }
357 
358 #if defined(LWS_WITH_NETWORK)
359 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)360 lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
361 		        union lws_tls_cert_info_results *buf, size_t len)
362 {
363 #if defined(LWS_HAVE_SSL_CTX_get0_certificate)
364 	X509 *x509 = SSL_CTX_get0_certificate(vhost->tls.ssl_ctx);
365 
366 	return lws_tls_openssl_cert_info(x509, type, buf, len);
367 #else
368 	lwsl_notice("openssl is too old to support %s\n", __func__);
369 
370 	return -1;
371 #endif
372 }
373 
374 
375 
376 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)377 lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
378 		       union lws_tls_cert_info_results *buf, size_t len)
379 {
380 	int rc = 0;
381 	X509 *x509;
382 
383 	wsi = lws_get_network_wsi(wsi);
384 
385 	x509 = SSL_get_peer_certificate(wsi->tls.ssl);
386 
387 	if (!x509) {
388 		lwsl_debug("no peer cert\n");
389 
390 		return -1;
391 	}
392 
393 	switch (type) {
394 	case LWS_TLS_CERT_INFO_VERIFIED:
395 		buf->verified = SSL_get_verify_result(wsi->tls.ssl) ==
396 					X509_V_OK;
397 		break;
398 	default:
399 		rc = lws_tls_openssl_cert_info(x509, type, buf, len);
400 	}
401 
402 	X509_free(x509);
403 
404 	return rc;
405 }
406 #endif
407 
408 int
lws_x509_create(struct lws_x509_cert ** x509)409 lws_x509_create(struct lws_x509_cert **x509)
410 {
411 	*x509 = lws_malloc(sizeof(**x509), __func__);
412 	if (*x509)
413 		(*x509)->cert = NULL;
414 
415 	return !(*x509);
416 }
417 
418 int
lws_x509_parse_from_pem(struct lws_x509_cert * x509,const void * pem,size_t len)419 lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len)
420 {
421 	BIO* bio = BIO_new(BIO_s_mem());
422 
423 	BIO_write(bio, pem, (int)len);
424 	x509->cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
425 	BIO_free(bio);
426 	if (!x509->cert) {
427 		lwsl_err("%s: unable to parse PEM cert\n", __func__);
428 		lws_tls_err_describe_clear();
429 
430 		return -1;
431 	}
432 
433 	return 0;
434 }
435 
436 int
lws_x509_verify(struct lws_x509_cert * x509,struct lws_x509_cert * trusted,const char * common_name)437 lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted,
438 		const char *common_name)
439 {
440 	char c[32], *p;
441 	int ret;
442 
443 	if (common_name) {
444 		X509_NAME *xn = X509_get_subject_name(x509->cert);
445 		if (!xn)
446 			return -1;
447 		X509_NAME_oneline(xn, c, (int)sizeof(c) - 2);
448 		p = strstr(c, "/CN=");
449 		if (p)
450 			p = p + 4;
451 		else
452 			p = c;
453 
454 		if (strcmp(p, common_name)) {
455 			lwsl_err("%s: common name mismatch\n", __func__);
456 			return -1;
457 		}
458 	}
459 
460 	ret = X509_check_issued(trusted->cert, x509->cert);
461 	if (ret != X509_V_OK) {
462 		lwsl_err("%s: unable to verify cert relationship\n", __func__);
463 		lws_tls_err_describe_clear();
464 
465 		return -1;
466 	}
467 
468 	return 0;
469 }
470 
471 #if defined(LWS_WITH_JOSE)
472 int
lws_x509_public_to_jwk(struct lws_jwk * jwk,struct lws_x509_cert * x509,const char * curves,int rsa_min_bits)473 lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
474 		       const char *curves, int rsa_min_bits)
475 {
476 	int id, n, ret = -1, count;
477 	ASN1_OBJECT *obj = NULL;
478 	const EC_POINT *ecpoint;
479 	const EC_GROUP *ecgroup;
480 	EC_KEY *ecpub = NULL;
481 	X509_PUBKEY *pubkey;
482 	RSA *rsapub = NULL;
483 	BIGNUM *mpi[4];
484 	EVP_PKEY *pkey;
485 
486 	memset(jwk, 0, sizeof(*jwk));
487 
488 	pubkey = X509_get_X509_PUBKEY(x509->cert);
489 	if (!pubkey) {
490 		lwsl_err("%s: missing pubkey alg in cert\n", __func__);
491 
492 		goto bail;
493 	}
494 
495 	if (X509_PUBKEY_get0_param(&obj, NULL, NULL, NULL, pubkey) != 1) {
496 		lwsl_err("%s: missing pubkey alg in cert\n", __func__);
497 
498 		goto bail;
499 	}
500 
501 	id = OBJ_obj2nid(obj);
502 	if (id == NID_undef) {
503 		lwsl_err("%s: missing pubkey alg in cert\n", __func__);
504 
505 		goto bail;
506 	}
507 
508 	lwsl_debug("%s: key type %d \"%s\"\n", __func__, id, OBJ_nid2ln(id));
509 
510 	pkey = X509_get_pubkey(x509->cert);
511 	if (!pkey) {
512 		lwsl_notice("%s: unable to extract pubkey", __func__);
513 
514 		goto bail;
515 	}
516 
517 	switch (id) {
518 	case NID_X9_62_id_ecPublicKey:
519 		lwsl_debug("%s: EC key\n", __func__);
520 		jwk->kty = LWS_GENCRYPTO_KTY_EC;
521 
522 		if (!curves) {
523 			lwsl_err("%s: ec curves not allowed\n", __func__);
524 
525 			goto bail1;
526 		}
527 
528 		ecpub = EVP_PKEY_get1_EC_KEY(pkey);
529 		if (!ecpub) {
530 			lwsl_notice("%s: missing EC pubkey\n", __func__);
531 
532 			goto bail1;
533 		}
534 
535 		ecpoint = EC_KEY_get0_public_key(ecpub);
536 		if (!ecpoint) {
537 			lwsl_err("%s: EC_KEY_get0_public_key failed\n", __func__);
538 			goto bail2;
539 		}
540 
541 		ecgroup = EC_KEY_get0_group(ecpub);
542 		if (!ecgroup) {
543 			lwsl_err("%s: EC_KEY_get0_group failed\n", __func__);
544 			goto bail2;
545 		}
546 
547 		/* validate the curve against ones we allow */
548 
549 		if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
550 				EC_GROUP_get_curve_name(ecgroup), jwk))
551 			/* already logged */
552 			goto bail2;
553 
554 		mpi[LWS_GENCRYPTO_EC_KEYEL_CRV] = NULL;
555 		mpi[LWS_GENCRYPTO_EC_KEYEL_X] = BN_new(); /* X */
556 		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = NULL;
557 		mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = BN_new(); /* Y */
558 
559 #if defined(LWS_HAVE_EC_POINT_get_affine_coordinates)
560 		if (EC_POINT_get_affine_coordinates(ecgroup, ecpoint,
561 #else
562 		if (EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint,
563 #endif
564 						  mpi[LWS_GENCRYPTO_EC_KEYEL_X],
565 						  mpi[LWS_GENCRYPTO_EC_KEYEL_Y],
566 							  NULL) != 1) {
567 			BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
568 			BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
569 			lwsl_err("%s: EC_POINT_get_aff failed\n", __func__);
570 			goto bail2;
571 		}
572 		count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
573 		n = LWS_GENCRYPTO_EC_KEYEL_X;
574 		break;
575 
576 	case NID_rsaEncryption:
577 		lwsl_debug("%s: rsa key\n", __func__);
578 		jwk->kty = LWS_GENCRYPTO_KTY_RSA;
579 
580 		rsapub = EVP_PKEY_get1_RSA(pkey);
581 		if (!rsapub) {
582 			lwsl_notice("%s: missing RSA pubkey\n", __func__);
583 
584 			goto bail1;
585 		}
586 
587 		if ((size_t)RSA_size(rsapub) * 8 < (size_t)rsa_min_bits) {
588 			lwsl_err("%s: key bits %d less than minimum %d\n",
589 				 __func__, RSA_size(rsapub) * 8, rsa_min_bits);
590 
591 			goto bail2;
592 		}
593 
594 #if defined(LWS_HAVE_RSA_SET0_KEY)
595 		/* we don't need d... but the api wants to write it */
596 		RSA_get0_key(rsapub,
597 			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
598 			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_E],
599 			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
600 #else
601 		mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = rsapub->e;
602 		mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = rsapub->n;
603 		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = NULL;
604 #endif
605 		count = LWS_GENCRYPTO_RSA_KEYEL_D;
606 		n = LWS_GENCRYPTO_RSA_KEYEL_E;
607 		break;
608 	default:
609 		lwsl_err("%s: unknown NID\n", __func__);
610 		goto bail2;
611 	}
612 
613 	for (; n < count; n++) {
614 		if (!mpi[n])
615 			continue;
616 		jwk->e[n].len = (unsigned int)BN_num_bytes(mpi[n]);
617 		jwk->e[n].buf = lws_malloc(jwk->e[n].len, "certkeyimp");
618 		if (!jwk->e[n].buf) {
619 			if (id == NID_X9_62_id_ecPublicKey) {
620 				BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
621 				BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
622 			}
623 			goto bail2;
624 		}
625 		BN_bn2bin(mpi[n], jwk->e[n].buf);
626 	}
627 
628 	if (id == NID_X9_62_id_ecPublicKey) {
629 		BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
630 		BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
631 	}
632 
633 	ret = 0;
634 
635 bail2:
636 	if (id == NID_X9_62_id_ecPublicKey)
637 		EC_KEY_free(ecpub);
638 	else
639 		RSA_free(rsapub);
640 
641 bail1:
642 	EVP_PKEY_free(pkey);
643 bail:
644 	/* jwk destroy will clean any partial state */
645 	if (ret)
646 		lws_jwk_destroy(jwk);
647 
648 	return ret;
649 }
650 
651 static int
lws_x509_jwk_privkey_pem_pp_cb(char * buf,int size,int rwflag,void * u)652 lws_x509_jwk_privkey_pem_pp_cb(char *buf, int size, int rwflag, void *u)
653 {
654 	const char *pp = (const char *)u;
655 	size_t n = strlen(pp);
656 
657 	if ((int)n > size - 1)
658 		return -1;
659 
660 	memcpy(buf, pp, n + 1);
661 
662 	return (int)n;
663 }
664 
665 int
lws_x509_jwk_privkey_pem(struct lws_context * cx,struct lws_jwk * jwk,void * pem,size_t len,const char * passphrase)666 lws_x509_jwk_privkey_pem(struct lws_context *cx, struct lws_jwk *jwk,
667 			 void *pem, size_t len, const char *passphrase)
668 {
669 	BIO* bio = BIO_new(BIO_s_mem());
670 	BIGNUM *mpi, *dummy[6];
671 	EVP_PKEY *pkey = NULL;
672 	EC_KEY *ecpriv = NULL;
673 	RSA *rsapriv = NULL;
674 	const BIGNUM *cmpi;
675 	int n, m, ret = -1;
676 
677 	BIO_write(bio, pem, (int)len);
678 	PEM_read_bio_PrivateKey(bio, &pkey, lws_x509_jwk_privkey_pem_pp_cb,
679 				(void *)passphrase);
680 	BIO_free(bio);
681 	lws_explicit_bzero((void *)pem, len);
682 	if (!pkey) {
683 		lwsl_err("%s: unable to parse PEM privkey\n", __func__);
684 		lws_tls_err_describe_clear();
685 
686 		return -1;
687 	}
688 
689 	/* confirm the key type matches the existing jwk situation */
690 
691 	switch (jwk->kty) {
692 	case LWS_GENCRYPTO_KTY_EC:
693 		if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) {
694 			lwsl_err("%s: jwk is EC but privkey isn't\n", __func__);
695 
696 			goto bail;
697 		}
698 		ecpriv = EVP_PKEY_get1_EC_KEY(pkey);
699 		if (!ecpriv) {
700 			lwsl_notice("%s: missing EC key\n", __func__);
701 
702 			goto bail;
703 		}
704 
705 		cmpi = EC_KEY_get0_private_key(ecpriv);
706 
707 		/* quick size check first */
708 
709 		n = BN_num_bytes(cmpi);
710 		if (jwk->e[LWS_GENCRYPTO_EC_KEYEL_Y].len != (uint32_t)n) {
711 			lwsl_err("%s: jwk key size doesn't match\n", __func__);
712 
713 			goto bail1;
714 		}
715 
716 		/* TODO.. check public curve / group + point */
717 
718 		jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len = (unsigned int)n;
719 		jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf = lws_malloc((unsigned int)n, "ec");
720 		if (!jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf)
721 			goto bail1;
722 
723 		m = BN_bn2binpad(cmpi, jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf,
724 				      (int32_t)jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len);
725 		if ((unsigned int)m != (unsigned int)BN_num_bytes(cmpi))
726 			goto bail1;
727 
728 		break;
729 
730 	case LWS_GENCRYPTO_KTY_RSA:
731 		if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_RSA) {
732 			lwsl_err("%s: RSA jwk, non-RSA privkey\n", __func__);
733 
734 			goto bail;
735 		}
736 		rsapriv = EVP_PKEY_get1_RSA(pkey);
737 		if (!rsapriv) {
738 			lwsl_notice("%s: missing RSA key\n", __func__);
739 
740 			goto bail;
741 		}
742 
743 #if defined(LWS_HAVE_RSA_SET0_KEY) && !defined(USE_WOLFSSL)
744 		RSA_get0_key(rsapriv, (const BIGNUM **)&dummy[0], /* n */
745 				      (const BIGNUM **)&dummy[1], /* e */
746 				      (const BIGNUM **)&mpi);	  /* d */
747 		RSA_get0_factors(rsapriv, (const BIGNUM **)&dummy[4],  /* p */
748 					  (const BIGNUM **)&dummy[5]); /* q */
749 #else
750 		dummy[0] = rsapriv->n;
751 		dummy[1] = rsapriv->e;
752 		dummy[4] = rsapriv->p;
753 		dummy[5] = rsapriv->q;
754 		mpi = rsapriv->d;
755 #endif
756 
757 		/* quick size check first */
758 
759 		n = BN_num_bytes(mpi);
760 		if (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len != (uint32_t)n) {
761 			lwsl_err("%s: jwk key size doesn't match\n", __func__);
762 
763 			goto bail1;
764 		}
765 
766 		/* then check that n & e match what we got from the cert */
767 
768 		dummy[2] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].buf,
769 				     (int32_t)jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len,
770 				     NULL);
771 		dummy[3] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].buf,
772 				     (int32_t)jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].len,
773 				     NULL);
774 
775 		m = BN_cmp(dummy[2], dummy[0]) | BN_cmp(dummy[3], dummy[1]);
776 		BN_clear_free(dummy[2]);
777 		BN_clear_free(dummy[3]);
778 		if (m) {
779 			lwsl_err("%s: privkey doesn't match jwk pubkey\n",
780 				 __func__);
781 
782 			goto bail1;
783 		}
784 
785 		/* accept d from the PEM privkey into the JWK */
786 
787 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].len = (unsigned int)n;
788 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf = lws_malloc((unsigned int)n, "privjk");
789 		if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf)
790 			goto bail1;
791 
792 		BN_bn2bin(mpi, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
793 
794 		/* accept p and q from the PEM privkey into the JWK */
795 
796 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].len = (unsigned int)BN_num_bytes(dummy[4]);
797 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf = lws_malloc((unsigned int)n, "privjk");
798 		if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf) {
799 			lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
800 			goto bail1;
801 		}
802 		BN_bn2bin(dummy[4], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf);
803 
804 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].len = (unsigned int)BN_num_bytes(dummy[5]);
805 		jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf = lws_malloc((unsigned int)n, "privjk");
806 		if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf) {
807 			lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
808 			lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf);
809 			goto bail1;
810 		}
811 		BN_bn2bin(dummy[5], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf);
812 		break;
813 	default:
814 		lwsl_err("%s: JWK has unknown kty %d\n", __func__, jwk->kty);
815 		return -1;
816 	}
817 
818 	ret = 0;
819 
820 bail1:
821 	if (jwk->kty == LWS_GENCRYPTO_KTY_EC)
822 		EC_KEY_free(ecpriv);
823 	else
824 		RSA_free(rsapriv);
825 
826 bail:
827 	EVP_PKEY_free(pkey);
828 
829 	return ret;
830 }
831 #endif
832 
833 void
lws_x509_destroy(struct lws_x509_cert ** x509)834 lws_x509_destroy(struct lws_x509_cert **x509)
835 {
836 	if (!*x509)
837 		return;
838 
839 	if ((*x509)->cert) {
840 		X509_free((*x509)->cert);
841 		(*x509)->cert = NULL;
842 	}
843 
844 	lws_free_set_NULL(*x509);
845 }
846