• 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 <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 #if defined(LWS_AMAZON_RTOS)
268 enum lws_ssl_capable_status
269 #else
270 int
271 #endif
lws_tls_server_abort_connection(struct lws * wsi)272 lws_tls_server_abort_connection(struct lws *wsi)
273 {
274 	if (wsi->tls.use_ssl)
275 		__lws_tls_shutdown(wsi);
276 
277 	SSL_free(wsi->tls.ssl);
278 
279 	return 0;
280 }
281 
282 enum lws_ssl_capable_status
lws_tls_server_accept(struct lws * wsi)283 lws_tls_server_accept(struct lws *wsi)
284 {
285 	union lws_tls_cert_info_results ir;
286 	int m, n;
287 
288 	n = SSL_accept(wsi->tls.ssl);
289 
290 	wsi->skip_fallback = 1;
291 	if (n == 1) {
292 
293 		if (strstr(wsi->a.vhost->name, ".invalid")) {
294 			lwsl_notice("%s: vhost has .invalid, "
295 				    "rejecting accept\n", __func__);
296 
297 			return LWS_SSL_CAPABLE_ERROR;
298 		}
299 
300 		n = lws_tls_peer_cert_info(wsi, LWS_TLS_CERT_INFO_COMMON_NAME,
301 					   &ir, sizeof(ir.ns.name));
302 		if (!n)
303 			lwsl_notice("%s: client cert CN '%s'\n",
304 				    __func__, ir.ns.name);
305 		else
306 			lwsl_info("%s: couldn't get client cert CN\n",
307 				  __func__);
308 		return LWS_SSL_CAPABLE_DONE;
309 	}
310 
311 	m = SSL_get_error(wsi->tls.ssl, n);
312 	lwsl_debug("%s: %s: accept SSL_get_error %d errno %d\n", __func__,
313 		    lws_wsi_tag(wsi), m, errno);
314 
315 	// mbedtls wrapper only
316 	if (m == SSL_ERROR_SYSCALL && errno == 11)
317 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
318 
319 #if defined(__APPLE__)
320 	if (m == SSL_ERROR_SYSCALL && errno == 35)
321 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
322 #endif
323 
324 #if defined(WIN32)
325 	if (m == SSL_ERROR_SYSCALL && errno == 0)
326 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
327 #endif
328 
329 	if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL)
330 		return LWS_SSL_CAPABLE_ERROR;
331 
332 	if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
333 		if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
334 			lwsl_info("%s: WANT_READ change_pollfd failed\n",
335 				  __func__);
336 			return LWS_SSL_CAPABLE_ERROR;
337 		}
338 
339 		lwsl_info("SSL_ERROR_WANT_READ\n");
340 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
341 	}
342 	if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
343 		lwsl_debug("%s: WANT_WRITE\n", __func__);
344 
345 		if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
346 			lwsl_info("%s: WANT_WRITE change_pollfd failed\n",
347 				  __func__);
348 			return LWS_SSL_CAPABLE_ERROR;
349 		}
350 		return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
351 	}
352 
353 	return LWS_SSL_CAPABLE_ERROR;
354 }
355 
356 #if defined(LWS_WITH_ACME)
357 /*
358  * mbedtls doesn't support SAN for cert creation.  So we use a known-good
359  * tls-sni-01 cert from OpenSSL that worked on Let's Encrypt, and just replace
360  * the pubkey n part and the signature part.
361  *
362  * This will need redoing for tls-sni-02...
363  */
364 
365 static uint8_t ss_cert_leadin[] = {
366 	0x30, 0x82,
367 	  0x05, 0x56, /* total length: LEN1 (+2 / +3) (correct for 513 + 512)*/
368 
369 	0x30, 0x82, /* length: LEN2  (+6 / +7) (correct for 513) */
370 		0x03, 0x3e,
371 
372 	/* addition: v3 cert (+5 bytes)*/
373 	0xa0, 0x03,
374 		0x02, 0x01, 0x02,
375 
376 	0x02, 0x01, 0x01,
377 	0x30, 0x0d, 0x06, 0x09, 0x2a,
378 	0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3f,
379 	0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47,
380 	0x42, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b,
381 	0x73, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x31,
382 	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x74, 0x65,
383 	0x6d, 0x70, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x61,
384 	0x6c, 0x69, 0x64, 0x30, 0x1e, 0x17, 0x0d,
385 
386 	/* from 2017-10-29 ... */
387 	0x31, 0x37, 0x31, 0x30, 0x32, 0x39, 0x31, 0x31, 0x34, 0x39, 0x34, 0x35,
388 	0x5a, 0x17, 0x0d,
389 
390 	/* thru 2049-10-29 we immediately discard the private key, no worries */
391 	0x34, 0x39, 0x31, 0x30, 0x32, 0x39, 0x31, 0x32, 0x34, 0x39, 0x34, 0x35,
392 	0x5a,
393 
394 	0x30, 0x3f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
395 	0x02, 0x47, 0x42, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
396 	0x0c, 0x0b, 0x73, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
397 	0x79, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11,
398 	0x74, 0x65, 0x6d, 0x70, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, 0x6e,
399 	0x76, 0x61, 0x6c, 0x69, 0x64, 0x30,
400 
401 	0x82,
402 		0x02, 0x22, /* LEN3 (+C3 / C4) */
403 	0x30, 0x0d, 0x06,
404 	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
405 	0x03,
406 
407 	0x82,
408 		0x02, 0x0f, /* LEN4 (+D6 / D7) */
409 
410 	0x00, 0x30, 0x82,
411 
412 		0x02, 0x0a, /* LEN5 (+ DB / DC) */
413 
414 	0x02, 0x82,
415 
416 	//0x02, 0x01, /* length of n in bytes (including leading 00 if any) */
417 	},
418 
419 	/* 1 + (keybits / 8) bytes N */
420 
421 	ss_cert_san_leadin[] = {
422 		/* e - fixed */
423 		0x02, 0x03, 0x01, 0x00, 0x01,
424 
425 		0xa3, 0x5d, 0x30, 0x5b, 0x30, 0x59, 0x06, 0x03, 0x55, 0x1d,
426 		0x11, 0x04, 0x52, 0x30, 0x50, /* <-- SAN length + 2 */
427 
428 		0x82, 0x4e, /* <-- SAN length */
429 	},
430 
431 	/* 78 bytes of SAN (tls-sni-01)
432 	0x61, 0x64, 0x34, 0x31, 0x61, 0x66, 0x62, 0x65, 0x30, 0x63, 0x61, 0x34,
433 	0x36, 0x34, 0x32, 0x66, 0x30, 0x61, 0x34, 0x34, 0x39, 0x64, 0x39, 0x63,
434 	0x61, 0x37, 0x36, 0x65, 0x62, 0x61, 0x61, 0x62, 0x2e, 0x32, 0x38, 0x39,
435 	0x34, 0x64, 0x34, 0x31, 0x36, 0x63, 0x39, 0x38, 0x33, 0x66, 0x31, 0x32,
436 	0x65, 0x64, 0x37, 0x33, 0x31, 0x61, 0x33, 0x30, 0x66, 0x35, 0x63, 0x34,
437 	0x34, 0x37, 0x37, 0x66, 0x65, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69,
438 	0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, */
439 
440 	/* end of LEN2 area */
441 
442 	ss_cert_sig_leadin[] = {
443 		/* it's saying that the signature is SHA256 + RSA */
444 		0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
445 		0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
446 
447 		0x82,
448 			0x02, 0x01,
449 		0x00,
450 	};
451 
452 	/* (keybits / 8) bytes signature to end of LEN1 area */
453 
454 #define SAN_A_LENGTH 78
455 
456 int
lws_tls_acme_sni_cert_create(struct lws_vhost * vhost,const char * san_a,const char * san_b)457 lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
458 			     const char *san_b)
459 {
460 	int buflen = 0x560;
461 	uint8_t *buf = lws_malloc((unsigned int)buflen, "tmp cert buf"), *p = buf, *pkey_asn1;
462 	struct lws_genrsa_ctx ctx;
463 	struct lws_gencrypto_keyelem el[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
464 	uint8_t digest[32];
465 	struct lws_genhash_ctx hash_ctx;
466 	int pkey_asn1_len = 3 * 1024;
467 	int n, m, keybits = lws_plat_recommended_rsa_bits(), adj;
468 
469 	if (!buf)
470 		return 1;
471 
472 	n = lws_genrsa_new_keypair(vhost->context, &ctx, LGRSAM_PKCS1_1_5,
473 				   &el[0], keybits);
474 	if (n < 0) {
475 		lws_genrsa_destroy_elements(&el[0]);
476 		goto bail1;
477 	}
478 
479 	n = sizeof(ss_cert_leadin);
480 	memcpy(p, ss_cert_leadin, (unsigned int)n);
481 	p += n;
482 
483 	adj = (0x0556 - 0x401) + (keybits / 4) + 1;
484 	buf[2] = (uint8_t)(adj >> 8);
485 	buf[3] = (uint8_t)(adj & 0xff);
486 
487 	adj = (0x033e - 0x201) + (keybits / 8) + 1;
488 	buf[6] = (uint8_t)(adj >> 8);
489 	buf[7] = (uint8_t)(adj & 0xff);
490 
491 	adj = (0x0222 - 0x201) + (keybits / 8) + 1;
492 	buf[0xc3] = (uint8_t)(adj >> 8);
493 	buf[0xc4] = (uint8_t)(adj & 0xff);
494 
495 	adj = (0x020f - 0x201) + (keybits / 8) + 1;
496 	buf[0xd6] = (uint8_t)(adj >> 8);
497 	buf[0xd7] = (uint8_t)(adj & 0xff);
498 
499 	adj = (0x020a - 0x201) + (keybits / 8) + 1;
500 	buf[0xdb] = (uint8_t)(adj >> 8);
501 	buf[0xdc] = (uint8_t)(adj & 0xff);
502 
503 	*p++ = (uint8_t)(((keybits / 8) + 1) >> 8);
504 	*p++ = (uint8_t)(((keybits / 8) + 1) & 0xff);
505 
506 	/* we need to drop 1 + (keybits / 8) bytes of n in here, 00 + key */
507 
508 	*p++ = 0x00;
509 	memcpy(p, el[LWS_GENCRYPTO_RSA_KEYEL_N].buf, el[LWS_GENCRYPTO_RSA_KEYEL_N].len);
510 	p += el[LWS_GENCRYPTO_RSA_KEYEL_N].len;
511 
512 	memcpy(p, ss_cert_san_leadin, sizeof(ss_cert_san_leadin));
513 	p += sizeof(ss_cert_san_leadin);
514 
515 	/* drop in 78 bytes of san_a */
516 
517 	memcpy(p, san_a, SAN_A_LENGTH);
518 	p += SAN_A_LENGTH;
519 	memcpy(p, ss_cert_sig_leadin, sizeof(ss_cert_sig_leadin));
520 
521 	p[17] = (uint8_t)(((keybits / 8) + 1) >> 8);
522 	p[18] = (uint8_t)(((keybits / 8) + 1) & 0xff);
523 
524 	p += sizeof(ss_cert_sig_leadin);
525 
526 	/* hash the cert plaintext */
527 
528 	if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256))
529 		goto bail2;
530 
531 	if (lws_genhash_update(&hash_ctx, buf, lws_ptr_diff_size_t(p, buf))) {
532 		lws_genhash_destroy(&hash_ctx, NULL);
533 
534 		goto bail2;
535 	}
536 	if (lws_genhash_destroy(&hash_ctx, digest))
537 		goto bail2;
538 
539 	/* sign the hash */
540 
541 	n = lws_genrsa_hash_sign(&ctx, digest, LWS_GENHASH_TYPE_SHA256, p,
542 				 (size_t)((size_t)buflen - lws_ptr_diff_size_t(p, buf)));
543 	if (n < 0)
544 		goto bail2;
545 	p += n;
546 
547 	pkey_asn1 = lws_malloc((unsigned int)pkey_asn1_len, "mbed crt tmp");
548 	if (!pkey_asn1)
549 		goto bail2;
550 
551 	m = lws_genrsa_render_pkey_asn1(&ctx, 1, pkey_asn1, (size_t)pkey_asn1_len);
552 	if (m < 0) {
553 		lws_free(pkey_asn1);
554 		goto bail2;
555 	}
556 
557 //	lwsl_hexdump_level(LLL_DEBUG, buf, lws_ptr_diff(p, buf));
558 	n = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx,
559 				 lws_ptr_diff(p, buf), buf);
560 	if (n != 1) {
561 		lws_free(pkey_asn1);
562 		lwsl_err("%s: generated cert failed to load 0x%x\n",
563 				__func__, -n);
564 	} else {
565 		//lwsl_debug("private key\n");
566 		//lwsl_hexdump_level(LLL_DEBUG, pkey_asn1, n);
567 
568 		/* and to use our generated private key */
569 		n = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx,
570 						pkey_asn1, m);
571 		lws_free(pkey_asn1);
572 		if (n != 1) {
573 			lwsl_err("%s: SSL_CTX_use_PrivateKey_ASN1 failed\n",
574 				    __func__);
575 		}
576 	}
577 
578 	lws_genrsa_destroy(&ctx);
579 	lws_genrsa_destroy_elements(&el[0]);
580 
581 	lws_free(buf);
582 
583 	return n != 1;
584 
585 bail2:
586 	lws_genrsa_destroy(&ctx);
587 	lws_genrsa_destroy_elements(&el[0]);
588 bail1:
589 	lws_free(buf);
590 
591 	return -1;
592 }
593 
594 void
lws_tls_acme_sni_cert_destroy(struct lws_vhost * vhost)595 lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost)
596 {
597 }
598 
599 #if defined(LWS_WITH_JOSE)
600 static int
_rngf(void * context,unsigned char * buf,size_t len)601 _rngf(void *context, unsigned char *buf, size_t len)
602 {
603 	if ((size_t)lws_get_random(context, buf, len) == len)
604 		return 0;
605 
606 	return -1;
607 }
608 
609 static const char *x5[] = { "C", "ST", "L", "O", "CN" };
610 
611 /*
612  * CSR is output formatted as b64url(DER)
613  * Private key is output as a PEM in memory
614  */
615 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)616 lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[],
617 			    uint8_t *dcsr, size_t csr_len, char **privkey_pem,
618 			    size_t *privkey_len)
619 {
620 	mbedtls_x509write_csr csr;
621 	mbedtls_pk_context mpk;
622 	int buf_size = 4096, n;
623 	char subject[200], *p = subject, *end = p + sizeof(subject) - 1;
624 	uint8_t *buf = malloc((unsigned int)buf_size); /* malloc because given to user code */
625 
626 	if (!buf)
627 		return -1;
628 
629 	mbedtls_x509write_csr_init(&csr);
630 
631 	mbedtls_pk_init(&mpk);
632 	if (mbedtls_pk_setup(&mpk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))) {
633 		lwsl_notice("%s: pk_setup failed\n", __func__);
634 		goto fail;
635 	}
636 
637 	n = mbedtls_rsa_gen_key(mbedtls_pk_rsa(mpk), _rngf, context,
638 				(unsigned int)lws_plat_recommended_rsa_bits(), 65537);
639 	if (n) {
640 		lwsl_notice("%s: failed to generate keys\n", __func__);
641 
642 		goto fail1;
643 	}
644 
645 	/* subject must be formatted like "C=TW,O=warmcat,CN=myserver" */
646 
647 	for (n = 0; n < (int)LWS_ARRAY_SIZE(x5); n++) {
648 		if (p != subject)
649 			*p++ = ',';
650 		if (elements[n])
651 			p += lws_snprintf(p, lws_ptr_diff_size_t(end, p), "%s=%s", x5[n],
652 					  elements[n]);
653 	}
654 
655 	if (mbedtls_x509write_csr_set_subject_name(&csr, subject))
656 		goto fail1;
657 
658 	mbedtls_x509write_csr_set_key(&csr, &mpk);
659 	mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
660 
661 	/*
662 	 * data is written at the end of the buffer! Use the
663 	 * return value to determine where you should start
664 	 * using the buffer
665 	 */
666 	n = mbedtls_x509write_csr_der(&csr, buf, (size_t)buf_size, _rngf, context);
667 	if (n < 0) {
668 		lwsl_notice("%s: write csr der failed\n", __func__);
669 		goto fail1;
670 	}
671 
672 	/* we have it in DER, we need it in b64URL */
673 
674 	n = lws_jws_base64_enc((char *)(buf + buf_size) - n, (size_t)n,
675 			       (char *)dcsr, csr_len);
676 	if (n < 0)
677 		goto fail1;
678 
679 	/*
680 	 * okay, the CSR is done, last we need the private key in PEM
681 	 * re-use the DER CSR buf as the result buffer since we cn do it in
682 	 * one step
683 	 */
684 
685 	if (mbedtls_pk_write_key_pem(&mpk, buf, (size_t)buf_size)) {
686 		lwsl_notice("write key pem failed\n");
687 		goto fail1;
688 	}
689 
690 	*privkey_pem = (char *)buf;
691 	*privkey_len = strlen((const char *)buf);
692 
693 	mbedtls_pk_free(&mpk);
694 	mbedtls_x509write_csr_free(&csr);
695 
696 	return n;
697 
698 fail1:
699 	mbedtls_pk_free(&mpk);
700 fail:
701 	mbedtls_x509write_csr_free(&csr);
702 	free(buf);
703 
704 	return -1;
705 }
706 #endif
707 #endif
708