xref: /aosp_15_r20/external/libwebsockets/lib/tls/mbedtls/mbedtls-x509.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
26*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-tls-mbedtls.h"
27*1c60b9acSAndroid Build Coastguard Worker #include <mbedtls/oid.h>
28*1c60b9acSAndroid Build Coastguard Worker 
29*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_OPTEE) || defined(OPTEE_DEV_KIT)
30*1c60b9acSAndroid Build Coastguard Worker struct tm {
31*1c60b9acSAndroid Build Coastguard Worker int    tm_sec; //   seconds [0,61]
32*1c60b9acSAndroid Build Coastguard Worker int    tm_min; //   minutes [0,59]
33*1c60b9acSAndroid Build Coastguard Worker int    tm_hour; //  hour [0,23]
34*1c60b9acSAndroid Build Coastguard Worker int    tm_mday; //  day of month [1,31]
35*1c60b9acSAndroid Build Coastguard Worker int    tm_mon; //   month of year [0,11]
36*1c60b9acSAndroid Build Coastguard Worker int    tm_year; //  years since 1900
37*1c60b9acSAndroid Build Coastguard Worker int    tm_wday; //  day of week [0,6] (Sunday = 0)
38*1c60b9acSAndroid Build Coastguard Worker int    tm_yday; //  day of year [0,365]
39*1c60b9acSAndroid Build Coastguard Worker int    tm_isdst; // daylight savings flag
40*1c60b9acSAndroid Build Coastguard Worker };
mktime(struct tm * t)41*1c60b9acSAndroid Build Coastguard Worker time_t mktime(struct tm *t)
42*1c60b9acSAndroid Build Coastguard Worker {
43*1c60b9acSAndroid Build Coastguard Worker 	return (time_t)0;
44*1c60b9acSAndroid Build Coastguard Worker }
45*1c60b9acSAndroid Build Coastguard Worker #endif
46*1c60b9acSAndroid Build Coastguard Worker 
47*1c60b9acSAndroid Build Coastguard Worker static time_t
lws_tls_mbedtls_time_to_unix(mbedtls_x509_time * xtime)48*1c60b9acSAndroid Build Coastguard Worker lws_tls_mbedtls_time_to_unix(mbedtls_x509_time *xtime)
49*1c60b9acSAndroid Build Coastguard Worker {
50*1c60b9acSAndroid Build Coastguard Worker 	struct tm t;
51*1c60b9acSAndroid Build Coastguard Worker 
52*1c60b9acSAndroid Build Coastguard Worker 	if (!xtime || !xtime->MBEDTLS_PRIVATE(year) || xtime->MBEDTLS_PRIVATE(year) < 0)
53*1c60b9acSAndroid Build Coastguard Worker 		return (time_t)(long long)-1;
54*1c60b9acSAndroid Build Coastguard Worker 
55*1c60b9acSAndroid Build Coastguard Worker 	memset(&t, 0, sizeof(t));
56*1c60b9acSAndroid Build Coastguard Worker 
57*1c60b9acSAndroid Build Coastguard Worker 	t.tm_year = xtime->MBEDTLS_PRIVATE(year) - 1900;
58*1c60b9acSAndroid Build Coastguard Worker 	t.tm_mon = xtime->MBEDTLS_PRIVATE(mon) - 1; /* mbedtls months are 1+, tm are 0+ */
59*1c60b9acSAndroid Build Coastguard Worker 	t.tm_mday = xtime->MBEDTLS_PRIVATE(day) - 1; /* mbedtls days are 1+, tm are 0+ */
60*1c60b9acSAndroid Build Coastguard Worker 	t.tm_hour = xtime->MBEDTLS_PRIVATE(hour);
61*1c60b9acSAndroid Build Coastguard Worker 	t.tm_min = xtime->MBEDTLS_PRIVATE(min);
62*1c60b9acSAndroid Build Coastguard Worker 	t.tm_sec = xtime->MBEDTLS_PRIVATE(sec);
63*1c60b9acSAndroid Build Coastguard Worker 	t.tm_isdst = -1;
64*1c60b9acSAndroid Build Coastguard Worker 
65*1c60b9acSAndroid Build Coastguard Worker 	return mktime(&t);
66*1c60b9acSAndroid Build Coastguard Worker }
67*1c60b9acSAndroid Build Coastguard Worker 
68*1c60b9acSAndroid Build Coastguard Worker static int
lws_tls_mbedtls_get_x509_name(mbedtls_x509_name * name,union lws_tls_cert_info_results * buf,size_t len)69*1c60b9acSAndroid Build Coastguard Worker lws_tls_mbedtls_get_x509_name(mbedtls_x509_name *name,
70*1c60b9acSAndroid Build Coastguard Worker 			      union lws_tls_cert_info_results *buf, size_t len)
71*1c60b9acSAndroid Build Coastguard Worker {
72*1c60b9acSAndroid Build Coastguard Worker 	int r = -1;
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker 	buf->ns.len = 0;
75*1c60b9acSAndroid Build Coastguard Worker 
76*1c60b9acSAndroid Build Coastguard Worker 	while (name) {
77*1c60b9acSAndroid Build Coastguard Worker 		/*
78*1c60b9acSAndroid Build Coastguard Worker 		if (MBEDTLS_OID_CMP(type, &name->oid)) {
79*1c60b9acSAndroid Build Coastguard Worker 			name = name->next;
80*1c60b9acSAndroid Build Coastguard Worker 			continue;
81*1c60b9acSAndroid Build Coastguard Worker 		}
82*1c60b9acSAndroid Build Coastguard Worker */
83*1c60b9acSAndroid Build Coastguard Worker 		lws_strnncpy(&buf->ns.name[buf->ns.len],
84*1c60b9acSAndroid Build Coastguard Worker 			     (const char *)name->MBEDTLS_PRIVATE(val).MBEDTLS_PRIVATE(p),
85*1c60b9acSAndroid Build Coastguard Worker 			     name->MBEDTLS_PRIVATE(val).MBEDTLS_PRIVATE(len),
86*1c60b9acSAndroid Build Coastguard Worker 			     len - (size_t)buf->ns.len);
87*1c60b9acSAndroid Build Coastguard Worker 		buf->ns.len = (int)strlen(buf->ns.name);
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker 		r = 0;
90*1c60b9acSAndroid Build Coastguard Worker 		name = name->MBEDTLS_PRIVATE(next);
91*1c60b9acSAndroid Build Coastguard Worker 	}
92*1c60b9acSAndroid Build Coastguard Worker 
93*1c60b9acSAndroid Build Coastguard Worker 	return r;
94*1c60b9acSAndroid Build Coastguard Worker }
95*1c60b9acSAndroid Build Coastguard Worker 
96*1c60b9acSAndroid Build Coastguard Worker 
97*1c60b9acSAndroid Build Coastguard Worker 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)98*1c60b9acSAndroid Build Coastguard Worker lws_tls_mbedtls_cert_info(mbedtls_x509_crt *x509, enum lws_tls_cert_info type,
99*1c60b9acSAndroid Build Coastguard Worker 			  union lws_tls_cert_info_results *buf, size_t len)
100*1c60b9acSAndroid Build Coastguard Worker {
101*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_x509_buf skid;
102*1c60b9acSAndroid Build Coastguard Worker 	lws_mbedtls_x509_authority akid;
103*1c60b9acSAndroid Build Coastguard Worker 
104*1c60b9acSAndroid Build Coastguard Worker 	if (!x509)
105*1c60b9acSAndroid Build Coastguard Worker 		return -1;
106*1c60b9acSAndroid Build Coastguard Worker 
107*1c60b9acSAndroid Build Coastguard Worker 	if (!len)
108*1c60b9acSAndroid Build Coastguard Worker 		len = sizeof(buf->ns.name);
109*1c60b9acSAndroid Build Coastguard Worker 
110*1c60b9acSAndroid Build Coastguard Worker 	switch (type) {
111*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_VALIDITY_FROM:
112*1c60b9acSAndroid Build Coastguard Worker 		buf->time = lws_tls_mbedtls_time_to_unix(&x509->MBEDTLS_PRIVATE(valid_from));
113*1c60b9acSAndroid Build Coastguard Worker 		if (buf->time == (time_t)(long long)-1)
114*1c60b9acSAndroid Build Coastguard Worker 			return -1;
115*1c60b9acSAndroid Build Coastguard Worker 		break;
116*1c60b9acSAndroid Build Coastguard Worker 
117*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_VALIDITY_TO:
118*1c60b9acSAndroid Build Coastguard Worker 		buf->time = lws_tls_mbedtls_time_to_unix(&x509->MBEDTLS_PRIVATE(valid_to));
119*1c60b9acSAndroid Build Coastguard Worker 		if (buf->time == (time_t)(long long)-1)
120*1c60b9acSAndroid Build Coastguard Worker 			return -1;
121*1c60b9acSAndroid Build Coastguard Worker 		break;
122*1c60b9acSAndroid Build Coastguard Worker 
123*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_COMMON_NAME:
124*1c60b9acSAndroid Build Coastguard Worker 		return lws_tls_mbedtls_get_x509_name(&x509->MBEDTLS_PRIVATE(subject), buf, len);
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_ISSUER_NAME:
127*1c60b9acSAndroid Build Coastguard Worker 		return lws_tls_mbedtls_get_x509_name(&x509->MBEDTLS_PRIVATE(issuer), buf, len);
128*1c60b9acSAndroid Build Coastguard Worker 
129*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_USAGE:
130*1c60b9acSAndroid Build Coastguard Worker 		buf->usage = x509->MBEDTLS_PRIVATE(key_usage);
131*1c60b9acSAndroid Build Coastguard Worker 		break;
132*1c60b9acSAndroid Build Coastguard Worker 
133*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY:
134*1c60b9acSAndroid Build Coastguard Worker 	{
135*1c60b9acSAndroid Build Coastguard Worker 		char *p = buf->ns.name;
136*1c60b9acSAndroid Build Coastguard Worker 		size_t r = len, u;
137*1c60b9acSAndroid Build Coastguard Worker 
138*1c60b9acSAndroid Build Coastguard Worker 		switch (mbedtls_pk_get_type(&x509->MBEDTLS_PRIVATE(pk))) {
139*1c60b9acSAndroid Build Coastguard Worker 		case MBEDTLS_PK_RSA:
140*1c60b9acSAndroid Build Coastguard Worker 		{
141*1c60b9acSAndroid Build Coastguard Worker 			mbedtls_rsa_context *rsa = mbedtls_pk_rsa(x509->MBEDTLS_PRIVATE(pk));
142*1c60b9acSAndroid Build Coastguard Worker 
143*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_mpi_write_string(&rsa->MBEDTLS_PRIVATE(N), 16, p, r, &u))
144*1c60b9acSAndroid Build Coastguard Worker 				return -1;
145*1c60b9acSAndroid Build Coastguard Worker 			r -= u;
146*1c60b9acSAndroid Build Coastguard Worker 			p += u;
147*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_mpi_write_string(&rsa->MBEDTLS_PRIVATE(E), 16, p, r, &u))
148*1c60b9acSAndroid Build Coastguard Worker 				return -1;
149*1c60b9acSAndroid Build Coastguard Worker 
150*1c60b9acSAndroid Build Coastguard Worker 			p += u;
151*1c60b9acSAndroid Build Coastguard Worker 			buf->ns.len = lws_ptr_diff(p, buf->ns.name);
152*1c60b9acSAndroid Build Coastguard Worker 			break;
153*1c60b9acSAndroid Build Coastguard Worker 		}
154*1c60b9acSAndroid Build Coastguard Worker 		case MBEDTLS_PK_ECKEY:
155*1c60b9acSAndroid Build Coastguard Worker 		{
156*1c60b9acSAndroid Build Coastguard Worker 			mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(x509->MBEDTLS_PRIVATE(pk));
157*1c60b9acSAndroid Build Coastguard Worker 
158*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_mpi_write_string(&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, p, r, &u))
159*1c60b9acSAndroid Build Coastguard Worker 				 return -1;
160*1c60b9acSAndroid Build Coastguard Worker 			r -= u;
161*1c60b9acSAndroid Build Coastguard Worker 			p += u;
162*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_mpi_write_string(&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, p, r, &u))
163*1c60b9acSAndroid Build Coastguard Worker 				 return -1;
164*1c60b9acSAndroid Build Coastguard Worker 			r -= u;
165*1c60b9acSAndroid Build Coastguard Worker 			p += u;
166*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_mpi_write_string(&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, p, r, &u))
167*1c60b9acSAndroid Build Coastguard Worker 				 return -1;
168*1c60b9acSAndroid Build Coastguard Worker 			p += u;
169*1c60b9acSAndroid Build Coastguard Worker 			buf->ns.len = lws_ptr_diff(p, buf->ns.name);
170*1c60b9acSAndroid Build Coastguard Worker 			break;
171*1c60b9acSAndroid Build Coastguard Worker 		}
172*1c60b9acSAndroid Build Coastguard Worker 		default:
173*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: x509 has unsupported pubkey type %d\n",
174*1c60b9acSAndroid Build Coastguard Worker 				    __func__,
175*1c60b9acSAndroid Build Coastguard Worker 				    mbedtls_pk_get_type(&x509->MBEDTLS_PRIVATE(pk)));
176*1c60b9acSAndroid Build Coastguard Worker 
177*1c60b9acSAndroid Build Coastguard Worker 			return -1;
178*1c60b9acSAndroid Build Coastguard Worker 		}
179*1c60b9acSAndroid Build Coastguard Worker 		break;
180*1c60b9acSAndroid Build Coastguard Worker 	}
181*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_DER_RAW:
182*1c60b9acSAndroid Build Coastguard Worker 
183*1c60b9acSAndroid Build Coastguard Worker 		buf->ns.len = (int)x509->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len);
184*1c60b9acSAndroid Build Coastguard Worker 
185*1c60b9acSAndroid Build Coastguard Worker 		if (len < x509->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))
186*1c60b9acSAndroid Build Coastguard Worker 			/*
187*1c60b9acSAndroid Build Coastguard Worker 			 * The buffer is too small and the attempt failed, but
188*1c60b9acSAndroid Build Coastguard Worker 			 * the required object length is in buf->ns.len
189*1c60b9acSAndroid Build Coastguard Worker 			 */
190*1c60b9acSAndroid Build Coastguard Worker 			return -1;
191*1c60b9acSAndroid Build Coastguard Worker 
192*1c60b9acSAndroid Build Coastguard Worker 		memcpy(buf->ns.name, x509->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
193*1c60b9acSAndroid Build Coastguard Worker 				x509->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len));
194*1c60b9acSAndroid Build Coastguard Worker 		break;
195*1c60b9acSAndroid Build Coastguard Worker 
196*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID:
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker 		memset(&akid, 0, sizeof(akid));
199*1c60b9acSAndroid Build Coastguard Worker 		memset(&skid, 0, sizeof(skid));
200*1c60b9acSAndroid Build Coastguard Worker 
201*1c60b9acSAndroid Build Coastguard Worker 		lws_x509_get_crt_ext(x509, &skid, &akid);
202*1c60b9acSAndroid Build Coastguard Worker 		if (akid.keyIdentifier.MBEDTLS_PRIVATE(tag) != MBEDTLS_ASN1_OCTET_STRING)
203*1c60b9acSAndroid Build Coastguard Worker 			return 1;
204*1c60b9acSAndroid Build Coastguard Worker 		buf->ns.len = (int)akid.keyIdentifier.MBEDTLS_PRIVATE(len);
205*1c60b9acSAndroid Build Coastguard Worker 		if (!akid.keyIdentifier.MBEDTLS_PRIVATE(p) ||
206*1c60b9acSAndroid Build Coastguard Worker 		    len < (size_t)buf->ns.len)
207*1c60b9acSAndroid Build Coastguard Worker 			return -1;
208*1c60b9acSAndroid Build Coastguard Worker 		memcpy(buf->ns.name, akid.keyIdentifier.MBEDTLS_PRIVATE(p), (size_t)buf->ns.len);
209*1c60b9acSAndroid Build Coastguard Worker 		break;
210*1c60b9acSAndroid Build Coastguard Worker 
211*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_ISSUER: {
212*1c60b9acSAndroid Build Coastguard Worker 		mbedtls_x509_sequence * ip;
213*1c60b9acSAndroid Build Coastguard Worker 
214*1c60b9acSAndroid Build Coastguard Worker 		memset(&akid, 0, sizeof(akid));
215*1c60b9acSAndroid Build Coastguard Worker 		memset(&skid, 0, sizeof(skid));
216*1c60b9acSAndroid Build Coastguard Worker 
217*1c60b9acSAndroid Build Coastguard Worker 		lws_x509_get_crt_ext(x509, &skid, &akid);
218*1c60b9acSAndroid Build Coastguard Worker 
219*1c60b9acSAndroid Build Coastguard Worker 		ip = &akid.authorityCertIssuer;
220*1c60b9acSAndroid Build Coastguard Worker 
221*1c60b9acSAndroid Build Coastguard Worker 		buf->ns.len = 0;
222*1c60b9acSAndroid Build Coastguard Worker 
223*1c60b9acSAndroid Build Coastguard Worker 		while (ip) {
224*1c60b9acSAndroid Build Coastguard Worker 			if (akid.keyIdentifier.MBEDTLS_PRIVATE(tag) != MBEDTLS_ASN1_OCTET_STRING ||
225*1c60b9acSAndroid Build Coastguard Worker 			    !ip->MBEDTLS_PRIVATE(buf).MBEDTLS_PRIVATE(p) ||
226*1c60b9acSAndroid Build Coastguard Worker 			    ip->MBEDTLS_PRIVATE(buf).MBEDTLS_PRIVATE(len) < 9 ||
227*1c60b9acSAndroid Build Coastguard Worker 			    len < (size_t)ip->MBEDTLS_PRIVATE(buf).MBEDTLS_PRIVATE(len) - 9u)
228*1c60b9acSAndroid Build Coastguard Worker 			break;
229*1c60b9acSAndroid Build Coastguard Worker 
230*1c60b9acSAndroid Build Coastguard Worker 			memcpy(buf->ns.name + buf->ns.len, ip->MBEDTLS_PRIVATE(buf).MBEDTLS_PRIVATE(p),
231*1c60b9acSAndroid Build Coastguard Worker 					(size_t)ip->MBEDTLS_PRIVATE(buf).MBEDTLS_PRIVATE(len) - 9);
232*1c60b9acSAndroid Build Coastguard Worker 			buf->ns.len = buf->ns.len + (int)ip->MBEDTLS_PRIVATE(buf).MBEDTLS_PRIVATE(len) - 9;
233*1c60b9acSAndroid Build Coastguard Worker 
234*1c60b9acSAndroid Build Coastguard Worker 			ip = ip->MBEDTLS_PRIVATE(next);
235*1c60b9acSAndroid Build Coastguard Worker 		}
236*1c60b9acSAndroid Build Coastguard Worker 		break;
237*1c60b9acSAndroid Build Coastguard Worker 	}
238*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_SERIAL:
239*1c60b9acSAndroid Build Coastguard Worker 
240*1c60b9acSAndroid Build Coastguard Worker 		memset(&akid, 0, sizeof(akid));
241*1c60b9acSAndroid Build Coastguard Worker 		memset(&skid, 0, sizeof(skid));
242*1c60b9acSAndroid Build Coastguard Worker 
243*1c60b9acSAndroid Build Coastguard Worker 		lws_x509_get_crt_ext(x509, &skid, &akid);
244*1c60b9acSAndroid Build Coastguard Worker 
245*1c60b9acSAndroid Build Coastguard Worker 		if (akid.authorityCertSerialNumber.MBEDTLS_PRIVATE(tag) != MBEDTLS_ASN1_OCTET_STRING)
246*1c60b9acSAndroid Build Coastguard Worker 			return 1;
247*1c60b9acSAndroid Build Coastguard Worker 		buf->ns.len = (int)akid.authorityCertSerialNumber.MBEDTLS_PRIVATE(len);
248*1c60b9acSAndroid Build Coastguard Worker 		if (!akid.authorityCertSerialNumber.MBEDTLS_PRIVATE(p) ||
249*1c60b9acSAndroid Build Coastguard Worker 		    len < (size_t)buf->ns.len)
250*1c60b9acSAndroid Build Coastguard Worker 			return -1;
251*1c60b9acSAndroid Build Coastguard Worker 		memcpy(buf->ns.name, akid.authorityCertSerialNumber.
252*1c60b9acSAndroid Build Coastguard Worker 					MBEDTLS_PRIVATE(p), (size_t)buf->ns.len);
253*1c60b9acSAndroid Build Coastguard Worker 		break;
254*1c60b9acSAndroid Build Coastguard Worker 
255*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_SUBJECT_KEY_ID:
256*1c60b9acSAndroid Build Coastguard Worker 
257*1c60b9acSAndroid Build Coastguard Worker 		memset(&akid, 0, sizeof(akid));
258*1c60b9acSAndroid Build Coastguard Worker 		memset(&skid, 0, sizeof(skid));
259*1c60b9acSAndroid Build Coastguard Worker 
260*1c60b9acSAndroid Build Coastguard Worker 		lws_x509_get_crt_ext(x509, &skid, &akid);
261*1c60b9acSAndroid Build Coastguard Worker 
262*1c60b9acSAndroid Build Coastguard Worker 		if (skid.MBEDTLS_PRIVATE(tag) != MBEDTLS_ASN1_OCTET_STRING)
263*1c60b9acSAndroid Build Coastguard Worker 			return 1;
264*1c60b9acSAndroid Build Coastguard Worker 		buf->ns.len = (int)skid.MBEDTLS_PRIVATE(len);
265*1c60b9acSAndroid Build Coastguard Worker 		if (len < (size_t)buf->ns.len)
266*1c60b9acSAndroid Build Coastguard Worker 			return -1;
267*1c60b9acSAndroid Build Coastguard Worker 		memcpy(buf->ns.name, skid.MBEDTLS_PRIVATE(p), (size_t)buf->ns.len);
268*1c60b9acSAndroid Build Coastguard Worker 		break;
269*1c60b9acSAndroid Build Coastguard Worker 	default:
270*1c60b9acSAndroid Build Coastguard Worker 		return -1;
271*1c60b9acSAndroid Build Coastguard Worker 	}
272*1c60b9acSAndroid Build Coastguard Worker 
273*1c60b9acSAndroid Build Coastguard Worker 	return 0;
274*1c60b9acSAndroid Build Coastguard Worker }
275*1c60b9acSAndroid Build Coastguard Worker 
276*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
277*1c60b9acSAndroid Build Coastguard Worker 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)278*1c60b9acSAndroid Build Coastguard Worker lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
279*1c60b9acSAndroid Build Coastguard Worker 		        union lws_tls_cert_info_results *buf, size_t len)
280*1c60b9acSAndroid Build Coastguard Worker {
281*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_x509_crt *x509;
282*1c60b9acSAndroid Build Coastguard Worker 
283*1c60b9acSAndroid Build Coastguard Worker 	x509 = ssl_ctx_get_mbedtls_x509_crt(vhost->tls.ssl_ctx);
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker 	return lws_tls_mbedtls_cert_info(x509, type, buf, len);
286*1c60b9acSAndroid Build Coastguard Worker }
287*1c60b9acSAndroid Build Coastguard Worker 
288*1c60b9acSAndroid Build Coastguard Worker 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)289*1c60b9acSAndroid Build Coastguard Worker lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
290*1c60b9acSAndroid Build Coastguard Worker 		       union lws_tls_cert_info_results *buf, size_t len)
291*1c60b9acSAndroid Build Coastguard Worker {
292*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_x509_crt *x509;
293*1c60b9acSAndroid Build Coastguard Worker 
294*1c60b9acSAndroid Build Coastguard Worker 	wsi = lws_get_network_wsi(wsi);
295*1c60b9acSAndroid Build Coastguard Worker 
296*1c60b9acSAndroid Build Coastguard Worker 	x509 = ssl_get_peer_mbedtls_x509_crt(wsi->tls.ssl);
297*1c60b9acSAndroid Build Coastguard Worker 
298*1c60b9acSAndroid Build Coastguard Worker 	if (!x509)
299*1c60b9acSAndroid Build Coastguard Worker 		return -1;
300*1c60b9acSAndroid Build Coastguard Worker 
301*1c60b9acSAndroid Build Coastguard Worker 	switch (type) {
302*1c60b9acSAndroid Build Coastguard Worker 	case LWS_TLS_CERT_INFO_VERIFIED:
303*1c60b9acSAndroid Build Coastguard Worker 		buf->verified = SSL_get_verify_result(wsi->tls.ssl) == X509_V_OK;
304*1c60b9acSAndroid Build Coastguard Worker 		return 0;
305*1c60b9acSAndroid Build Coastguard Worker 	default:
306*1c60b9acSAndroid Build Coastguard Worker 		return lws_tls_mbedtls_cert_info(x509, type, buf, len);
307*1c60b9acSAndroid Build Coastguard Worker 	}
308*1c60b9acSAndroid Build Coastguard Worker 
309*1c60b9acSAndroid Build Coastguard Worker 	return -1;
310*1c60b9acSAndroid Build Coastguard Worker }
311*1c60b9acSAndroid Build Coastguard Worker #endif
312*1c60b9acSAndroid Build Coastguard Worker 
313*1c60b9acSAndroid Build Coastguard Worker 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)314*1c60b9acSAndroid Build Coastguard Worker lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
315*1c60b9acSAndroid Build Coastguard Worker 	      union lws_tls_cert_info_results *buf, size_t len)
316*1c60b9acSAndroid Build Coastguard Worker {
317*1c60b9acSAndroid Build Coastguard Worker 	return lws_tls_mbedtls_cert_info(&x509->cert, type, buf, len);
318*1c60b9acSAndroid Build Coastguard Worker }
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker int
lws_x509_create(struct lws_x509_cert ** x509)321*1c60b9acSAndroid Build Coastguard Worker lws_x509_create(struct lws_x509_cert **x509)
322*1c60b9acSAndroid Build Coastguard Worker {
323*1c60b9acSAndroid Build Coastguard Worker 	*x509 = lws_malloc(sizeof(**x509), __func__);
324*1c60b9acSAndroid Build Coastguard Worker 
325*1c60b9acSAndroid Build Coastguard Worker 	return !(*x509);
326*1c60b9acSAndroid Build Coastguard Worker }
327*1c60b9acSAndroid Build Coastguard Worker 
328*1c60b9acSAndroid Build Coastguard Worker /*
329*1c60b9acSAndroid Build Coastguard Worker  * Parse one DER-encoded or one or more concatenated PEM-encoded certificates
330*1c60b9acSAndroid Build Coastguard Worker  * and add them to the chained list.
331*1c60b9acSAndroid Build Coastguard Worker  */
332*1c60b9acSAndroid Build Coastguard Worker 
333*1c60b9acSAndroid Build Coastguard Worker int
lws_x509_parse_from_pem(struct lws_x509_cert * x509,const void * pem,size_t len)334*1c60b9acSAndroid Build Coastguard Worker lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len)
335*1c60b9acSAndroid Build Coastguard Worker {
336*1c60b9acSAndroid Build Coastguard Worker 	int ret;
337*1c60b9acSAndroid Build Coastguard Worker 
338*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_x509_crt_init(&x509->cert);
339*1c60b9acSAndroid Build Coastguard Worker 
340*1c60b9acSAndroid Build Coastguard Worker 	ret = mbedtls_x509_crt_parse(&x509->cert, pem, len);
341*1c60b9acSAndroid Build Coastguard Worker 	if (ret) {
342*1c60b9acSAndroid Build Coastguard Worker 		if (ret > 0)
343*1c60b9acSAndroid Build Coastguard Worker 			mbedtls_x509_crt_free(&x509->cert);
344*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to parse PEM cert: -0x%x\n",
345*1c60b9acSAndroid Build Coastguard Worker 			 __func__, -ret);
346*1c60b9acSAndroid Build Coastguard Worker 
347*1c60b9acSAndroid Build Coastguard Worker 		return -1;
348*1c60b9acSAndroid Build Coastguard Worker 	}
349*1c60b9acSAndroid Build Coastguard Worker 
350*1c60b9acSAndroid Build Coastguard Worker 	return 0;
351*1c60b9acSAndroid Build Coastguard Worker }
352*1c60b9acSAndroid Build Coastguard Worker 
353*1c60b9acSAndroid Build Coastguard Worker int
lws_x509_verify(struct lws_x509_cert * x509,struct lws_x509_cert * trusted,const char * common_name)354*1c60b9acSAndroid Build Coastguard Worker lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted,
355*1c60b9acSAndroid Build Coastguard Worker 		const char *common_name)
356*1c60b9acSAndroid Build Coastguard Worker {
357*1c60b9acSAndroid Build Coastguard Worker 	uint32_t flags = 0;
358*1c60b9acSAndroid Build Coastguard Worker 	int ret;
359*1c60b9acSAndroid Build Coastguard Worker 
360*1c60b9acSAndroid Build Coastguard Worker 	ret = mbedtls_x509_crt_verify_with_profile(&x509->cert, &trusted->cert,
361*1c60b9acSAndroid Build Coastguard Worker 						   NULL,
362*1c60b9acSAndroid Build Coastguard Worker 						   &mbedtls_x509_crt_profile_next,
363*1c60b9acSAndroid Build Coastguard Worker 						   common_name, &flags, NULL,
364*1c60b9acSAndroid Build Coastguard Worker 						   NULL);
365*1c60b9acSAndroid Build Coastguard Worker 
366*1c60b9acSAndroid Build Coastguard Worker 	if (ret) {
367*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to parse PEM cert: -0x%x\n",
368*1c60b9acSAndroid Build Coastguard Worker 			 __func__, -ret);
369*1c60b9acSAndroid Build Coastguard Worker 
370*1c60b9acSAndroid Build Coastguard Worker 		return -1;
371*1c60b9acSAndroid Build Coastguard Worker 	}
372*1c60b9acSAndroid Build Coastguard Worker 
373*1c60b9acSAndroid Build Coastguard Worker 	return 0;
374*1c60b9acSAndroid Build Coastguard Worker }
375*1c60b9acSAndroid Build Coastguard Worker 
376*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_JOSE)
377*1c60b9acSAndroid Build Coastguard Worker 
378*1c60b9acSAndroid Build Coastguard Worker int
lws_x509_public_to_jwk(struct lws_jwk * jwk,struct lws_x509_cert * x509,const char * curves,int rsa_min_bits)379*1c60b9acSAndroid Build Coastguard Worker lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
380*1c60b9acSAndroid Build Coastguard Worker 		       const char *curves, int rsa_min_bits)
381*1c60b9acSAndroid Build Coastguard Worker {
382*1c60b9acSAndroid Build Coastguard Worker 	int kt = (int)mbedtls_pk_get_type(&x509->cert.MBEDTLS_PRIVATE(pk)),
383*1c60b9acSAndroid Build Coastguard Worker 			n, count = 0, ret = -1;
384*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_context *rsactx;
385*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair *ecpctx;
386*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
387*1c60b9acSAndroid Build Coastguard Worker 
388*1c60b9acSAndroid Build Coastguard Worker 	memset(jwk, 0, sizeof(*jwk));
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker 	switch (kt) {
391*1c60b9acSAndroid Build Coastguard Worker 	case MBEDTLS_PK_RSA:
392*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: RSA key\n", __func__);
393*1c60b9acSAndroid Build Coastguard Worker 		jwk->kty = LWS_GENCRYPTO_KTY_RSA;
394*1c60b9acSAndroid Build Coastguard Worker 		rsactx = mbedtls_pk_rsa(x509->cert.MBEDTLS_PRIVATE(pk));
395*1c60b9acSAndroid Build Coastguard Worker 
396*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = &rsactx->MBEDTLS_PRIVATE(E);
397*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = &rsactx->MBEDTLS_PRIVATE(N);
398*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = &rsactx->MBEDTLS_PRIVATE(D);
399*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_P] = &rsactx->MBEDTLS_PRIVATE(P);
400*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_Q] = &rsactx->MBEDTLS_PRIVATE(Q);
401*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_DP] = &rsactx->MBEDTLS_PRIVATE(DP);
402*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_DQ] = &rsactx->MBEDTLS_PRIVATE(DQ);
403*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_QI] = &rsactx->MBEDTLS_PRIVATE(QP);
404*1c60b9acSAndroid Build Coastguard Worker 
405*1c60b9acSAndroid Build Coastguard Worker 		count = LWS_GENCRYPTO_RSA_KEYEL_QI + 1;
406*1c60b9acSAndroid Build Coastguard Worker 		n = LWS_GENCRYPTO_RSA_KEYEL_E;
407*1c60b9acSAndroid Build Coastguard Worker 		break;
408*1c60b9acSAndroid Build Coastguard Worker 
409*1c60b9acSAndroid Build Coastguard Worker 	case MBEDTLS_PK_ECKEY:
410*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: EC key\n", __func__);
411*1c60b9acSAndroid Build Coastguard Worker 		jwk->kty = LWS_GENCRYPTO_KTY_EC;
412*1c60b9acSAndroid Build Coastguard Worker 		ecpctx = mbedtls_pk_ec(x509->cert.MBEDTLS_PRIVATE(pk));
413*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_EC_KEYEL_X] = &ecpctx->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X);
414*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = &ecpctx->MBEDTLS_PRIVATE(d);
415*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = &ecpctx->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y);
416*1c60b9acSAndroid Build Coastguard Worker 
417*1c60b9acSAndroid Build Coastguard Worker 		if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
418*1c60b9acSAndroid Build Coastguard Worker 				(int)ecpctx->MBEDTLS_PRIVATE(grp).id, jwk))
419*1c60b9acSAndroid Build Coastguard Worker 			/* already logged */
420*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
421*1c60b9acSAndroid Build Coastguard Worker 
422*1c60b9acSAndroid Build Coastguard Worker 		count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
423*1c60b9acSAndroid Build Coastguard Worker 		n = LWS_GENCRYPTO_EC_KEYEL_X;
424*1c60b9acSAndroid Build Coastguard Worker 		break;
425*1c60b9acSAndroid Build Coastguard Worker 	default:
426*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: key type %d not supported\n", __func__, kt);
427*1c60b9acSAndroid Build Coastguard Worker 
428*1c60b9acSAndroid Build Coastguard Worker 		return -1;
429*1c60b9acSAndroid Build Coastguard Worker 	}
430*1c60b9acSAndroid Build Coastguard Worker 
431*1c60b9acSAndroid Build Coastguard Worker 	for (; n < count; n++) {
432*1c60b9acSAndroid Build Coastguard Worker 		if (!mbedtls_mpi_size(mpi[n]))
433*1c60b9acSAndroid Build Coastguard Worker 			continue;
434*1c60b9acSAndroid Build Coastguard Worker 
435*1c60b9acSAndroid Build Coastguard Worker 		jwk->e[n].buf = lws_malloc(mbedtls_mpi_size(mpi[n]), "certjwk");
436*1c60b9acSAndroid Build Coastguard Worker 		if (!jwk->e[n].buf)
437*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
438*1c60b9acSAndroid Build Coastguard Worker 		jwk->e[n].len = (uint32_t)mbedtls_mpi_size(mpi[n]);
439*1c60b9acSAndroid Build Coastguard Worker 		mbedtls_mpi_write_binary(mpi[n], jwk->e[n].buf, jwk->e[n].len);
440*1c60b9acSAndroid Build Coastguard Worker 	}
441*1c60b9acSAndroid Build Coastguard Worker 
442*1c60b9acSAndroid Build Coastguard Worker 	ret = 0;
443*1c60b9acSAndroid Build Coastguard Worker 
444*1c60b9acSAndroid Build Coastguard Worker bail:
445*1c60b9acSAndroid Build Coastguard Worker 	/* jwk destroy will clean up partials */
446*1c60b9acSAndroid Build Coastguard Worker 	if (ret)
447*1c60b9acSAndroid Build Coastguard Worker 		lws_jwk_destroy(jwk);
448*1c60b9acSAndroid Build Coastguard Worker 
449*1c60b9acSAndroid Build Coastguard Worker 	return ret;
450*1c60b9acSAndroid Build Coastguard Worker }
451*1c60b9acSAndroid Build Coastguard Worker 
452*1c60b9acSAndroid Build Coastguard Worker int
lws_x509_jwk_privkey_pem(struct lws_context * cx,struct lws_jwk * jwk,void * pem,size_t len,const char * passphrase)453*1c60b9acSAndroid Build Coastguard Worker lws_x509_jwk_privkey_pem(struct lws_context *cx, struct lws_jwk *jwk,
454*1c60b9acSAndroid Build Coastguard Worker 			 void *pem, size_t len, const char *passphrase)
455*1c60b9acSAndroid Build Coastguard Worker {
456*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_context *rsactx;
457*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair *ecpctx;
458*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_pk_context pk;
459*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
460*1c60b9acSAndroid Build Coastguard Worker 	int n, ret = -1, count = 0;
461*1c60b9acSAndroid Build Coastguard Worker 
462*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_pk_init(&pk);
463*1c60b9acSAndroid Build Coastguard Worker 
464*1c60b9acSAndroid Build Coastguard Worker 	n = 0;
465*1c60b9acSAndroid Build Coastguard Worker 	if (passphrase)
466*1c60b9acSAndroid Build Coastguard Worker 		n = (int)strlen(passphrase);
467*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_pk_parse_key(&pk, pem, len, (uint8_t *)passphrase, (unsigned int)n
468*1c60b9acSAndroid Build Coastguard Worker #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
469*1c60b9acSAndroid Build Coastguard Worker 					, mbedtls_ctr_drbg_random, &cx->mcdc
470*1c60b9acSAndroid Build Coastguard Worker #endif
471*1c60b9acSAndroid Build Coastguard Worker 			);
472*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
473*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: parse PEM key failed: -0x%x\n", __func__, -n);
474*1c60b9acSAndroid Build Coastguard Worker 
475*1c60b9acSAndroid Build Coastguard Worker 		return -1;
476*1c60b9acSAndroid Build Coastguard Worker 	}
477*1c60b9acSAndroid Build Coastguard Worker 
478*1c60b9acSAndroid Build Coastguard Worker 	/* the incoming private key type */
479*1c60b9acSAndroid Build Coastguard Worker 	switch (mbedtls_pk_get_type(&pk)) {
480*1c60b9acSAndroid Build Coastguard Worker 	case MBEDTLS_PK_RSA:
481*1c60b9acSAndroid Build Coastguard Worker 		if (jwk->kty != LWS_GENCRYPTO_KTY_RSA) {
482*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: RSA privkey, non-RSA jwk\n", __func__);
483*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
484*1c60b9acSAndroid Build Coastguard Worker 		}
485*1c60b9acSAndroid Build Coastguard Worker 		rsactx = mbedtls_pk_rsa(pk);
486*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = &rsactx->MBEDTLS_PRIVATE(D);
487*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_P] = &rsactx->MBEDTLS_PRIVATE(P);
488*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_RSA_KEYEL_Q] = &rsactx->MBEDTLS_PRIVATE(Q);
489*1c60b9acSAndroid Build Coastguard Worker 		n = LWS_GENCRYPTO_RSA_KEYEL_D;
490*1c60b9acSAndroid Build Coastguard Worker 		count = LWS_GENCRYPTO_RSA_KEYEL_Q + 1;
491*1c60b9acSAndroid Build Coastguard Worker 		break;
492*1c60b9acSAndroid Build Coastguard Worker 	case MBEDTLS_PK_ECKEY:
493*1c60b9acSAndroid Build Coastguard Worker 		if (jwk->kty != LWS_GENCRYPTO_KTY_EC) {
494*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: EC privkey, non-EC jwk\n", __func__);
495*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
496*1c60b9acSAndroid Build Coastguard Worker 		}
497*1c60b9acSAndroid Build Coastguard Worker 		ecpctx = mbedtls_pk_ec(pk);
498*1c60b9acSAndroid Build Coastguard Worker 		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = &ecpctx->MBEDTLS_PRIVATE(d);
499*1c60b9acSAndroid Build Coastguard Worker 		n = LWS_GENCRYPTO_EC_KEYEL_D;
500*1c60b9acSAndroid Build Coastguard Worker 		count = n + 1;
501*1c60b9acSAndroid Build Coastguard Worker 		break;
502*1c60b9acSAndroid Build Coastguard Worker 	default:
503*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unusable key type %d\n", __func__,
504*1c60b9acSAndroid Build Coastguard Worker 				mbedtls_pk_get_type(&pk));
505*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
506*1c60b9acSAndroid Build Coastguard Worker 	}
507*1c60b9acSAndroid Build Coastguard Worker 
508*1c60b9acSAndroid Build Coastguard Worker 	for (; n < count; n++) {
509*1c60b9acSAndroid Build Coastguard Worker 		if (!mbedtls_mpi_size(mpi[n])) {
510*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: empty privkey\n", __func__);
511*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
512*1c60b9acSAndroid Build Coastguard Worker 		}
513*1c60b9acSAndroid Build Coastguard Worker 
514*1c60b9acSAndroid Build Coastguard Worker 		jwk->e[n].buf = lws_malloc(mbedtls_mpi_size(mpi[n]), "certjwk");
515*1c60b9acSAndroid Build Coastguard Worker 		if (!jwk->e[n].buf)
516*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
517*1c60b9acSAndroid Build Coastguard Worker 		jwk->e[n].len = (uint32_t)mbedtls_mpi_size(mpi[n]);
518*1c60b9acSAndroid Build Coastguard Worker 		mbedtls_mpi_write_binary(mpi[n], jwk->e[n].buf, jwk->e[n].len);
519*1c60b9acSAndroid Build Coastguard Worker 	}
520*1c60b9acSAndroid Build Coastguard Worker 
521*1c60b9acSAndroid Build Coastguard Worker 	ret = 0;
522*1c60b9acSAndroid Build Coastguard Worker 
523*1c60b9acSAndroid Build Coastguard Worker bail:
524*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_pk_free(&pk);
525*1c60b9acSAndroid Build Coastguard Worker 
526*1c60b9acSAndroid Build Coastguard Worker 	return ret;
527*1c60b9acSAndroid Build Coastguard Worker }
528*1c60b9acSAndroid Build Coastguard Worker #endif
529*1c60b9acSAndroid Build Coastguard Worker 
530*1c60b9acSAndroid Build Coastguard Worker void
lws_x509_destroy(struct lws_x509_cert ** x509)531*1c60b9acSAndroid Build Coastguard Worker lws_x509_destroy(struct lws_x509_cert **x509)
532*1c60b9acSAndroid Build Coastguard Worker {
533*1c60b9acSAndroid Build Coastguard Worker 	if (!*x509)
534*1c60b9acSAndroid Build Coastguard Worker 		return;
535*1c60b9acSAndroid Build Coastguard Worker 
536*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_x509_crt_free(&(*x509)->cert);
537*1c60b9acSAndroid Build Coastguard Worker 
538*1c60b9acSAndroid Build Coastguard Worker 	lws_free_set_NULL(*x509);
539*1c60b9acSAndroid Build Coastguard Worker }
540