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
29int
30lws_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
52static int
53lws_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
104int
105lws_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
184int
185lws_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
245int
246lws_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
267enum lws_ssl_capable_status
268lws_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
278enum lws_ssl_capable_status
279lws_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
361static 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
452int
453lws_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
581bail2:
582	lws_genrsa_destroy(&ctx);
583	lws_genrsa_destroy_elements(&el[0]);
584bail1:
585	lws_free(buf);
586
587	return -1;
588}
589
590void
591lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost)
592{
593}
594
595#if defined(LWS_WITH_JOSE)
596static int
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
605static 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 */
611int
612lws_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
694fail1:
695	mbedtls_pk_free(&mpk);
696fail:
697	mbedtls_x509write_csr_free(&csr);
698	free(buf);
699
700	return -1;
701}
702#endif
703#endif
704