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 <mbedtls/x509_csr.h>
27 #include <errno.h>
28 
29 int
lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)30 lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
31 {
32 	int verify_options = SSL_VERIFY_PEER;
33 
34 	/* as a server, are we requiring clients to identify themselves? */
35 	if (!lws_check_opt(vh->options,
36 			  LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT)) {
37 		lwsl_notice("no client cert required\n");
38 		return 0;
39 	}
40 
41 	if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
42 		verify_options = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
43 
44 	lwsl_notice("%s: vh %s requires client cert %d\n", __func__, vh->name,
45 		    verify_options);
46 
47 	SSL_CTX_set_verify(vh->tls.ssl_ctx, verify_options, NULL);
48 
49 	return 0;
50 }
51 
52 static int
lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx, const unsigned char *servername, size_t len)53 lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx,
54 		   const unsigned char *servername, size_t len)
55 {
56 	SSL *ssl = SSL_SSL_from_mbedtls_ssl_context(mbedtls_ctx);
57 	struct lws_context *context = (struct lws_context *)arg;
58 	struct lws_vhost *vhost, *vh;
59 
60 	lwsl_notice("%s: %s\n", __func__, servername);
61 
62 	/*
63 	 * We can only get ssl accepted connections by using a vhost's ssl_ctx
64 	 * find out which listening one took us and only match vhosts on the
65 	 * same port.
66 	 */
67 	vh = context->vhost_list;
68 	while (vh) {
69 		if (!vh->being_destroyed &&
70 		    vh->tls.ssl_ctx == SSL_get_SSL_CTX(ssl))
71 			break;
72 		vh = vh->vhost_next;
73 	}
74 
75 	if (!vh) {
76 		assert(vh); /* can't match the incoming vh? */
77 		return 0;
78 	}
79 
80 	vhost = lws_select_vhost(context, vh->listen_port,
81 				 (const char *)servername);
82 	if (!vhost) {
83 		lwsl_info("SNI: none: %s:%d\n", servername, vh->listen_port);
84 
85 		return 0;
86 	}
87 
88 	lwsl_info("SNI: Found: %s:%d at vhost '%s'\n", servername,
89 					vh->listen_port, vhost->name);
90 
91 	if (!vhost->tls.ssl_ctx) {
92 		lwsl_err("%s: vhost %s matches SNI but no valid cert\n",
93 				__func__, vh->name);
94 
95 		return 1;
96 	}
97 
98 	/* select the ssl ctx from the selected vhost for this conn */
99 	SSL_set_SSL_CTX(ssl, vhost->tls.ssl_ctx);
100 
101 	return 0;
102 }
103 
104 int
lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi, const char *cert, const char *private_key, const char *mem_cert, size_t mem_cert_len, const char *mem_privkey, size_t mem_privkey_len)105 lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
106 			  const char *cert, const char *private_key,
107 			  const char *mem_cert, size_t mem_cert_len,
108 			  const char *mem_privkey, size_t mem_privkey_len)
109 {
110 	lws_filepos_t flen;
111 	uint8_t *p = NULL;
112 	long err;
113 	int n;
114 
115 	if ((!cert || !private_key) && (!mem_cert || !mem_privkey)) {
116 		lwsl_notice("%s: no usable input\n", __func__);
117 		return 0;
118 	}
119 
120 	n = (int)lws_tls_generic_cert_checks(vhost, cert, private_key);
121 
122 	if (n == LWS_TLS_EXTANT_NO && (!mem_cert || !mem_privkey))
123 		return 0;
124 
125 	/*
126 	 * we can't read the root-privs files.  But if mem_cert is provided,
127 	 * we should use that.
128 	 */
129 	if (n == LWS_TLS_EXTANT_NO)
130 		n = LWS_TLS_EXTANT_ALTERNATIVE;
131 
132 	if (n == LWS_TLS_EXTANT_ALTERNATIVE && (!mem_cert || !mem_privkey))
133 		return 1; /* no alternative */
134 
135 	if (n == LWS_TLS_EXTANT_ALTERNATIVE) {
136 		/*
137 		 * Although we have prepared update certs, we no longer have
138 		 * the rights to read our own cert + key we saved.
139 		 *
140 		 * If we were passed copies in memory buffers, use those
141 		 * instead.
142 		 *
143 		 * The passed memory-buffer cert image is in DER, and the
144 		 * memory-buffer private key image is PEM.
145 		 */
146 		cert = NULL;
147 		private_key = NULL;
148 	}
149 	if (lws_tls_alloc_pem_to_der_file(vhost->context, cert, mem_cert,
150 					  mem_cert_len, &p, &flen)) {
151 		lwsl_err("couldn't find cert file %s\n", cert);
152 
153 		return 1;
154 	}
155 
156 	err = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, (int)flen, p);
157 	lws_free_set_NULL(p);
158 	if (!err) {
159 		lwsl_err("Problem loading cert\n");
160 		return 1;
161 	}
162 
163 	if (lws_tls_alloc_pem_to_der_file(vhost->context, private_key,
164 					  (char *)mem_privkey, mem_privkey_len,
165 					  &p, &flen)) {
166 		lwsl_err("couldn't find private key\n");
167 
168 		return 1;
169 	}
170 
171 	err = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx, p, (long)flen);
172 	lws_free_set_NULL(p);
173 	if (!err) {
174 		lwsl_err("Problem loading key\n");
175 
176 		return 1;
177 	}
178 
179 	vhost->tls.skipped_certs = 0;
180 
181 	return 0;
182 }
183 
184 int
lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info, struct lws_vhost *vhost, struct lws *wsi)185 lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
186 				  struct lws_vhost *vhost, struct lws *wsi)
187 {
188 	const SSL_METHOD *method = TLS_server_method();
189 	uint8_t *p;
190 	lws_filepos_t flen;
191 	int n;
192 
193 	vhost->tls.ssl_ctx = SSL_CTX_new(method, &vhost->context->mcdc);	/* create context */
194 	if (!vhost->tls.ssl_ctx) {
195 		lwsl_err("problem creating ssl context\n");
196 		return 1;
197 	}
198 
199 	if (!vhost->tls.use_ssl ||
200 	    (!info->ssl_cert_filepath && !info->server_ssl_cert_mem))
201 		return 0;
202 
203 	if (info->ssl_ca_filepath) {
204 		lwsl_notice("%s: vh %s: loading CA filepath %s\n", __func__,
205 			    vhost->name, info->ssl_ca_filepath);
206 		if (lws_tls_alloc_pem_to_der_file(vhost->context,
207 				info->ssl_ca_filepath, NULL, 0, &p, &flen)) {
208 			lwsl_err("couldn't find client CA file %s\n",
209 					info->ssl_ca_filepath);
210 
211 			return 1;
212 		}
213 
214 		if (SSL_CTX_add_client_CA_ASN1(vhost->tls.ssl_ctx, (int)flen, p) != 1) {
215 			lwsl_err("%s: SSL_CTX_add_client_CA_ASN1 unhappy\n",
216 				 __func__);
217 			free(p);
218 			return 1;
219 		}
220 		free(p);
221 	} else {
222 		if (info->server_ssl_ca_mem && info->server_ssl_ca_mem_len &&
223 		    SSL_CTX_add_client_CA_ASN1(vhost->tls.ssl_ctx,
224 					       (int)info->server_ssl_ca_mem_len,
225 					       info->server_ssl_ca_mem) != 1) {
226 			lwsl_err("%s: mem SSL_CTX_add_client_CA_ASN1 unhappy\n",
227 				 __func__);
228 			return 1;
229 		}
230 		lwsl_notice("%s: vh %s: mem CA OK\n", __func__, vhost->name);
231 	}
232 
233 	n = lws_tls_server_certs_load(vhost, wsi, info->ssl_cert_filepath,
234 				      info->ssl_private_key_filepath,
235 				      info->server_ssl_cert_mem,
236 				      info->server_ssl_cert_mem_len,
237 				      info->server_ssl_private_key_mem,
238 				      info->server_ssl_private_key_mem_len);
239 	if (n)
240 		return n;
241 
242 	return 0;
243 }
244 
245 int
lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)246 lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
247 {
248 	errno = 0;
249 	wsi->tls.ssl = SSL_new(wsi->a.vhost->tls.ssl_ctx);
250 	if (wsi->tls.ssl == NULL) {
251 		lwsl_err("SSL_new failed: errno %d\n", errno);
252 
253 		lws_tls_err_describe_clear();
254 		return 1;
255 	}
256 
257 	SSL_set_fd(wsi->tls.ssl, (int)accept_fd);
258 
259 	if (wsi->a.vhost->tls.ssl_info_event_mask)
260 		SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
261 
262 	SSL_set_sni_callback(wsi->tls.ssl, lws_mbedtls_sni_cb, wsi->a.context);
263 
264 	return 0;
265 }
266 
267 enum lws_ssl_capable_status
lws_tls_server_abort_connection(struct lws *wsi)268 lws_tls_server_abort_connection(struct lws *wsi)
269 {
270 	if (wsi->tls.use_ssl)
271 		__lws_tls_shutdown(wsi);
272 
273 	SSL_free(wsi->tls.ssl);
274 
275 	return 0;
276 }
277 
278 enum lws_ssl_capable_status
lws_tls_server_accept(struct lws *wsi)279 lws_tls_server_accept(struct lws *wsi)
280 {
281 	union lws_tls_cert_info_results ir;
282 	int m, n;
283 
284 	n = SSL_accept(wsi->tls.ssl);
285 
286 	wsi->skip_fallback = 1;
287 	if (n == 1) {
288 
289 		if (strstr(wsi->a.vhost->name, ".invalid")) {
290 			lwsl_notice("%s: vhost has .invalid, "
291 				    "rejecting accept\n", __func__);
292 
293 			return LWS_SSL_CAPABLE_ERROR;
294 		}
295 
296 		n = lws_tls_peer_cert_info(wsi, LWS_TLS_CERT_INFO_COMMON_NAME,
297 					   &ir, sizeof(ir.ns.name));
298 		if (!n)
299 			lwsl_notice("%s: client cert CN '%s'\n",
300 				    __func__, ir.ns.name);
301 		else
302 			lwsl_info("%s: couldn't get client cert CN\n",
303 				  __func__);
304 		return LWS_SSL_CAPABLE_DONE;
305 	}
306 
307 	m = SSL_get_error(wsi->tls.ssl, n);
308 	lwsl_debug("%s: %s: accept SSL_get_error %d errno %d\n", __func__,
309 		    lws_wsi_tag(wsi), m, errno);
310 
311 	// mbedtls wrapper only
312 	if (m == SSL_ERROR_SYSCALL && errno == 11)
313 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
314 
315 #if defined(__APPLE__)
316 	if (m == SSL_ERROR_SYSCALL && errno == 35)
317 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
318 #endif
319 
320 #if defined(WIN32)
321 	if (m == SSL_ERROR_SYSCALL && errno == 0)
322 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
323 #endif
324 
325 	if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL)
326 		return LWS_SSL_CAPABLE_ERROR;
327 
328 	if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
329 		if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
330 			lwsl_info("%s: WANT_READ change_pollfd failed\n",
331 				  __func__);
332 			return LWS_SSL_CAPABLE_ERROR;
333 		}
334 
335 		lwsl_info("SSL_ERROR_WANT_READ\n");
336 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
337 	}
338 	if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
339 		lwsl_debug("%s: WANT_WRITE\n", __func__);
340 
341 		if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
342 			lwsl_info("%s: WANT_WRITE change_pollfd failed\n",
343 				  __func__);
344 			return LWS_SSL_CAPABLE_ERROR;
345 		}
346 		return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
347 	}
348 
349 	return LWS_SSL_CAPABLE_ERROR;
350 }
351 
352 #if defined(LWS_WITH_ACME)
353 /*
354  * mbedtls doesn't support SAN for cert creation.  So we use a known-good
355  * tls-sni-01 cert from OpenSSL that worked on Let's Encrypt, and just replace
356  * the pubkey n part and the signature part.
357  *
358  * This will need redoing for tls-sni-02...
359  */
360 
361 static uint8_t ss_cert_leadin[] = {
362 	0x30, 0x82,
363 	  0x05, 0x56, /* total length: LEN1 (+2 / +3) (correct for 513 + 512)*/
364 
365 	0x30, 0x82, /* length: LEN2  (+6 / +7) (correct for 513) */
366 		0x03, 0x3e,
367 
368 	/* addition: v3 cert (+5 bytes)*/
369 	0xa0, 0x03,
370 		0x02, 0x01, 0x02,
371 
372 	0x02, 0x01, 0x01,
373 	0x30, 0x0d, 0x06, 0x09, 0x2a,
374 	0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3f,
375 	0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47,
376 	0x42, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b,
377 	0x73, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x31,
378 	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x74, 0x65,
379 	0x6d, 0x70, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x61,
380 	0x6c, 0x69, 0x64, 0x30, 0x1e, 0x17, 0x0d,
381 
382 	/* from 2017-10-29 ... */
383 	0x31, 0x37, 0x31, 0x30, 0x32, 0x39, 0x31, 0x31, 0x34, 0x39, 0x34, 0x35,
384 	0x5a, 0x17, 0x0d,
385 
386 	/* thru 2049-10-29 we immediately discard the private key, no worries */
387 	0x34, 0x39, 0x31, 0x30, 0x32, 0x39, 0x31, 0x32, 0x34, 0x39, 0x34, 0x35,
388 	0x5a,
389 
390 	0x30, 0x3f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
391 	0x02, 0x47, 0x42, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
392 	0x0c, 0x0b, 0x73, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
393 	0x79, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11,
394 	0x74, 0x65, 0x6d, 0x70, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, 0x6e,
395 	0x76, 0x61, 0x6c, 0x69, 0x64, 0x30,
396 
397 	0x82,
398 		0x02, 0x22, /* LEN3 (+C3 / C4) */
399 	0x30, 0x0d, 0x06,
400 	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
401 	0x03,
402 
403 	0x82,
404 		0x02, 0x0f, /* LEN4 (+D6 / D7) */
405 
406 	0x00, 0x30, 0x82,
407 
408 		0x02, 0x0a, /* LEN5 (+ DB / DC) */
409 
410 	0x02, 0x82,
411 
412 	//0x02, 0x01, /* length of n in bytes (including leading 00 if any) */
413 	},
414 
415 	/* 1 + (keybits / 8) bytes N */
416 
417 	ss_cert_san_leadin[] = {
418 		/* e - fixed */
419 		0x02, 0x03, 0x01, 0x00, 0x01,
420 
421 		0xa3, 0x5d, 0x30, 0x5b, 0x30, 0x59, 0x06, 0x03, 0x55, 0x1d,
422 		0x11, 0x04, 0x52, 0x30, 0x50, /* <-- SAN length + 2 */
423 
424 		0x82, 0x4e, /* <-- SAN length */
425 	},
426 
427 	/* 78 bytes of SAN (tls-sni-01)
428 	0x61, 0x64, 0x34, 0x31, 0x61, 0x66, 0x62, 0x65, 0x30, 0x63, 0x61, 0x34,
429 	0x36, 0x34, 0x32, 0x66, 0x30, 0x61, 0x34, 0x34, 0x39, 0x64, 0x39, 0x63,
430 	0x61, 0x37, 0x36, 0x65, 0x62, 0x61, 0x61, 0x62, 0x2e, 0x32, 0x38, 0x39,
431 	0x34, 0x64, 0x34, 0x31, 0x36, 0x63, 0x39, 0x38, 0x33, 0x66, 0x31, 0x32,
432 	0x65, 0x64, 0x37, 0x33, 0x31, 0x61, 0x33, 0x30, 0x66, 0x35, 0x63, 0x34,
433 	0x34, 0x37, 0x37, 0x66, 0x65, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69,
434 	0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, */
435 
436 	/* end of LEN2 area */
437 
438 	ss_cert_sig_leadin[] = {
439 		/* it's saying that the signature is SHA256 + RSA */
440 		0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
441 		0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
442 
443 		0x82,
444 			0x02, 0x01,
445 		0x00,
446 	};
447 
448 	/* (keybits / 8) bytes signature to end of LEN1 area */
449 
450 #define SAN_A_LENGTH 78
451 
452 int
lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a, const char *san_b)453 lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
454 			     const char *san_b)
455 {
456 	int buflen = 0x560;
457 	uint8_t *buf = lws_malloc((unsigned int)buflen, "tmp cert buf"), *p = buf, *pkey_asn1;
458 	struct lws_genrsa_ctx ctx;
459 	struct lws_gencrypto_keyelem el[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
460 	uint8_t digest[32];
461 	struct lws_genhash_ctx hash_ctx;
462 	int pkey_asn1_len = 3 * 1024;
463 	int n, m, keybits = lws_plat_recommended_rsa_bits(), adj;
464 
465 	if (!buf)
466 		return 1;
467 
468 	n = lws_genrsa_new_keypair(vhost->context, &ctx, LGRSAM_PKCS1_1_5,
469 				   &el[0], keybits);
470 	if (n < 0) {
471 		lws_genrsa_destroy_elements(&el[0]);
472 		goto bail1;
473 	}
474 
475 	n = sizeof(ss_cert_leadin);
476 	memcpy(p, ss_cert_leadin, (unsigned int)n);
477 	p += n;
478 
479 	adj = (0x0556 - 0x401) + (keybits / 4) + 1;
480 	buf[2] = (uint8_t)(adj >> 8);
481 	buf[3] = (uint8_t)(adj & 0xff);
482 
483 	adj = (0x033e - 0x201) + (keybits / 8) + 1;
484 	buf[6] = (uint8_t)(adj >> 8);
485 	buf[7] = (uint8_t)(adj & 0xff);
486 
487 	adj = (0x0222 - 0x201) + (keybits / 8) + 1;
488 	buf[0xc3] = (uint8_t)(adj >> 8);
489 	buf[0xc4] = (uint8_t)(adj & 0xff);
490 
491 	adj = (0x020f - 0x201) + (keybits / 8) + 1;
492 	buf[0xd6] = (uint8_t)(adj >> 8);
493 	buf[0xd7] = (uint8_t)(adj & 0xff);
494 
495 	adj = (0x020a - 0x201) + (keybits / 8) + 1;
496 	buf[0xdb] = (uint8_t)(adj >> 8);
497 	buf[0xdc] = (uint8_t)(adj & 0xff);
498 
499 	*p++ = (uint8_t)(((keybits / 8) + 1) >> 8);
500 	*p++ = (uint8_t)(((keybits / 8) + 1) & 0xff);
501 
502 	/* we need to drop 1 + (keybits / 8) bytes of n in here, 00 + key */
503 
504 	*p++ = 0x00;
505 	memcpy(p, el[LWS_GENCRYPTO_RSA_KEYEL_N].buf, el[LWS_GENCRYPTO_RSA_KEYEL_N].len);
506 	p += el[LWS_GENCRYPTO_RSA_KEYEL_N].len;
507 
508 	memcpy(p, ss_cert_san_leadin, sizeof(ss_cert_san_leadin));
509 	p += sizeof(ss_cert_san_leadin);
510 
511 	/* drop in 78 bytes of san_a */
512 
513 	memcpy(p, san_a, SAN_A_LENGTH);
514 	p += SAN_A_LENGTH;
515 	memcpy(p, ss_cert_sig_leadin, sizeof(ss_cert_sig_leadin));
516 
517 	p[17] = (uint8_t)(((keybits / 8) + 1) >> 8);
518 	p[18] = (uint8_t)(((keybits / 8) + 1) & 0xff);
519 
520 	p += sizeof(ss_cert_sig_leadin);
521 
522 	/* hash the cert plaintext */
523 
524 	if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256))
525 		goto bail2;
526 
527 	if (lws_genhash_update(&hash_ctx, buf, lws_ptr_diff_size_t(p, buf))) {
528 		lws_genhash_destroy(&hash_ctx, NULL);
529 
530 		goto bail2;
531 	}
532 	if (lws_genhash_destroy(&hash_ctx, digest))
533 		goto bail2;
534 
535 	/* sign the hash */
536 
537 	n = lws_genrsa_hash_sign(&ctx, digest, LWS_GENHASH_TYPE_SHA256, p,
538 				 (size_t)((size_t)buflen - lws_ptr_diff_size_t(p, buf)));
539 	if (n < 0)
540 		goto bail2;
541 	p += n;
542 
543 	pkey_asn1 = lws_malloc((unsigned int)pkey_asn1_len, "mbed crt tmp");
544 	if (!pkey_asn1)
545 		goto bail2;
546 
547 	m = lws_genrsa_render_pkey_asn1(&ctx, 1, pkey_asn1, (size_t)pkey_asn1_len);
548 	if (m < 0) {
549 		lws_free(pkey_asn1);
550 		goto bail2;
551 	}
552 
553 //	lwsl_hexdump_level(LLL_DEBUG, buf, lws_ptr_diff(p, buf));
554 	n = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx,
555 				 lws_ptr_diff(p, buf), buf);
556 	if (n != 1) {
557 		lws_free(pkey_asn1);
558 		lwsl_err("%s: generated cert failed to load 0x%x\n",
559 				__func__, -n);
560 	} else {
561 		//lwsl_debug("private key\n");
562 		//lwsl_hexdump_level(LLL_DEBUG, pkey_asn1, n);
563 
564 		/* and to use our generated private key */
565 		n = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx,
566 						pkey_asn1, m);
567 		lws_free(pkey_asn1);
568 		if (n != 1) {
569 			lwsl_err("%s: SSL_CTX_use_PrivateKey_ASN1 failed\n",
570 				    __func__);
571 		}
572 	}
573 
574 	lws_genrsa_destroy(&ctx);
575 	lws_genrsa_destroy_elements(&el[0]);
576 
577 	lws_free(buf);
578 
579 	return n != 1;
580 
581 bail2:
582 	lws_genrsa_destroy(&ctx);
583 	lws_genrsa_destroy_elements(&el[0]);
584 bail1:
585 	lws_free(buf);
586 
587 	return -1;
588 }
589 
590 void
lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost)591 lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost)
592 {
593 }
594 
595 #if defined(LWS_WITH_JOSE)
596 static int
_rngf(void *context, unsigned char *buf, size_t len)597 _rngf(void *context, unsigned char *buf, size_t len)
598 {
599 	if ((size_t)lws_get_random(context, buf, len) == len)
600 		return 0;
601 
602 	return -1;
603 }
604 
605 static const char *x5[] = { "C", "ST", "L", "O", "CN" };
606 
607 /*
608  * CSR is output formatted as b64url(DER)
609  * Private key is output as a PEM in memory
610  */
611 int
lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[], uint8_t *dcsr, size_t csr_len, char **privkey_pem, size_t *privkey_len)612 lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[],
613 			    uint8_t *dcsr, size_t csr_len, char **privkey_pem,
614 			    size_t *privkey_len)
615 {
616 	mbedtls_x509write_csr csr;
617 	mbedtls_pk_context mpk;
618 	int buf_size = 4096, n;
619 	char subject[200], *p = subject, *end = p + sizeof(subject) - 1;
620 	uint8_t *buf = malloc((unsigned int)buf_size); /* malloc because given to user code */
621 
622 	if (!buf)
623 		return -1;
624 
625 	mbedtls_x509write_csr_init(&csr);
626 
627 	mbedtls_pk_init(&mpk);
628 	if (mbedtls_pk_setup(&mpk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))) {
629 		lwsl_notice("%s: pk_setup failed\n", __func__);
630 		goto fail;
631 	}
632 
633 	n = mbedtls_rsa_gen_key(mbedtls_pk_rsa(mpk), _rngf, context,
634 				(unsigned int)lws_plat_recommended_rsa_bits(), 65537);
635 	if (n) {
636 		lwsl_notice("%s: failed to generate keys\n", __func__);
637 
638 		goto fail1;
639 	}
640 
641 	/* subject must be formatted like "C=TW,O=warmcat,CN=myserver" */
642 
643 	for (n = 0; n < (int)LWS_ARRAY_SIZE(x5); n++) {
644 		if (p != subject)
645 			*p++ = ',';
646 		if (elements[n])
647 			p += lws_snprintf(p, lws_ptr_diff_size_t(end, p), "%s=%s", x5[n],
648 					  elements[n]);
649 	}
650 
651 	if (mbedtls_x509write_csr_set_subject_name(&csr, subject))
652 		goto fail1;
653 
654 	mbedtls_x509write_csr_set_key(&csr, &mpk);
655 	mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
656 
657 	/*
658 	 * data is written at the end of the buffer! Use the
659 	 * return value to determine where you should start
660 	 * using the buffer
661 	 */
662 	n = mbedtls_x509write_csr_der(&csr, buf, (size_t)buf_size, _rngf, context);
663 	if (n < 0) {
664 		lwsl_notice("%s: write csr der failed\n", __func__);
665 		goto fail1;
666 	}
667 
668 	/* we have it in DER, we need it in b64URL */
669 
670 	n = lws_jws_base64_enc((char *)(buf + buf_size) - n, (size_t)n,
671 			       (char *)dcsr, csr_len);
672 	if (n < 0)
673 		goto fail1;
674 
675 	/*
676 	 * okay, the CSR is done, last we need the private key in PEM
677 	 * re-use the DER CSR buf as the result buffer since we cn do it in
678 	 * one step
679 	 */
680 
681 	if (mbedtls_pk_write_key_pem(&mpk, buf, (size_t)buf_size)) {
682 		lwsl_notice("write key pem failed\n");
683 		goto fail1;
684 	}
685 
686 	*privkey_pem = (char *)buf;
687 	*privkey_len = strlen((const char *)buf);
688 
689 	mbedtls_pk_free(&mpk);
690 	mbedtls_x509write_csr_free(&csr);
691 
692 	return n;
693 
694 fail1:
695 	mbedtls_pk_free(&mpk);
696 fail:
697 	mbedtls_x509write_csr_free(&csr);
698 	free(buf);
699 
700 	return -1;
701 }
702 #endif
703 #endif
704