• 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 #include "private-lib-core.h"
26 #include "private-lib-tls-mbedtls.h"
27 #include <mbedtls/oid.h>
28 
29 #if defined(LWS_PLAT_OPTEE) || defined(OPTEE_DEV_KIT)
30 struct tm {
31 int    tm_sec; //   seconds [0,61]
32 int    tm_min; //   minutes [0,59]
33 int    tm_hour; //  hour [0,23]
34 int    tm_mday; //  day of month [1,31]
35 int    tm_mon; //   month of year [0,11]
36 int    tm_year; //  years since 1900
37 int    tm_wday; //  day of week [0,6] (Sunday = 0)
38 int    tm_yday; //  day of year [0,365]
39 int    tm_isdst; // daylight savings flag
40 };
mktime(struct tm * t)41 time_t mktime(struct tm *t)
42 {
43 	return (time_t)0;
44 }
45 #endif
46 
47 static time_t
lws_tls_mbedtls_time_to_unix(mbedtls_x509_time * xtime)48 lws_tls_mbedtls_time_to_unix(mbedtls_x509_time *xtime)
49 {
50 	struct tm t;
51 
52 	if (!xtime || !xtime->year || xtime->year < 0)
53 		return (time_t)(long long)-1;
54 
55 	memset(&t, 0, sizeof(t));
56 
57 	t.tm_year = xtime->year - 1900;
58 	t.tm_mon = xtime->mon - 1; /* mbedtls months are 1+, tm are 0+ */
59 	t.tm_mday = xtime->day - 1; /* mbedtls days are 1+, tm are 0+ */
60 	t.tm_hour = xtime->hour;
61 	t.tm_min = xtime->min;
62 	t.tm_sec = xtime->sec;
63 	t.tm_isdst = -1;
64 
65 	return mktime(&t);
66 }
67 
68 static int
lws_tls_mbedtls_get_x509_name(mbedtls_x509_name * name,union lws_tls_cert_info_results * buf,size_t len)69 lws_tls_mbedtls_get_x509_name(mbedtls_x509_name *name,
70 			      union lws_tls_cert_info_results *buf, size_t len)
71 {
72 	while (name) {
73 		if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid)) {
74 			name = name->next;
75 			continue;
76 		}
77 
78 		if (len - 1 < name->val.len)
79 			return -1;
80 
81 		memcpy(&buf->ns.name[0], name->val.p, name->val.len);
82 		buf->ns.name[name->val.len] = '\0';
83 		buf->ns.len = name->val.len;
84 
85 		return 0;
86 	}
87 
88 	return -1;
89 }
90 
91 static int
lws_tls_mbedtls_cert_info(mbedtls_x509_crt * x509,enum lws_tls_cert_info type,union lws_tls_cert_info_results * buf,size_t len)92 lws_tls_mbedtls_cert_info(mbedtls_x509_crt *x509, enum lws_tls_cert_info type,
93 			  union lws_tls_cert_info_results *buf, size_t len)
94 {
95 	if (!x509)
96 		return -1;
97 
98 	switch (type) {
99 	case LWS_TLS_CERT_INFO_VALIDITY_FROM:
100 		buf->time = lws_tls_mbedtls_time_to_unix(&x509->valid_from);
101 		if (buf->time == (time_t)(long long)-1)
102 			return -1;
103 		break;
104 
105 	case LWS_TLS_CERT_INFO_VALIDITY_TO:
106 		buf->time = lws_tls_mbedtls_time_to_unix(&x509->valid_to);
107 		if (buf->time == (time_t)(long long)-1)
108 			return -1;
109 		break;
110 
111 	case LWS_TLS_CERT_INFO_COMMON_NAME:
112 		return lws_tls_mbedtls_get_x509_name(&x509->subject, buf, len);
113 
114 	case LWS_TLS_CERT_INFO_ISSUER_NAME:
115 		return lws_tls_mbedtls_get_x509_name(&x509->issuer, buf, len);
116 
117 	case LWS_TLS_CERT_INFO_USAGE:
118 		buf->usage = x509->key_usage;
119 		break;
120 
121 	case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY:
122 	{
123 		char *p = buf->ns.name;
124 		size_t r = len, u;
125 
126 		switch (mbedtls_pk_get_type(&x509->pk)) {
127 		case MBEDTLS_PK_RSA:
128 		{
129 			mbedtls_rsa_context *rsa = mbedtls_pk_rsa(x509->pk);
130 
131 			if (mbedtls_mpi_write_string(&rsa->N, 16, p, r, &u))
132 				return -1;
133 			r -= u;
134 			p += u;
135 			if (mbedtls_mpi_write_string(&rsa->E, 16, p, r, &u))
136 				return -1;
137 
138 			p += u;
139 			buf->ns.len = lws_ptr_diff(p, buf->ns.name);
140 			break;
141 		}
142 		case MBEDTLS_PK_ECKEY:
143 		{
144 			mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(x509->pk);
145 
146 			if (mbedtls_mpi_write_string(&ecp->Q.X, 16, p, r, &u))
147 				 return -1;
148 			r -= u;
149 			p += u;
150 			if (mbedtls_mpi_write_string(&ecp->Q.Y, 16, p, r, &u))
151 				 return -1;
152 			r -= u;
153 			p += u;
154 			if (mbedtls_mpi_write_string(&ecp->Q.Z, 16, p, r, &u))
155 				 return -1;
156 			p += u;
157 			buf->ns.len = lws_ptr_diff(p, buf->ns.name);
158 			break;
159 		}
160 		default:
161 			lwsl_notice("%s: x509 has unsupported pubkey type %d\n",
162 				    __func__,
163 				    mbedtls_pk_get_type(&x509->pk));
164 
165 			return -1;
166 		}
167 		break;
168 	}
169 
170 	default:
171 		return -1;
172 	}
173 
174 	return 0;
175 }
176 
177 #if defined(LWS_WITH_NETWORK)
178 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)179 lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
180 		        union lws_tls_cert_info_results *buf, size_t len)
181 {
182 	mbedtls_x509_crt *x509;
183 
184 	x509 = ssl_ctx_get_mbedtls_x509_crt(vhost->tls.ssl_ctx);
185 
186 	return lws_tls_mbedtls_cert_info(x509, type, buf, len);
187 }
188 
189 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)190 lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
191 		       union lws_tls_cert_info_results *buf, size_t len)
192 {
193 	mbedtls_x509_crt *x509;
194 
195 	wsi = lws_get_network_wsi(wsi);
196 
197 	x509 = ssl_get_peer_mbedtls_x509_crt(wsi->tls.ssl);
198 
199 	if (!x509)
200 		return -1;
201 
202 	switch (type) {
203 	case LWS_TLS_CERT_INFO_VERIFIED:
204 		buf->verified = SSL_get_verify_result(wsi->tls.ssl) == X509_V_OK;
205 		return 0;
206 	default:
207 		return lws_tls_mbedtls_cert_info(x509, type, buf, len);
208 	}
209 
210 	return -1;
211 }
212 #endif
213 
214 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)215 lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
216 	      union lws_tls_cert_info_results *buf, size_t len)
217 {
218 	return lws_tls_mbedtls_cert_info(&x509->cert, type, buf, len);
219 }
220 
221 int
lws_x509_create(struct lws_x509_cert ** x509)222 lws_x509_create(struct lws_x509_cert **x509)
223 {
224 	*x509 = lws_malloc(sizeof(**x509), __func__);
225 
226 	return !(*x509);
227 }
228 
229 /*
230  * Parse one DER-encoded or one or more concatenated PEM-encoded certificates
231  * and add them to the chained list.
232  */
233 
234 int
lws_x509_parse_from_pem(struct lws_x509_cert * x509,const void * pem,size_t len)235 lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len)
236 {
237 	int ret;
238 
239 	mbedtls_x509_crt_init(&x509->cert);
240 
241 	ret = mbedtls_x509_crt_parse(&x509->cert, pem, len);
242 	if (ret) {
243 		if (ret > 0)
244 			mbedtls_x509_crt_free(&x509->cert);
245 		lwsl_err("%s: unable to parse PEM cert: -0x%x\n",
246 			 __func__, -ret);
247 
248 		return -1;
249 	}
250 
251 	return 0;
252 }
253 
254 int
lws_x509_verify(struct lws_x509_cert * x509,struct lws_x509_cert * trusted,const char * common_name)255 lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted,
256 		const char *common_name)
257 {
258 	uint32_t flags = 0;
259 	int ret;
260 
261 	ret = mbedtls_x509_crt_verify_with_profile(&x509->cert, &trusted->cert,
262 						   NULL,
263 						   &mbedtls_x509_crt_profile_next,
264 						   common_name, &flags, NULL,
265 						   NULL);
266 
267 	if (ret) {
268 		lwsl_err("%s: unable to parse PEM cert: -0x%x\n",
269 			 __func__, -ret);
270 
271 		return -1;
272 	}
273 
274 	return 0;
275 }
276 
277 #if defined(LWS_WITH_JOSE)
278 
279 int
lws_x509_public_to_jwk(struct lws_jwk * jwk,struct lws_x509_cert * x509,const char * curves,int rsa_min_bits)280 lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
281 		       const char *curves, int rsa_min_bits)
282 {
283 	int kt = mbedtls_pk_get_type(&x509->cert.pk), n, count = 0, ret = -1;
284 	mbedtls_rsa_context *rsactx;
285 	mbedtls_ecp_keypair *ecpctx;
286 	mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
287 
288 	memset(jwk, 0, sizeof(*jwk));
289 
290 	switch (kt) {
291 	case MBEDTLS_PK_RSA:
292 		lwsl_notice("%s: RSA key\n", __func__);
293 		jwk->kty = LWS_GENCRYPTO_KTY_RSA;
294 		rsactx = mbedtls_pk_rsa(x509->cert.pk);
295 
296 		mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = &rsactx->E;
297 		mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = &rsactx->N;
298 		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = &rsactx->D;
299 		mpi[LWS_GENCRYPTO_RSA_KEYEL_P] = &rsactx->P;
300 		mpi[LWS_GENCRYPTO_RSA_KEYEL_Q] = &rsactx->Q;
301 		mpi[LWS_GENCRYPTO_RSA_KEYEL_DP] = &rsactx->DP;
302 		mpi[LWS_GENCRYPTO_RSA_KEYEL_DQ] = &rsactx->DQ;
303 		mpi[LWS_GENCRYPTO_RSA_KEYEL_QI] = &rsactx->QP;
304 
305 		count = LWS_GENCRYPTO_RSA_KEYEL_COUNT;
306 		n = LWS_GENCRYPTO_RSA_KEYEL_E;
307 		break;
308 
309 	case MBEDTLS_PK_ECKEY:
310 		lwsl_notice("%s: EC key\n", __func__);
311 		jwk->kty = LWS_GENCRYPTO_KTY_EC;
312 		ecpctx = mbedtls_pk_ec(x509->cert.pk);
313 		mpi[LWS_GENCRYPTO_EC_KEYEL_X] = &ecpctx->Q.X;
314 		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = &ecpctx->d;
315 		mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = &ecpctx->Q.Y;
316 
317 		if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
318 				ecpctx->grp.id, jwk))
319 			/* already logged */
320 			goto bail;
321 
322 		count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
323 		n = LWS_GENCRYPTO_EC_KEYEL_X;
324 		break;
325 	default:
326 		lwsl_err("%s: key type %d not supported\n", __func__, kt);
327 
328 		return -1;
329 	}
330 
331 	for (; n < count; n++) {
332 		if (!mbedtls_mpi_size(mpi[n]))
333 			continue;
334 
335 		jwk->e[n].buf = lws_malloc(mbedtls_mpi_size(mpi[n]), "certjwk");
336 		if (!jwk->e[n].buf)
337 			goto bail;
338 		jwk->e[n].len = mbedtls_mpi_size(mpi[n]);
339 		mbedtls_mpi_write_binary(mpi[n], jwk->e[n].buf, jwk->e[n].len);
340 	}
341 
342 	ret = 0;
343 
344 bail:
345 	/* jwk destroy will clean up partials */
346 	if (ret)
347 		lws_jwk_destroy(jwk);
348 
349 	return ret;
350 }
351 
352 int
lws_x509_jwk_privkey_pem(struct lws_jwk * jwk,void * pem,size_t len,const char * passphrase)353 lws_x509_jwk_privkey_pem(struct lws_jwk *jwk, void *pem, size_t len,
354 			 const char *passphrase)
355 {
356 	mbedtls_rsa_context *rsactx;
357 	mbedtls_ecp_keypair *ecpctx;
358 	mbedtls_pk_context pk;
359 	mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
360 	int n, ret = -1, count = 0;
361 
362 	mbedtls_pk_init(&pk);
363 
364 	n = 0;
365 	if (passphrase)
366 		n = strlen(passphrase);
367 	n = mbedtls_pk_parse_key(&pk, pem, len, (uint8_t *)passphrase, n);
368 	if (n) {
369 		lwsl_err("%s: parse PEM key failed: -0x%x\n", __func__, -n);
370 
371 		return -1;
372 	}
373 
374 	/* the incoming private key type */
375 	switch (mbedtls_pk_get_type(&pk)) {
376 	case MBEDTLS_PK_RSA:
377 		if (jwk->kty != LWS_GENCRYPTO_KTY_RSA) {
378 			lwsl_err("%s: RSA privkey, non-RSA jwk\n", __func__);
379 			goto bail;
380 		}
381 		rsactx = mbedtls_pk_rsa(pk);
382 		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = &rsactx->D;
383 		mpi[LWS_GENCRYPTO_RSA_KEYEL_P] = &rsactx->P;
384 		mpi[LWS_GENCRYPTO_RSA_KEYEL_Q] = &rsactx->Q;
385 		n = LWS_GENCRYPTO_RSA_KEYEL_D;
386 		count = LWS_GENCRYPTO_RSA_KEYEL_Q + 1;
387 		break;
388 	case MBEDTLS_PK_ECKEY:
389 		if (jwk->kty != LWS_GENCRYPTO_KTY_EC) {
390 			lwsl_err("%s: EC privkey, non-EC jwk\n", __func__);
391 			goto bail;
392 		}
393 		ecpctx = mbedtls_pk_ec(pk);
394 		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = &ecpctx->d;
395 		n = LWS_GENCRYPTO_EC_KEYEL_D;
396 		count = n + 1;
397 		break;
398 	default:
399 		lwsl_err("%s: unusable key type %d\n", __func__,
400 				mbedtls_pk_get_type(&pk));
401 		goto bail;
402 	}
403 
404 	for (; n < count; n++) {
405 		if (!mbedtls_mpi_size(mpi[n])) {
406 			lwsl_err("%s: empty privkey\n", __func__);
407 			goto bail;
408 		}
409 
410 		jwk->e[n].buf = lws_malloc(mbedtls_mpi_size(mpi[n]), "certjwk");
411 		if (!jwk->e[n].buf)
412 			goto bail;
413 		jwk->e[n].len = mbedtls_mpi_size(mpi[n]);
414 		mbedtls_mpi_write_binary(mpi[n], jwk->e[n].buf, jwk->e[n].len);
415 	}
416 
417 	ret = 0;
418 
419 bail:
420 	mbedtls_pk_free(&pk);
421 
422 	return ret;
423 }
424 #endif
425 
426 void
lws_x509_destroy(struct lws_x509_cert ** x509)427 lws_x509_destroy(struct lws_x509_cert **x509)
428 {
429 	if (!*x509)
430 		return;
431 
432 	mbedtls_x509_crt_free(&(*x509)->cert);
433 
434 	lws_free_set_NULL(*x509);
435 }
436