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