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
27 /*
28 * Care: many openssl apis return 1 for success. These are translated to the
29 * lws convention of 0 for success.
30 */
31
32 extern int openssl_websocket_private_data_index,
33 openssl_SSL_CTX_private_data_index;
34
35 int lws_openssl_describe_cipher(struct lws *wsi);
36
37 static int
OpenSSL_verify_callback(int preverify_ok,X509_STORE_CTX * x509_ctx)38 OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
39 {
40 SSL *ssl;
41 int n;
42 struct lws *wsi;
43 union lws_tls_cert_info_results ir;
44 X509 *topcert = X509_STORE_CTX_get_current_cert(x509_ctx);
45
46 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
47 SSL_get_ex_data_X509_STORE_CTX_idx());
48
49 /*
50 * !!! nasty openssl requires the index to come as a library-scope
51 * static
52 */
53 wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
54
55 n = lws_tls_openssl_cert_info(topcert, LWS_TLS_CERT_INFO_COMMON_NAME,
56 &ir, sizeof(ir.ns.name));
57 if (!n)
58 lwsl_info("%s: client cert CN '%s'\n", __func__, ir.ns.name);
59 else
60 lwsl_info("%s: couldn't get client cert CN\n", __func__);
61
62 n = wsi->vhost->protocols[0].callback(wsi,
63 LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
64 x509_ctx, ssl, preverify_ok);
65
66 /* convert return code from 0 = OK to 1 = OK */
67 return !n;
68 }
69
70 int
lws_tls_server_client_cert_verify_config(struct lws_vhost * vh)71 lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
72 {
73 int verify_options = SSL_VERIFY_PEER;
74
75 /* as a server, are we requiring clients to identify themselves? */
76
77 if (!lws_check_opt(vh->options,
78 LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT))
79 return 0;
80
81 if (!lws_check_opt(vh->options,
82 LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
83 verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
84
85 SSL_CTX_set_session_id_context(vh->tls.ssl_ctx, (uint8_t *)vh->context,
86 sizeof(void *));
87
88 /* absolutely require the client cert */
89 SSL_CTX_set_verify(vh->tls.ssl_ctx, verify_options,
90 OpenSSL_verify_callback);
91
92 return 0;
93 }
94
95 #if defined(SSL_TLSEXT_ERR_NOACK) && !defined(OPENSSL_NO_TLSEXT)
96 static int
lws_ssl_server_name_cb(SSL * ssl,int * ad,void * arg)97 lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
98 {
99 struct lws_context *context = (struct lws_context *)arg;
100 struct lws_vhost *vhost, *vh;
101 const char *servername;
102
103 if (!ssl)
104 return SSL_TLSEXT_ERR_NOACK;
105
106 /*
107 * We can only get ssl accepted connections by using a vhost's ssl_ctx
108 * find out which listening one took us and only match vhosts on the
109 * same port.
110 */
111 vh = context->vhost_list;
112 while (vh) {
113 if (!vh->being_destroyed &&
114 vh->tls.ssl_ctx == SSL_get_SSL_CTX(ssl))
115 break;
116 vh = vh->vhost_next;
117 }
118
119 if (!vh) {
120 assert(vh); /* can't match the incoming vh? */
121 return SSL_TLSEXT_ERR_OK;
122 }
123
124 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
125 if (!servername) {
126 /* the client doesn't know what hostname it wants */
127 lwsl_info("SNI: Unknown ServerName\n");
128
129 return SSL_TLSEXT_ERR_OK;
130 }
131
132 vhost = lws_select_vhost(context, vh->listen_port, servername);
133 if (!vhost) {
134 lwsl_info("SNI: none: %s:%d\n", servername, vh->listen_port);
135
136 return SSL_TLSEXT_ERR_OK;
137 }
138
139 lwsl_info("SNI: Found: %s:%d\n", servername, vh->listen_port);
140
141 /* select the ssl ctx from the selected vhost for this conn */
142 SSL_set_SSL_CTX(ssl, vhost->tls.ssl_ctx);
143
144 return SSL_TLSEXT_ERR_OK;
145 }
146 #endif
147
148 /*
149 * this may now get called after the vhost creation, when certs become
150 * available.
151 */
152 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)153 lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi,
154 const char *cert, const char *private_key,
155 const char *mem_cert, size_t mem_cert_len,
156 const char *mem_privkey, size_t mem_privkey_len)
157 {
158 #if !defined(OPENSSL_NO_EC)
159 const char *ecdh_curve = "prime256v1";
160 #if !defined(LWS_WITH_BORINGSSL) && defined(LWS_HAVE_SSL_EXTRA_CHAIN_CERTS)
161 STACK_OF(X509) *extra_certs = NULL;
162 #endif
163 EC_KEY *ecdh, *EC_key = NULL;
164 EVP_PKEY *pkey;
165 X509 *x = NULL;
166 int ecdh_nid;
167 int KeyType;
168 #endif
169 unsigned long error;
170 lws_filepos_t flen;
171 uint8_t *p;
172 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
173 int ret;
174 #endif
175 int n = lws_tls_generic_cert_checks(vhost, cert, private_key), m;
176
177 if (!cert && !private_key)
178 n = LWS_TLS_EXTANT_ALTERNATIVE;
179
180 if (n == LWS_TLS_EXTANT_NO && (!mem_cert || !mem_privkey))
181 return 0;
182 if (n == LWS_TLS_EXTANT_NO)
183 n = LWS_TLS_EXTANT_ALTERNATIVE;
184
185 if (n == LWS_TLS_EXTANT_ALTERNATIVE && (!mem_cert || !mem_privkey))
186 return 1; /* no alternative */
187
188 if (n == LWS_TLS_EXTANT_ALTERNATIVE) {
189
190 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
191
192 /*
193 * Although we have prepared update certs, we no longer have
194 * the rights to read our own cert + key we saved.
195 *
196 * If we were passed copies in memory buffers, use those
197 * in favour of the filepaths we normally want.
198 */
199 cert = NULL;
200 private_key = NULL;
201 }
202
203 /*
204 * use the multi-cert interface for backwards compatibility in the
205 * both simple files case
206 */
207
208 if (n != LWS_TLS_EXTANT_ALTERNATIVE && cert) {
209
210 /* set the local certificate from CertFile */
211 m = SSL_CTX_use_certificate_chain_file(vhost->tls.ssl_ctx, cert);
212 if (m != 1) {
213 error = ERR_get_error();
214 lwsl_err("problem getting cert '%s' %lu: %s\n",
215 cert, error, ERR_error_string(error,
216 (char *)vhost->context->pt[0].serv_buf));
217
218 return 1;
219 }
220
221 if (private_key) {
222 /* set the private key from KeyFile */
223 if (SSL_CTX_use_PrivateKey_file(vhost->tls.ssl_ctx, private_key,
224 SSL_FILETYPE_PEM) != 1) {
225 error = ERR_get_error();
226 lwsl_err("ssl problem getting key '%s' %lu: %s\n",
227 private_key, error,
228 ERR_error_string(error,
229 (char *)vhost->context->pt[0].serv_buf));
230 return 1;
231 }
232 } else {
233 if (vhost->protocols[0].callback(wsi,
234 LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
235 vhost->tls.ssl_ctx, NULL, 0)) {
236 lwsl_err("ssl private key not set\n");
237
238 return 1;
239 }
240 }
241
242 return 0;
243 }
244
245 /* otherwise allow for DER or PEM, file or memory image */
246
247 if (lws_tls_alloc_pem_to_der_file(vhost->context, cert, mem_cert,
248 mem_cert_len, &p, &flen)) {
249 lwsl_err("%s: couldn't read cert file\n", __func__);
250
251 return 1;
252 }
253
254 #if !defined(USE_WOLFSSL)
255 ret = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, (int)flen, p);
256 #else
257 ret = wolfSSL_CTX_use_certificate_buffer(vhost->tls.ssl_ctx,
258 (uint8_t *)p, (int)flen,
259 WOLFSSL_FILETYPE_ASN1);
260 #endif
261 lws_free_set_NULL(p);
262 if (ret != 1) {
263 lwsl_err("%s: Problem loading cert\n", __func__);
264
265 return 1;
266 }
267
268 if (lws_tls_alloc_pem_to_der_file(vhost->context, private_key,
269 mem_privkey, mem_privkey_len,
270 &p, &flen)) {
271 lwsl_notice("unable to convert memory privkey\n");
272
273 return 1;
274 }
275
276 #if !defined(USE_WOLFSSL)
277 ret = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vhost->tls.ssl_ctx, p,
278 (long)(long long)flen);
279 if (ret != 1) {
280 ret = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_EC,
281 vhost->tls.ssl_ctx, p,
282 (long)(long long)flen);
283 }
284 #else
285 ret = wolfSSL_CTX_use_PrivateKey_buffer(vhost->tls.ssl_ctx, p, flen,
286 WOLFSSL_FILETYPE_ASN1);
287 #endif
288 lws_free_set_NULL(p);
289 if (ret != 1) {
290 lwsl_notice("unable to use memory privkey\n");
291
292 return 1;
293 }
294
295 #else
296 /*
297 * Although we have prepared update certs, we no longer have
298 * the rights to read our own cert + key we saved.
299 *
300 * If we were passed copies in memory buffers, use those
301 * instead.
302 *
303 * The passed memory-buffer cert image is in DER, and the
304 * memory-buffer private key image is PEM.
305 */
306 #ifndef USE_WOLFSSL
307 if (lws_tls_alloc_pem_to_der_file(vhost->context, cert, mem_cert,
308 mem_cert_len, &p, &flen)) {
309 lwsl_err("%s: couldn't convert pem to der\n", __func__);
310 return 1;
311 }
312 if (SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx,
313 (int)flen,
314 (uint8_t *)p) != 1) {
315 #else
316 if (wolfSSL_CTX_use_certificate_buffer(vhost->tls.ssl_ctx,
317 (uint8_t *)mem_cert,
318 (int)mem_cert_len,
319 WOLFSSL_FILETYPE_ASN1) != 1) {
320
321 #endif
322 lwsl_err("Problem loading update cert\n");
323
324 return 1;
325 }
326
327 if (lws_tls_alloc_pem_to_der_file(vhost->context, NULL,
328 mem_privkey, mem_privkey_len,
329 &p, &flen)) {
330 lwsl_notice("unable to convert memory privkey\n");
331
332 return 1;
333 }
334 #ifndef USE_WOLFSSL
335 if (SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA,
336 vhost->tls.ssl_ctx, p,
337 (long)(long long)flen) != 1) {
338 #else
339 if (wolfSSL_CTX_use_PrivateKey_buffer(vhost->tls.ssl_ctx, p,
340 flen, WOLFSSL_FILETYPE_ASN1) != 1) {
341 #endif
342 lwsl_notice("unable to use memory privkey\n");
343
344 return 1;
345 }
346
347 goto check_key;
348 }
349
350 /* set the local certificate from CertFile */
351 m = SSL_CTX_use_certificate_chain_file(vhost->tls.ssl_ctx, cert);
352 if (m != 1) {
353 error = ERR_get_error();
354 lwsl_err("problem getting cert '%s' %lu: %s\n",
355 cert, error, ERR_error_string(error,
356 (char *)vhost->context->pt[0].serv_buf));
357
358 return 1;
359 }
360
361 if (n != LWS_TLS_EXTANT_ALTERNATIVE && private_key) {
362 /* set the private key from KeyFile */
363 if (SSL_CTX_use_PrivateKey_file(vhost->tls.ssl_ctx, private_key,
364 SSL_FILETYPE_PEM) != 1) {
365 error = ERR_get_error();
366 lwsl_err("ssl problem getting key '%s' %lu: %s\n",
367 private_key, error,
368 ERR_error_string(error,
369 (char *)vhost->context->pt[0].serv_buf));
370 return 1;
371 }
372 } else {
373 if (vhost->protocols[0].callback(wsi,
374 LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
375 vhost->tls.ssl_ctx, NULL, 0)) {
376 lwsl_err("ssl private key not set\n");
377
378 return 1;
379 }
380 }
381
382 check_key:
383 #endif
384
385 /* verify private key */
386 if (!SSL_CTX_check_private_key(vhost->tls.ssl_ctx)) {
387 lwsl_err("Private SSL key doesn't match cert\n");
388
389 return 1;
390 }
391
392
393 #if !defined(OPENSSL_NO_EC)
394 if (vhost->tls.ecdh_curve[0])
395 ecdh_curve = vhost->tls.ecdh_curve;
396
397 ecdh_nid = OBJ_sn2nid(ecdh_curve);
398 if (NID_undef == ecdh_nid) {
399 lwsl_err("SSL: Unknown curve name '%s'", ecdh_curve);
400 return 1;
401 }
402
403 ecdh = EC_KEY_new_by_curve_name(ecdh_nid);
404 if (NULL == ecdh) {
405 lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve);
406 return 1;
407 }
408 SSL_CTX_set_tmp_ecdh(vhost->tls.ssl_ctx, ecdh);
409 EC_KEY_free(ecdh);
410
411 SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
412
413 lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve);
414
415 if (lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_SSL_ECDH))
416 lwsl_notice(" Using ECDH certificate support\n");
417
418 /* Get X509 certificate from ssl context */
419 #if !defined(LWS_WITH_BORINGSSL)
420 #if !defined(LWS_HAVE_SSL_EXTRA_CHAIN_CERTS)
421 x = sk_X509_value(vhost->tls.ssl_ctx->extra_certs, 0);
422 #else
423 SSL_CTX_get_extra_chain_certs_only(vhost->tls.ssl_ctx, &extra_certs);
424 if (extra_certs)
425 x = sk_X509_value(extra_certs, 0);
426 else
427 lwsl_info("%s: no extra certs\n", __func__);
428 #endif
429 if (!x) {
430 //lwsl_err("%s: x is NULL\n", __func__);
431 goto post_ecdh;
432 }
433 #else
434 return 0;
435 #endif
436 /* Get the public key from certificate */
437 pkey = X509_get_pubkey(x);
438 if (!pkey) {
439 lwsl_err("%s: pkey is NULL\n", __func__);
440
441 return 1;
442 }
443 /* Get the key type */
444 KeyType = EVP_PKEY_type(EVP_PKEY_id(pkey));
445
446 if (EVP_PKEY_EC != KeyType) {
447 lwsl_notice("Key type is not EC\n");
448 return 0;
449 }
450 /* Get the key */
451 EC_key = EVP_PKEY_get1_EC_KEY(pkey);
452 /* Set ECDH parameter */
453 if (!EC_key) {
454 lwsl_err("%s: ECDH key is NULL \n", __func__);
455 return 1;
456 }
457 SSL_CTX_set_tmp_ecdh(vhost->tls.ssl_ctx, EC_key);
458
459 EC_KEY_free(EC_key);
460 #else
461 lwsl_notice(" OpenSSL doesn't support ECDH\n");
462 #endif
463 #if !defined(OPENSSL_NO_EC) && !defined(LWS_WITH_BORINGSSL)
464 post_ecdh:
465 #endif
466 vhost->tls.skipped_certs = 0;
467
468 return 0;
469 }
470
471 int
472 lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
473 struct lws_vhost *vhost, struct lws *wsi)
474 {
475 unsigned long error;
476 SSL_METHOD *method = (SSL_METHOD *)SSLv23_server_method();
477
478 if (!method) {
479 error = ERR_get_error();
480 lwsl_err("problem creating ssl method %lu: %s\n",
481 error, ERR_error_string(error,
482 (char *)vhost->context->pt[0].serv_buf));
483 return 1;
484 }
485 vhost->tls.ssl_ctx = SSL_CTX_new(method); /* create context */
486 if (!vhost->tls.ssl_ctx) {
487 error = ERR_get_error();
488 lwsl_err("problem creating ssl context %lu: %s\n",
489 error, ERR_error_string(error,
490 (char *)vhost->context->pt[0].serv_buf));
491 return 1;
492 }
493
494 SSL_CTX_set_ex_data(vhost->tls.ssl_ctx,
495 openssl_SSL_CTX_private_data_index,
496 (char *)vhost->context);
497 /* Disable SSLv2 and SSLv3 */
498 SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_NO_SSLv2 |
499 SSL_OP_NO_SSLv3);
500 #ifdef SSL_OP_NO_COMPRESSION
501 SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_NO_COMPRESSION);
502 #endif
503 SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_SINGLE_DH_USE);
504 SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
505
506 if (info->ssl_cipher_list)
507 SSL_CTX_set_cipher_list(vhost->tls.ssl_ctx, info->ssl_cipher_list);
508
509 #if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
510 if (info->tls1_3_plus_cipher_list)
511 SSL_CTX_set_ciphersuites(vhost->tls.ssl_ctx,
512 info->tls1_3_plus_cipher_list);
513 #endif
514
515 #if !defined(OPENSSL_NO_TLSEXT)
516 SSL_CTX_set_tlsext_servername_callback(vhost->tls.ssl_ctx,
517 lws_ssl_server_name_cb);
518 SSL_CTX_set_tlsext_servername_arg(vhost->tls.ssl_ctx, vhost->context);
519 #endif
520
521 if (info->ssl_ca_filepath &&
522 !SSL_CTX_load_verify_locations(vhost->tls.ssl_ctx,
523 info->ssl_ca_filepath, NULL)) {
524 lwsl_err("%s: SSL_CTX_load_verify_locations unhappy\n",
525 __func__);
526 }
527
528 if (info->ssl_options_set)
529 SSL_CTX_set_options(vhost->tls.ssl_ctx, info->ssl_options_set);
530
531 /* SSL_clear_options introduced in 0.9.8m */
532 #if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
533 if (info->ssl_options_clear)
534 SSL_CTX_clear_options(vhost->tls.ssl_ctx,
535 info->ssl_options_clear);
536 #endif
537
538 lwsl_info(" SSL options 0x%lX\n",
539 (unsigned long)SSL_CTX_get_options(vhost->tls.ssl_ctx));
540 if (!vhost->tls.use_ssl ||
541 (!info->ssl_cert_filepath && !info->server_ssl_cert_mem))
542 return 0;
543
544 lws_ssl_bind_passphrase(vhost->tls.ssl_ctx, 0, info);
545
546 return lws_tls_server_certs_load(vhost, wsi, info->ssl_cert_filepath,
547 info->ssl_private_key_filepath,
548 info->server_ssl_cert_mem,
549 info->server_ssl_cert_mem_len,
550 info->server_ssl_private_key_mem,
551 info->server_ssl_private_key_mem_len);
552 }
553
554 int
555 lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd)
556 {
557 #if !defined(USE_WOLFSSL)
558 BIO *bio;
559 #endif
560
561 errno = 0;
562 ERR_clear_error();
563 wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_ctx);
564 if (wsi->tls.ssl == NULL) {
565 lwsl_err("SSL_new failed: %d (errno %d)\n",
566 lws_ssl_get_error(wsi, 0), errno);
567
568 lws_tls_err_describe_clear();
569 return 1;
570 }
571
572 SSL_set_ex_data(wsi->tls.ssl, openssl_websocket_private_data_index, wsi);
573 SSL_set_fd(wsi->tls.ssl, (int)(long long)accept_fd);
574
575 #ifdef USE_WOLFSSL
576 #ifdef USE_OLD_CYASSL
577 CyaSSL_set_using_nonblock(wsi->tls.ssl, 1);
578 #else
579 wolfSSL_set_using_nonblock(wsi->tls.ssl, 1);
580 #endif
581 #else
582
583 SSL_set_mode(wsi->tls.ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
584 SSL_MODE_RELEASE_BUFFERS);
585 bio = SSL_get_rbio(wsi->tls.ssl);
586 if (bio)
587 BIO_set_nbio(bio, 1); /* nonblocking */
588 else
589 lwsl_notice("NULL rbio\n");
590 bio = SSL_get_wbio(wsi->tls.ssl);
591 if (bio)
592 BIO_set_nbio(bio, 1); /* nonblocking */
593 else
594 lwsl_notice("NULL rbio\n");
595 #endif
596
597 #if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
598 if (wsi->vhost->tls.ssl_info_event_mask)
599 SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
600 #endif
601
602 return 0;
603 }
604
605 int
606 lws_tls_server_abort_connection(struct lws *wsi)
607 {
608 SSL_shutdown(wsi->tls.ssl);
609 SSL_free(wsi->tls.ssl);
610
611 return 0;
612 }
613
614 enum lws_ssl_capable_status
615 lws_tls_server_accept(struct lws *wsi)
616 {
617 struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
618 union lws_tls_cert_info_results ir;
619 int m, n;
620
621 errno = 0;
622 ERR_clear_error();
623 n = SSL_accept(wsi->tls.ssl);
624
625 wsi->skip_fallback = 1;
626
627 if (n == 1) {
628 n = lws_tls_peer_cert_info(wsi, LWS_TLS_CERT_INFO_COMMON_NAME, &ir,
629 sizeof(ir.ns.name));
630 if (!n)
631 lwsl_notice("%s: client cert CN '%s'\n", __func__,
632 ir.ns.name);
633 else
634 lwsl_info("%s: no client cert CN\n", __func__);
635
636 lws_openssl_describe_cipher(wsi);
637
638 if (SSL_pending(wsi->tls.ssl) &&
639 lws_dll2_is_detached(&wsi->tls.dll_pending_tls))
640 lws_dll2_add_head(&wsi->tls.dll_pending_tls,
641 &pt->tls.dll_pending_tls_owner);
642
643 return LWS_SSL_CAPABLE_DONE;
644 }
645
646 m = lws_ssl_get_error(wsi, n);
647 lws_tls_err_describe_clear();
648
649 if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL)
650 return LWS_SSL_CAPABLE_ERROR;
651
652 if (m == SSL_ERROR_WANT_READ ||
653 (m != SSL_ERROR_ZERO_RETURN && SSL_want_read(wsi->tls.ssl))) {
654 if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
655 lwsl_info("%s: WANT_READ change_pollfd failed\n",
656 __func__);
657 return LWS_SSL_CAPABLE_ERROR;
658 }
659
660 lwsl_info("SSL_ERROR_WANT_READ: m %d\n", m);
661 return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
662 }
663 if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
664 lwsl_debug("%s: WANT_WRITE\n", __func__);
665
666 if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
667 lwsl_info("%s: WANT_WRITE change_pollfd failed\n",
668 __func__);
669 return LWS_SSL_CAPABLE_ERROR;
670 }
671 return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
672 }
673
674 return LWS_SSL_CAPABLE_ERROR;
675 }
676
677 #if defined(LWS_WITH_ACME)
678 static int
679 lws_tls_openssl_rsa_new_key(RSA **rsa, int bits)
680 {
681 BIGNUM *bn = BN_new();
682 int n;
683
684 if (!bn)
685 return 1;
686
687 if (BN_set_word(bn, RSA_F4) != 1) {
688 BN_free(bn);
689 return 1;
690 }
691
692 *rsa = RSA_new();
693 if (!*rsa) {
694 BN_free(bn);
695 return 1;
696 }
697
698 n = RSA_generate_key_ex(*rsa, bits, bn, NULL);
699 BN_free(bn);
700 if (n == 1)
701 return 0;
702
703 RSA_free(*rsa);
704 *rsa = NULL;
705
706 return 1;
707 }
708
709 struct lws_tls_ss_pieces {
710 X509 *x509;
711 EVP_PKEY *pkey;
712 RSA *rsa;
713 };
714
715 int
716 lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
717 const char *san_b)
718 {
719 GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
720 GENERAL_NAME *gen = NULL;
721 ASN1_IA5STRING *ia5 = NULL;
722 X509_NAME *name;
723
724 if (!gens)
725 return 1;
726
727 vhost->tls.ss = lws_zalloc(sizeof(*vhost->tls.ss), "sni cert");
728 if (!vhost->tls.ss) {
729 GENERAL_NAMES_free(gens);
730 return 1;
731 }
732
733 vhost->tls.ss->x509 = X509_new();
734 if (!vhost->tls.ss->x509)
735 goto bail;
736
737 ASN1_INTEGER_set(X509_get_serialNumber(vhost->tls.ss->x509), 1);
738 X509_gmtime_adj(X509_get_notBefore(vhost->tls.ss->x509), 0);
739 X509_gmtime_adj(X509_get_notAfter(vhost->tls.ss->x509), 3600);
740
741 vhost->tls.ss->pkey = EVP_PKEY_new();
742 if (!vhost->tls.ss->pkey)
743 goto bail0;
744
745 if (lws_tls_openssl_rsa_new_key(&vhost->tls.ss->rsa, 4096))
746 goto bail1;
747
748 if (!EVP_PKEY_assign_RSA(vhost->tls.ss->pkey, vhost->tls.ss->rsa))
749 goto bail2;
750
751 X509_set_pubkey(vhost->tls.ss->x509, vhost->tls.ss->pkey);
752
753 name = X509_get_subject_name(vhost->tls.ss->x509);
754 X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
755 (unsigned char *)"GB", -1, -1, 0);
756 X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
757 (unsigned char *)"somecompany", -1, -1, 0);
758 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8,
759 (unsigned char *)"temp.acme.invalid",
760 -1, -1, 0) != 1) {
761 lwsl_notice("failed to add CN\n");
762 goto bail2;
763 }
764 X509_set_issuer_name(vhost->tls.ss->x509, name);
765
766 /* add the SAN payloads */
767
768 gen = GENERAL_NAME_new();
769 ia5 = ASN1_IA5STRING_new();
770 if (!ASN1_STRING_set(ia5, san_a, -1)) {
771 lwsl_notice("failed to set ia5\n");
772 GENERAL_NAME_free(gen);
773 goto bail2;
774 }
775 GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
776 sk_GENERAL_NAME_push(gens, gen);
777
778 if (X509_add1_ext_i2d(vhost->tls.ss->x509, NID_subject_alt_name,
779 gens, 0, X509V3_ADD_APPEND) != 1)
780 goto bail2;
781
782 GENERAL_NAMES_free(gens);
783
784 if (san_b && san_b[0]) {
785 gens = sk_GENERAL_NAME_new_null();
786 gen = GENERAL_NAME_new();
787 ia5 = ASN1_IA5STRING_new();
788 if (!ASN1_STRING_set(ia5, san_a, -1)) {
789 lwsl_notice("failed to set ia5\n");
790 GENERAL_NAME_free(gen);
791 goto bail2;
792 }
793 GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
794 sk_GENERAL_NAME_push(gens, gen);
795
796 if (X509_add1_ext_i2d(vhost->tls.ss->x509, NID_subject_alt_name,
797 gens, 0, X509V3_ADD_APPEND) != 1)
798 goto bail2;
799
800 GENERAL_NAMES_free(gens);
801 }
802
803 /* sign it with our private key */
804 if (!X509_sign(vhost->tls.ss->x509, vhost->tls.ss->pkey, EVP_sha256()))
805 goto bail2;
806
807 #if 0
808 {/* useful to take a sample of a working cert for mbedtls to crib */
809 FILE *fp = fopen("/tmp/acme-temp-cert", "w+");
810
811 i2d_X509_fp(fp, vhost->tls.ss->x509);
812 fclose(fp);
813 }
814 #endif
815
816 /* tell the vhost to use our crafted certificate */
817 SSL_CTX_use_certificate(vhost->tls.ssl_ctx, vhost->tls.ss->x509);
818 /* and to use our generated private key */
819 SSL_CTX_use_PrivateKey(vhost->tls.ssl_ctx, vhost->tls.ss->pkey);
820
821 return 0;
822
823 bail2:
824 RSA_free(vhost->tls.ss->rsa);
825 bail1:
826 EVP_PKEY_free(vhost->tls.ss->pkey);
827 bail0:
828 X509_free(vhost->tls.ss->x509);
829 bail:
830 lws_free(vhost->tls.ss);
831 GENERAL_NAMES_free(gens);
832
833 return 1;
834 }
835
836 void
837 lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost)
838 {
839 if (!vhost->tls.ss)
840 return;
841
842 EVP_PKEY_free(vhost->tls.ss->pkey);
843 X509_free(vhost->tls.ss->x509);
844 lws_free_set_NULL(vhost->tls.ss);
845 }
846
847 static int
848 lws_tls_openssl_add_nid(X509_NAME *name, int nid, const char *value)
849 {
850 X509_NAME_ENTRY *e;
851 int n;
852
853 if (!value || value[0] == '\0')
854 value = "none";
855
856 e = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
857 (unsigned char *)value, -1);
858 if (!e)
859 return 1;
860 n = X509_NAME_add_entry(name, e, -1, 0);
861 X509_NAME_ENTRY_free(e);
862
863 return n != 1;
864 }
865
866 static int nid_list[] = {
867 NID_countryName, /* LWS_TLS_REQ_ELEMENT_COUNTRY */
868 NID_stateOrProvinceName, /* LWS_TLS_REQ_ELEMENT_STATE */
869 NID_localityName, /* LWS_TLS_REQ_ELEMENT_LOCALITY */
870 NID_organizationName, /* LWS_TLS_REQ_ELEMENT_ORGANIZATION */
871 NID_commonName, /* LWS_TLS_REQ_ELEMENT_COMMON_NAME */
872 NID_subject_alt_name, /* LWS_TLS_REQ_ELEMENT_SUBJECT_ALT_NAME */
873 NID_pkcs9_emailAddress, /* LWS_TLS_REQ_ELEMENT_EMAIL */
874 };
875
876 int
877 lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[],
878 uint8_t *csr, size_t csr_len, char **privkey_pem,
879 size_t *privkey_len)
880 {
881 uint8_t *csr_in = csr;
882 RSA *rsakey;
883 X509_REQ *req;
884 X509_NAME *subj;
885 EVP_PKEY *pkey;
886 char *p, *end;
887 BIO *bio;
888 long bio_len;
889 int n, ret = -1;
890
891 if (lws_tls_openssl_rsa_new_key(&rsakey, 4096))
892 return -1;
893
894 pkey = EVP_PKEY_new();
895 if (!pkey)
896 goto bail0;
897 if (!EVP_PKEY_set1_RSA(pkey, rsakey))
898 goto bail1;
899
900 req = X509_REQ_new();
901 if (!req)
902 goto bail1;
903
904 X509_REQ_set_pubkey(req, pkey);
905
906 subj = X509_NAME_new();
907 if (!subj)
908 goto bail2;
909
910 for (n = 0; n < LWS_TLS_REQ_ELEMENT_COUNT; n++)
911 if (elements[n] &&
912 lws_tls_openssl_add_nid(subj, nid_list[n],
913 elements[n])) {
914 lwsl_notice("%s: failed to add element %d\n",
915 __func__, n);
916 goto bail3;
917 }
918
919 if (X509_REQ_set_subject_name(req, subj) != 1)
920 goto bail3;
921
922 if (elements[LWS_TLS_REQ_ELEMENT_SUBJECT_ALT_NAME]) {
923 STACK_OF(X509_EXTENSION) *exts;
924 X509_EXTENSION *ext;
925 char san[256];
926
927 exts = sk_X509_EXTENSION_new_null();
928 if (!exts)
929 goto bail3;
930
931 lws_snprintf(san, sizeof(san), "DNS:%s,DNS:%s",
932 elements[LWS_TLS_REQ_ELEMENT_COMMON_NAME],
933 elements[LWS_TLS_REQ_ELEMENT_SUBJECT_ALT_NAME]);
934
935 ext = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name,
936 san);
937 if (!ext) {
938 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
939 goto bail3;
940 }
941 sk_X509_EXTENSION_push(exts, ext);
942
943 if (!X509_REQ_add_extensions(req, exts)) {
944 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
945 goto bail3;
946 }
947 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
948 }
949
950 if (!X509_REQ_sign(req, pkey, EVP_sha256()))
951 goto bail3;
952
953 /*
954 * issue the CSR as PEM to a BIO, and translate to b64urlenc without
955 * headers, trailers, or whitespace
956 */
957
958 bio = BIO_new(BIO_s_mem());
959 if (!bio)
960 goto bail3;
961
962 if (PEM_write_bio_X509_REQ(bio, req) != 1) {
963 BIO_free(bio);
964 goto bail3;
965 }
966
967 bio_len = BIO_get_mem_data(bio, &p);
968 end = p + bio_len;
969
970 /* strip the header line */
971 while (p < end && *p != '\n')
972 p++;
973
974 while (p < end && csr_len) {
975 if (*p == '\n') {
976 p++;
977 continue;
978 }
979
980 if (*p == '-')
981 break;
982
983 if (*p == '+')
984 *csr++ = '-';
985 else
986 if (*p == '/')
987 *csr++ = '_';
988 else
989 *csr++ = *p;
990 p++;
991 csr_len--;
992 }
993 BIO_free(bio);
994 if (!csr_len) {
995 lwsl_notice("%s: need %ld for CSR\n", __func__, bio_len);
996 goto bail3;
997 }
998
999 /*
1000 * Also return the private key as a PEM in memory
1001 * (platform may not have a filesystem)
1002 */
1003 bio = BIO_new(BIO_s_mem());
1004 if (!bio)
1005 goto bail3;
1006
1007 if (PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, 0, NULL) != 1) {
1008 BIO_free(bio);
1009 goto bail3;
1010 }
1011 bio_len = BIO_get_mem_data(bio, &p);
1012 *privkey_pem = malloc(bio_len); /* malloc so user code can own / free */
1013 *privkey_len = (size_t)bio_len;
1014 if (!*privkey_pem) {
1015 lwsl_notice("%s: need %ld for private key\n", __func__,
1016 bio_len);
1017 BIO_free(bio);
1018 goto bail3;
1019 }
1020 memcpy(*privkey_pem, p, (int)(long long)bio_len);
1021 BIO_free(bio);
1022
1023 ret = lws_ptr_diff(csr, csr_in);
1024
1025 bail3:
1026 X509_NAME_free(subj);
1027 bail2:
1028 X509_REQ_free(req);
1029 bail1:
1030 EVP_PKEY_free(pkey);
1031 bail0:
1032 RSA_free(rsakey);
1033
1034 return ret;
1035 }
1036 #endif
1037