introduce vhosts
[platform/upstream/libwebsockets.git] / lib / ssl.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation:
9  *  version 2.1 of the License.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA  02110-1301  USA
20  */
21
22 #include "private-libwebsockets.h"
23 #ifndef USE_WOLFSSL
24  #include <openssl/err.h>
25 #endif
26
27 #ifdef LWS_HAVE_OPENSSL_ECDH_H
28 #include <openssl/ecdh.h>
29 #endif
30
31 int openssl_websocket_private_data_index,
32     openssl_SSL_CTX_private_data_index;
33
34 static int
35 lws_context_init_ssl_pem_passwd_cb(char * buf, int size, int rwflag, void *userdata)
36 {
37         struct lws_context_creation_info * info =
38                         (struct lws_context_creation_info *)userdata;
39
40         strncpy(buf, info->ssl_private_key_password, size);
41         buf[size - 1] = '\0';
42
43         return strlen(buf);
44 }
45
46 static void lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, struct lws_context_creation_info *info)
47 {
48         if (!info->ssl_private_key_password)
49                 return;
50         /*
51          * password provided, set ssl callback and user data
52          * for checking password which will be trigered during
53          * SSL_CTX_use_PrivateKey_file function
54          */
55         SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)info);
56         SSL_CTX_set_default_passwd_cb(ssl_ctx, lws_context_init_ssl_pem_passwd_cb);
57 }
58
59 int
60 lws_context_init_ssl_library(struct lws_context_creation_info *info)
61 {
62 #ifdef USE_WOLFSSL
63 #ifdef USE_OLD_CYASSL
64         lwsl_notice(" Compiled with CyaSSL support\n");
65 #else
66         lwsl_notice(" Compiled with wolfSSL support\n");
67 #endif
68 #else
69         lwsl_notice(" Compiled with OpenSSL support\n");
70 #endif
71
72         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
73                 lwsl_notice(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n");
74                 return 0;
75         }
76
77         /* basic openssl init */
78
79         SSL_library_init();
80
81         OpenSSL_add_all_algorithms();
82         SSL_load_error_strings();
83
84         openssl_websocket_private_data_index =
85                 SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL);
86
87         openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0,
88                         NULL, NULL, NULL, NULL);
89
90         return 0;
91 }
92
93 #ifndef LWS_NO_SERVER
94 static int
95 OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
96 {
97         SSL *ssl;
98         int n;
99         struct lws_vhost *vh;
100         struct lws wsi;
101
102         ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
103                 SSL_get_ex_data_X509_STORE_CTX_idx());
104
105         /*
106          * !!! nasty openssl requires the index to come as a library-scope
107          * static
108          */
109         vh = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
110
111         /*
112          * give him a fake wsi with context set, so he can use lws_get_context()
113          * in the callback
114          */
115         memset(&wsi, 0, sizeof(wsi));
116         wsi.vhost = vh;
117         wsi.context = vh->context;
118
119         n = vh->protocols[0].callback(&wsi,
120                         LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
121                                            x509_ctx, ssl, preverify_ok);
122
123         /* convert return code from 0 = OK to 1 = OK */
124         return !n;
125 }
126
127 static int
128 lws_context_ssl_init_ecdh(struct lws_vhost *vhost)
129 {
130 #ifdef LWS_SSL_SERVER_WITH_ECDH_CERT
131         EC_KEY *EC_key = NULL;
132         EVP_PKEY *pkey;
133         int KeyType;
134         X509 *x;
135
136         if (!lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_SSL_ECDH))
137                 return 0;
138
139         lwsl_notice(" Using ECDH certificate support\n");
140
141         /* Get X509 certificate from ssl context */
142         x = sk_X509_value(vhost->ssl_ctx->extra_certs, 0);
143         if (!x) {
144                 lwsl_err("%s: x is NULL\n", __func__);
145                 return 1;
146         }
147         /* Get the public key from certificate */
148         pkey = X509_get_pubkey(x);
149         if (!pkey) {
150                 lwsl_err("%s: pkey is NULL\n", __func__);
151
152                 return 1;
153         }
154         /* Get the key type */
155         KeyType = EVP_PKEY_type(pkey->type);
156
157         if (EVP_PKEY_EC != KeyType) {
158                 lwsl_notice("Key type is not EC\n");
159                 return 0;
160         }
161         /* Get the key */
162         EC_key = EVP_PKEY_get1_EC_KEY(pkey);
163         /* Set ECDH parameter */
164         if (!EC_key) {
165                 lwsl_err("%s: ECDH key is NULL \n", __func__);
166                 return 1;
167         }
168         SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, EC_key);
169         EC_KEY_free(EC_key);
170 #endif
171         return 0;
172 }
173
174 static int
175 lws_context_ssl_init_ecdh_curve(struct lws_context_creation_info *info,
176                                 struct lws_vhost *vhost)
177 {
178 #ifdef LWS_HAVE_OPENSSL_ECDH_H
179         EC_KEY *ecdh;
180         int ecdh_nid;
181         const char *ecdh_curve = "prime256v1";
182
183         if (info->ecdh_curve)
184                 ecdh_curve = info->ecdh_curve;
185
186         ecdh_nid = OBJ_sn2nid(ecdh_curve);
187         if (NID_undef == ecdh_nid) {
188                 lwsl_err("SSL: Unknown curve name '%s'", ecdh_curve);
189                 return 1;
190         }
191
192         ecdh = EC_KEY_new_by_curve_name(ecdh_nid);
193         if (NULL == ecdh) {
194                 lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve);
195                 return 1;
196         }
197         SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, ecdh);
198         EC_KEY_free(ecdh);
199
200         SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
201
202         lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve);
203 #else
204         lwsl_notice(" OpenSSL doesn't support ECDH\n");
205 #endif
206         return 0;
207 }
208
209 #ifndef OPENSSL_NO_TLSEXT
210 static int
211 lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
212 {
213         struct lws_context *context;
214         struct lws_vhost *vhost, *vh;
215         const char *servername;
216         int port;
217
218         if (!ssl)
219                 return SSL_TLSEXT_ERR_NOACK;
220
221         context = (struct lws_context *)SSL_CTX_get_ex_data(
222                                         SSL_get_SSL_CTX(ssl),
223                                         openssl_SSL_CTX_private_data_index);
224
225         /*
226          * We can only get ssl accepted connections by using a vhost's ssl_ctx
227          * find out which listening one took us and only match vhosts on the
228          * same port.
229          */
230         vh = context->vhost_list;
231         while (vh) {
232                 if (vh->ssl_ctx == SSL_get_SSL_CTX(ssl))
233                         break;
234                 vh = vh->vhost_next;
235         }
236
237         assert(vh); /* we cannot get an ssl without using a vhost ssl_ctx */
238         port = vh->listen_port;
239
240         servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
241
242         if (servername) {
243                 vhost = lws_select_vhost(context, port, servername);
244                 if (vhost) {
245                         lwsl_info("SNI: Found: %s\n", servername);
246                         SSL_set_SSL_CTX(ssl, vhost->ssl_ctx);
247                         return SSL_TLSEXT_ERR_OK;
248                 }
249                 lwsl_err("SNI: Unknown ServerName: %s\n", servername);
250         }
251
252         return SSL_TLSEXT_ERR_OK;
253 }
254 #endif
255
256 LWS_VISIBLE int
257 lws_context_init_server_ssl(struct lws_context_creation_info *info,
258                             struct lws_vhost *vhost)
259 {
260         SSL_METHOD *method;
261         struct lws_context *context = vhost->context;
262         struct lws wsi;
263         int error;
264         int n;
265
266         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
267                 vhost->use_ssl = 0;
268                 return 0;
269         }
270
271         if (info->port != CONTEXT_PORT_NO_LISTEN) {
272
273                 vhost->use_ssl = info->ssl_cert_filepath != NULL;
274
275                 if (vhost->use_ssl && info->ssl_cipher_list)
276                         lwsl_notice(" SSL ciphers: '%s'\n", info->ssl_cipher_list);
277
278                 if (vhost->use_ssl)
279                         lwsl_notice(" Using SSL mode\n");
280                 else
281                         lwsl_notice(" Using non-SSL mode\n");
282         }
283
284         /*
285          * give him a fake wsi with context + vhost set, so he can use
286          * lws_get_context() in the callback
287          */
288         memset(&wsi, 0, sizeof(wsi));
289         wsi.vhost = vhost;
290         wsi.context = vhost->context;
291
292         /*
293          * Firefox insists on SSLv23 not SSLv3
294          * Konq disables SSLv2 by default now, SSLv23 works
295          *
296          * SSLv23_server_method() is the openssl method for "allow all TLS
297          * versions", compared to e.g. TLSv1_2_server_method() which only allows
298          * tlsv1.2. Unwanted versions must be disabled using SSL_CTX_set_options()
299          */
300
301         method = (SSL_METHOD *)SSLv23_server_method();
302         if (!method) {
303                 error = ERR_get_error();
304                 lwsl_err("problem creating ssl method %lu: %s\n",
305                         error, ERR_error_string(error,
306                                               (char *)context->pt[0].serv_buf));
307                 return 1;
308         }
309         vhost->ssl_ctx = SSL_CTX_new(method);   /* create context */
310         if (!vhost->ssl_ctx) {
311                 error = ERR_get_error();
312                 lwsl_err("problem creating ssl context %lu: %s\n",
313                         error, ERR_error_string(error,
314                                               (char *)context->pt[0].serv_buf));
315                 return 1;
316         }
317
318         /* associate the lws context with the SSL_CTX */
319
320         SSL_CTX_set_ex_data(vhost->ssl_ctx,
321                         openssl_SSL_CTX_private_data_index, vhost->context);
322
323         /* Disable SSLv2 and SSLv3 */
324         SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
325 #ifdef SSL_OP_NO_COMPRESSION
326         SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_NO_COMPRESSION);
327 #endif
328         SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_DH_USE);
329         SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
330         if (info->ssl_cipher_list)
331                 SSL_CTX_set_cipher_list(vhost->ssl_ctx,
332                                                 info->ssl_cipher_list);
333
334         /* as a server, are we requiring clients to identify themselves? */
335
336         if (lws_check_opt(info->options, LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT)) {
337                 int verify_options = SSL_VERIFY_PEER;
338
339                 if (!lws_check_opt(info->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
340                         verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
341
342                 SSL_CTX_set_session_id_context(vhost->ssl_ctx,
343                                 (unsigned char *)context, sizeof(void *));
344
345                 /* absolutely require the client cert */
346
347                 SSL_CTX_set_verify(vhost->ssl_ctx,
348                        verify_options, OpenSSL_verify_callback);
349         }
350
351 #ifndef OPENSSL_NO_TLSEXT
352         SSL_CTX_set_tlsext_servername_callback(vhost->ssl_ctx,
353                                                lws_ssl_server_name_cb);
354 #endif
355
356         /*
357          * give user code a chance to load certs into the server
358          * allowing it to verify incoming client certs
359          */
360
361         if (info->ssl_ca_filepath &&
362             !SSL_CTX_load_verify_locations(vhost->ssl_ctx,
363                                            info->ssl_ca_filepath, NULL)) {
364                 lwsl_err("%s: SSL_CTX_load_verify_locations unhappy\n", __func__);
365         }
366
367         if (vhost->use_ssl) {
368                 if (lws_context_ssl_init_ecdh_curve(info, vhost))
369                         return -1;
370
371                 vhost->protocols[0].callback(&wsi,
372                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
373                         vhost->ssl_ctx, NULL, 0);
374         }
375
376         if (lws_check_opt(info->options, LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT))
377                 /* Normally SSL listener rejects non-ssl, optionally allow */
378                 vhost->allow_non_ssl_on_ssl_port = 1;
379
380         if (vhost->use_ssl) {
381                 /* openssl init for server sockets */
382
383                 /* set the local certificate from CertFile */
384                 n = SSL_CTX_use_certificate_chain_file(vhost->ssl_ctx,
385                                         info->ssl_cert_filepath);
386                 if (n != 1) {
387                         error = ERR_get_error();
388                         lwsl_err("problem getting cert '%s' %lu: %s\n",
389                                 info->ssl_cert_filepath,
390                                 error,
391                                 ERR_error_string(error,
392                                               (char *)context->pt[0].serv_buf));
393                         return 1;
394                 }
395                 lws_ssl_bind_passphrase(vhost->ssl_ctx, info);
396
397                 if (info->ssl_private_key_filepath != NULL) {
398                         /* set the private key from KeyFile */
399                         if (SSL_CTX_use_PrivateKey_file(vhost->ssl_ctx,
400                                      info->ssl_private_key_filepath,
401                                                        SSL_FILETYPE_PEM) != 1) {
402                                 error = ERR_get_error();
403                                 lwsl_err("ssl problem getting key '%s' %lu: %s\n",
404                                          info->ssl_private_key_filepath, error,
405                                          ERR_error_string(error,
406                                               (char *)context->pt[0].serv_buf));
407                                 return 1;
408                         }
409                 } else
410                         if (vhost->protocols[0].callback(&wsi,
411                                 LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
412                                 vhost->ssl_ctx, NULL, 0)) {
413                                 lwsl_err("ssl private key not set\n");
414
415                                 return 1;
416                         }
417
418                 /* verify private key */
419                 if (!SSL_CTX_check_private_key(vhost->ssl_ctx)) {
420                         lwsl_err("Private SSL key doesn't match cert\n");
421                         return 1;
422                 }
423
424                 if (lws_context_ssl_init_ecdh(vhost))
425                         return 1;
426
427                 /*
428                  * SSL is happy and has a cert it's content with
429                  * If we're supporting HTTP2, initialize that
430                  */
431
432                 lws_context_init_http2_ssl(context);
433         }
434
435         return 0;
436 }
437 #endif
438
439 LWS_VISIBLE void
440 lws_ssl_destroy(struct lws_vhost *vhost)
441 {
442         if (!lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
443                 return;
444
445         if (vhost->ssl_ctx)
446                 SSL_CTX_free(vhost->ssl_ctx);
447         if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
448                 SSL_CTX_free(vhost->ssl_client_ctx);
449
450 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
451         ERR_remove_state(0);
452 #else
453         ERR_remove_thread_state(NULL);
454 #endif
455         ERR_free_strings();
456         EVP_cleanup();
457         CRYPTO_cleanup_all_ex_data();
458 }
459
460 LWS_VISIBLE void
461 lws_decode_ssl_error(void)
462 {
463         char buf[256];
464         u_long err;
465
466         while ((err = ERR_get_error()) != 0) {
467                 ERR_error_string_n(err, buf, sizeof(buf));
468                 lwsl_err("*** %lu %s\n", err, buf);
469         }
470 }
471
472 #ifndef LWS_NO_CLIENT
473
474 int lws_context_init_client_ssl(struct lws_context_creation_info *info,
475                                 struct lws_vhost *vhost)
476 {
477         int error;
478         int n;
479         SSL_METHOD *method;
480         struct lws wsi;
481
482         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
483                 return 0;
484
485         if (info->provided_client_ssl_ctx) {
486                 /* use the provided OpenSSL context if given one */
487                 vhost->ssl_client_ctx = info->provided_client_ssl_ctx;
488                 /* nothing for lib to delete */
489                 vhost->user_supplied_ssl_ctx = 1;
490                 return 0;
491         }
492
493         if (info->port != CONTEXT_PORT_NO_LISTEN)
494                 return 0;
495
496         /* basic openssl init */
497
498         SSL_library_init();
499
500         OpenSSL_add_all_algorithms();
501         SSL_load_error_strings();
502
503         method = (SSL_METHOD *)SSLv23_client_method();
504         if (!method) {
505                 error = ERR_get_error();
506                 lwsl_err("problem creating ssl method %lu: %s\n",
507                         error, ERR_error_string(error,
508                                       (char *)vhost->context->pt[0].serv_buf));
509                 return 1;
510         }
511         /* create context */
512         vhost->ssl_client_ctx = SSL_CTX_new(method);
513         if (!vhost->ssl_client_ctx) {
514                 error = ERR_get_error();
515                 lwsl_err("problem creating ssl context %lu: %s\n",
516                         error, ERR_error_string(error,
517                                       (char *)vhost->context->pt[0].serv_buf));
518                 return 1;
519         }
520
521 #ifdef SSL_OP_NO_COMPRESSION
522         SSL_CTX_set_options(vhost->ssl_client_ctx,
523                                                  SSL_OP_NO_COMPRESSION);
524 #endif
525         SSL_CTX_set_options(vhost->ssl_client_ctx,
526                                        SSL_OP_CIPHER_SERVER_PREFERENCE);
527         if (info->ssl_cipher_list)
528                 SSL_CTX_set_cipher_list(vhost->ssl_client_ctx,
529                                                 info->ssl_cipher_list);
530
531 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
532         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
533                 /* loads OS default CA certs */
534                 SSL_CTX_set_default_verify_paths(vhost->ssl_client_ctx);
535 #endif
536
537         /* openssl init for cert verification (for client sockets) */
538         if (!info->ssl_ca_filepath) {
539                 if (!SSL_CTX_load_verify_locations(
540                         vhost->ssl_client_ctx, NULL,
541                                              LWS_OPENSSL_CLIENT_CERTS))
542                         lwsl_err(
543                             "Unable to load SSL Client certs from %s "
544                             "(set by --with-client-cert-dir= "
545                             "in configure) --  client ssl isn't "
546                             "going to work", LWS_OPENSSL_CLIENT_CERTS);
547         } else
548                 if (!SSL_CTX_load_verify_locations(
549                         vhost->ssl_client_ctx, info->ssl_ca_filepath,
550                                                           NULL))
551                         lwsl_err(
552                                 "Unable to load SSL Client certs "
553                                 "file from %s -- client ssl isn't "
554                                 "going to work", info->ssl_ca_filepath);
555                 else
556                         lwsl_info("loaded ssl_ca_filepath\n");
557
558         /*
559          * callback allowing user code to load extra verification certs
560          * helping the client to verify server identity
561          */
562
563         /* support for client-side certificate authentication */
564         if (info->ssl_cert_filepath) {
565                 n = SSL_CTX_use_certificate_chain_file(vhost->ssl_client_ctx,
566                                                        info->ssl_cert_filepath);
567                 if (n != 1) {
568                         lwsl_err("problem getting cert '%s' %lu: %s\n",
569                                 info->ssl_cert_filepath,
570                                 ERR_get_error(),
571                                 ERR_error_string(ERR_get_error(),
572                                 (char *)vhost->context->pt[0].serv_buf));
573                         return 1;
574                 }
575         }
576         if (info->ssl_private_key_filepath) {
577                 lws_ssl_bind_passphrase(vhost->ssl_client_ctx, info);
578                 /* set the private key from KeyFile */
579                 if (SSL_CTX_use_PrivateKey_file(vhost->ssl_client_ctx,
580                     info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
581                         lwsl_err("use_PrivateKey_file '%s' %lu: %s\n",
582                                 info->ssl_private_key_filepath,
583                                 ERR_get_error(),
584                                 ERR_error_string(ERR_get_error(),
585                                       (char *)vhost->context->pt[0].serv_buf));
586                         return 1;
587                 }
588
589                 /* verify private key */
590                 if (!SSL_CTX_check_private_key(vhost->ssl_client_ctx)) {
591                         lwsl_err("Private SSL key doesn't match cert\n");
592                         return 1;
593                 }
594         }
595
596         /*
597          * give him a fake wsi with context set, so he can use
598          * lws_get_context() in the callback
599          */
600         memset(&wsi, 0, sizeof(wsi));
601         wsi.vhost = vhost;
602         wsi.context = vhost->context;
603
604         vhost->protocols[0].callback(&wsi,
605                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
606                                        vhost->ssl_client_ctx, NULL, 0);
607
608         return 0;
609 }
610 #endif
611
612 LWS_VISIBLE void
613 lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi)
614 {
615         struct lws_context *context = wsi->context;
616         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
617
618         if (!wsi->pending_read_list_prev &&
619             !wsi->pending_read_list_next &&
620             pt->pending_read_list != wsi)
621                 /* we are not on the list */
622                 return;
623
624         /* point previous guy's next to our next */
625         if (!wsi->pending_read_list_prev)
626                 pt->pending_read_list = wsi->pending_read_list_next;
627         else
628                 wsi->pending_read_list_prev->pending_read_list_next =
629                         wsi->pending_read_list_next;
630
631         /* point next guy's previous to our previous */
632         if (wsi->pending_read_list_next)
633                 wsi->pending_read_list_next->pending_read_list_prev =
634                         wsi->pending_read_list_prev;
635
636         wsi->pending_read_list_prev = NULL;
637         wsi->pending_read_list_next = NULL;
638 }
639
640 LWS_VISIBLE int
641 lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
642 {
643         struct lws_context *context = wsi->context;
644         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
645         int n;
646
647         if (!wsi->ssl)
648                 return lws_ssl_capable_read_no_ssl(wsi, buf, len);
649
650         n = SSL_read(wsi->ssl, buf, len);
651         /* manpage: returning 0 means connection shut down */
652         if (!n)
653                 return LWS_SSL_CAPABLE_ERROR;
654
655         if (n < 0) {
656                 n = SSL_get_error(wsi->ssl, n);
657                 if (n ==  SSL_ERROR_WANT_READ || n ==  SSL_ERROR_WANT_WRITE)
658                         return LWS_SSL_CAPABLE_MORE_SERVICE;
659
660                 return LWS_SSL_CAPABLE_ERROR;
661         }
662
663         /*
664          * if it was our buffer that limited what we read,
665          * check if SSL has additional data pending inside SSL buffers.
666          *
667          * Because these won't signal at the network layer with POLLIN
668          * and if we don't realize, this data will sit there forever
669          */
670         if (n != len)
671                 goto bail;
672         if (!wsi->ssl)
673                 goto bail;
674         if (!SSL_pending(wsi->ssl))
675                 goto bail;
676         if (wsi->pending_read_list_next)
677                 return n;
678         if (wsi->pending_read_list_prev)
679                 return n;
680         if (pt->pending_read_list == wsi)
681                 return n;
682
683         /* add us to the linked list of guys with pending ssl */
684         if (pt->pending_read_list)
685                 pt->pending_read_list->pending_read_list_prev = wsi;
686
687         wsi->pending_read_list_next = pt->pending_read_list;
688         wsi->pending_read_list_prev = NULL;
689         pt->pending_read_list = wsi;
690
691         return n;
692 bail:
693         lws_ssl_remove_wsi_from_buffered_list(wsi);
694
695         return n;
696 }
697
698 LWS_VISIBLE int
699 lws_ssl_pending(struct lws *wsi)
700 {
701         if (!wsi->ssl)
702                 return 0;
703
704         return SSL_pending(wsi->ssl);
705 }
706
707 LWS_VISIBLE int
708 lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
709 {
710         int n;
711
712         if (!wsi->ssl)
713                 return lws_ssl_capable_write_no_ssl(wsi, buf, len);
714
715         n = SSL_write(wsi->ssl, buf, len);
716         if (n > 0)
717                 return n;
718
719         n = SSL_get_error(wsi->ssl, n);
720         if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE) {
721                 if (n == SSL_ERROR_WANT_WRITE)
722                         lws_set_blocking_send(wsi);
723                 return LWS_SSL_CAPABLE_MORE_SERVICE;
724         }
725
726         return LWS_SSL_CAPABLE_ERROR;
727 }
728
729 LWS_VISIBLE int
730 lws_ssl_close(struct lws *wsi)
731 {
732         int n;
733
734         if (!wsi->ssl)
735                 return 0; /* not handled */
736
737         n = SSL_get_fd(wsi->ssl);
738         SSL_shutdown(wsi->ssl);
739         compatible_close(n);
740         SSL_free(wsi->ssl);
741         wsi->ssl = NULL;
742
743         return 1; /* handled */
744 }
745
746 /* leave all wsi close processing to the caller */
747
748 LWS_VISIBLE int
749 lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
750 {
751         struct lws_context *context = wsi->context;
752         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
753         int n, m;
754 #ifndef USE_WOLFSSL
755         BIO *bio;
756 #endif
757
758         if (!LWS_SSL_ENABLED(wsi->vhost))
759                 return 0;
760
761         switch (wsi->mode) {
762         case LWSCM_SSL_INIT:
763
764                 wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
765                 if (wsi->ssl == NULL) {
766                         lwsl_err("SSL_new failed: %s\n",
767                                  ERR_error_string(SSL_get_error(wsi->ssl, 0), NULL));
768                         lws_decode_ssl_error();
769                         if (accept_fd != LWS_SOCK_INVALID)
770                                 compatible_close(accept_fd);
771                         goto fail;
772                 }
773
774                 SSL_set_ex_data(wsi->ssl,
775                         openssl_websocket_private_data_index, context);
776
777                 SSL_set_fd(wsi->ssl, accept_fd);
778
779 #ifdef USE_WOLFSSL
780 #ifdef USE_OLD_CYASSL
781                 CyaSSL_set_using_nonblock(wsi->ssl, 1);
782 #else
783                 wolfSSL_set_using_nonblock(wsi->ssl, 1);
784 #endif
785 #else
786                 SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
787                 bio = SSL_get_rbio(wsi->ssl);
788                 if (bio)
789                         BIO_set_nbio(bio, 1); /* nonblocking */
790                 else
791                         lwsl_notice("NULL rbio\n");
792                 bio = SSL_get_wbio(wsi->ssl);
793                 if (bio)
794                         BIO_set_nbio(bio, 1); /* nonblocking */
795                 else
796                         lwsl_notice("NULL rbio\n");
797 #endif
798
799                 /*
800                  * we are not accepted yet, but we need to enter ourselves
801                  * as a live connection.  That way we can retry when more
802                  * pieces come if we're not sorted yet
803                  */
804
805                 wsi->mode = LWSCM_SSL_ACK_PENDING;
806                 if (insert_wsi_socket_into_fds(context, wsi))
807                         goto fail;
808
809                 lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT,
810                                 context->timeout_secs);
811
812                 lwsl_info("inserted SSL accept into fds, trying SSL_accept\n");
813
814                 /* fallthru */
815
816         case LWSCM_SSL_ACK_PENDING:
817
818                 if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
819                         goto fail;
820
821                 lws_latency_pre(context, wsi);
822
823                 n = recv(wsi->sock, (char *)pt->serv_buf, LWS_MAX_SOCKET_IO_BUF,
824                          MSG_PEEK);
825
826                 /*
827                  * optionally allow non-SSL connect on SSL listening socket
828                  * This is disabled by default, if enabled it goes around any
829                  * SSL-level access control (eg, client-side certs) so leave
830                  * it disabled unless you know it's not a problem for you
831                  */
832
833                 if (wsi->vhost->allow_non_ssl_on_ssl_port) {
834                         if (n >= 1 && pt->serv_buf[0] >= ' ') {
835                                 /*
836                                 * TLS content-type for Handshake is 0x16, and
837                                 * for ChangeCipherSpec Record, it's 0x14
838                                 *
839                                 * A non-ssl session will start with the HTTP
840                                 * method in ASCII.  If we see it's not a legit
841                                 * SSL handshake kill the SSL for this
842                                 * connection and try to handle as a HTTP
843                                 * connection upgrade directly.
844                                 */
845                                 wsi->use_ssl = 0;
846                                 SSL_shutdown(wsi->ssl);
847                                 SSL_free(wsi->ssl);
848                                 wsi->ssl = NULL;
849                                 if (lws_check_opt(context->options,
850                                     LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS))
851                                         wsi->redirect_to_https = 1;
852                                 goto accepted;
853                         }
854                         if (!n) /*
855                                  * connection is gone, or nothing to read
856                                  * if it's gone, we will timeout on
857                                  * PENDING_TIMEOUT_SSL_ACCEPT
858                                  */
859                                 break;
860                         if (n < 0 && (LWS_ERRNO == LWS_EAGAIN ||
861                                       LWS_ERRNO == LWS_EWOULDBLOCK)) {
862                                 /*
863                                  * well, we get no way to know ssl or not
864                                  * so go around again waiting for something
865                                  * to come and give us a hint, or timeout the
866                                  * connection.
867                                  */
868                                 m = SSL_ERROR_WANT_READ;
869                                 goto go_again;
870                         }
871                 }
872
873                 /* normal SSL connection processing path */
874
875                 n = SSL_accept(wsi->ssl);
876                 lws_latency(context, wsi,
877                         "SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);
878
879                 if (n == 1)
880                         goto accepted;
881
882                 m = SSL_get_error(wsi->ssl, n);
883                 lwsl_debug("SSL_accept failed %d / %s\n",
884                            m, ERR_error_string(m, NULL));
885 go_again:
886                 if (m == SSL_ERROR_WANT_READ) {
887                         if (lws_change_pollfd(wsi, 0, LWS_POLLIN))
888                                 goto fail;
889
890                         lwsl_info("SSL_ERROR_WANT_READ\n");
891                         break;
892                 }
893                 if (m == SSL_ERROR_WANT_WRITE) {
894                         if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
895                                 goto fail;
896
897                         break;
898                 }
899                 lwsl_debug("SSL_accept failed skt %u: %s\n",
900                            wsi->sock, ERR_error_string(m, NULL));
901                 goto fail;
902
903 accepted:
904                 /* OK, we are accepted... give him some time to negotiate */
905                 lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
906                                 context->timeout_secs);
907
908                 wsi->mode = LWSCM_HTTP_SERVING;
909
910                 lws_http2_configure_if_upgraded(wsi);
911
912                 lwsl_debug("accepted new SSL conn\n");
913                 break;
914         }
915
916         return 0;
917
918 fail:
919         return 1;
920 }
921
922 void
923 lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
924 {
925         if (vhost->ssl_ctx)
926                 SSL_CTX_free(vhost->ssl_ctx);
927         if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
928                 SSL_CTX_free(vhost->ssl_client_ctx);
929 }
930
931 void
932 lws_ssl_context_destroy(struct lws_context *context)
933 {
934 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
935         ERR_remove_state(0);
936 #else
937         ERR_remove_thread_state(NULL);
938 #endif
939         ERR_free_strings();
940         EVP_cleanup();
941         CRYPTO_cleanup_all_ex_data();
942 }