multithreaded service
[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 int openssl_websocket_private_data_index;
28
29 static int
30 lws_context_init_ssl_pem_passwd_cb(char * buf, int size, int rwflag, void *userdata)
31 {
32         struct lws_context_creation_info * info =
33                         (struct lws_context_creation_info *)userdata;
34
35         strncpy(buf, info->ssl_private_key_password, size);
36         buf[size - 1] = '\0';
37
38         return strlen(buf);
39 }
40
41 static void lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, struct lws_context_creation_info *info)
42 {
43         if (!info->ssl_private_key_password)
44                 return;
45         /*
46          * password provided, set ssl callback and user data
47          * for checking password which will be trigered during
48          * SSL_CTX_use_PrivateKey_file function
49          */
50         SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)info);
51         SSL_CTX_set_default_passwd_cb(ssl_ctx, lws_context_init_ssl_pem_passwd_cb);
52 }
53
54 #ifndef LWS_NO_SERVER
55 static int
56 OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
57 {
58         SSL *ssl;
59         int n;
60         struct lws_context *context;
61         struct lws wsi;
62
63         ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
64                 SSL_get_ex_data_X509_STORE_CTX_idx());
65
66         /*
67          * !!! nasty openssl requires the index to come as a library-scope
68          * static
69          */
70         context = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
71
72         /*
73          * give him a fake wsi with context set, so he can use lws_get_context()
74          * in the callback
75          */
76         memset(&wsi, 0, sizeof(wsi));
77         wsi.context = context;
78
79         n = context->protocols[0].callback(&wsi,
80                         LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
81                                            x509_ctx, ssl, preverify_ok);
82
83         /* convert return code from 0 = OK to 1 = OK */
84         return !n;
85 }
86
87 LWS_VISIBLE int
88 lws_context_init_server_ssl(struct lws_context_creation_info *info,
89                             struct lws_context *context)
90 {
91         SSL_METHOD *method;
92         struct lws wsi;
93         int error;
94         int n;
95 #ifdef LWS_SSL_SERVER_WITH_ECDH_CERT
96         int KeyType;
97         EC_KEY *EC_key = NULL;
98         X509 *x;
99         EVP_PKEY *pkey;
100 #endif
101
102         if (info->port != CONTEXT_PORT_NO_LISTEN) {
103
104                 context->use_ssl = info->ssl_cert_filepath != NULL;
105
106 #ifdef USE_WOLFSSL
107 #ifdef USE_OLD_CYASSL
108                 lwsl_notice(" Compiled with CyaSSL support\n");
109 #else
110                 lwsl_notice(" Compiled with wolfSSL support\n");
111 #endif
112 #else
113                 lwsl_notice(" Compiled with OpenSSL support\n");
114 #endif
115
116                 if (info->ssl_cipher_list)
117                         lwsl_notice(" SSL ciphers: '%s'\n", info->ssl_cipher_list);
118
119                 if (context->use_ssl)
120                         lwsl_notice(" Using SSL mode\n");
121                 else
122                         lwsl_notice(" Using non-SSL mode\n");
123         }
124
125         /*
126          * give him a fake wsi with context set, so he can use
127          * lws_get_context() in the callback
128          */
129         memset(&wsi, 0, sizeof(wsi));
130         wsi.context = context;
131
132         /* basic openssl init */
133
134         SSL_library_init();
135
136         OpenSSL_add_all_algorithms();
137         SSL_load_error_strings();
138
139         openssl_websocket_private_data_index =
140                 SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);
141
142         /*
143          * Firefox insists on SSLv23 not SSLv3
144          * Konq disables SSLv2 by default now, SSLv23 works
145          *
146          * SSLv23_server_method() is the openssl method for "allow all TLS
147          * versions", compared to e.g. TLSv1_2_server_method() which only allows
148          * tlsv1.2. Unwanted versions must be disabled using SSL_CTX_set_options()
149          */
150
151         method = (SSL_METHOD *)SSLv23_server_method();
152         if (!method) {
153                 error = ERR_get_error();
154                 lwsl_err("problem creating ssl method %lu: %s\n",
155                         error, ERR_error_string(error,
156                                               (char *)context->pt[0].serv_buf));
157                 return 1;
158         }
159         context->ssl_ctx = SSL_CTX_new(method); /* create context */
160         if (!context->ssl_ctx) {
161                 error = ERR_get_error();
162                 lwsl_err("problem creating ssl context %lu: %s\n",
163                         error, ERR_error_string(error,
164                                               (char *)context->pt[0].serv_buf));
165                 return 1;
166         }
167
168         /* Disable SSLv2 and SSLv3 */
169         SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
170 #ifdef SSL_OP_NO_COMPRESSION
171         SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_COMPRESSION);
172 #endif
173         SSL_CTX_set_options(context->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
174         if (info->ssl_cipher_list)
175                 SSL_CTX_set_cipher_list(context->ssl_ctx,
176                                                 info->ssl_cipher_list);
177
178         /* as a server, are we requiring clients to identify themselves? */
179
180         if (info->options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
181                 int verify_options = SSL_VERIFY_PEER;
182
183                 if (!(info->options & LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
184                         verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
185
186                 SSL_CTX_set_session_id_context(context->ssl_ctx,
187                                 (unsigned char *)context, sizeof(void *));
188
189                 /* absolutely require the client cert */
190
191                 SSL_CTX_set_verify(context->ssl_ctx,
192                        verify_options, OpenSSL_verify_callback);
193
194                 /*
195                  * give user code a chance to load certs into the server
196                  * allowing it to verify incoming client certs
197                  */
198
199                 context->protocols[0].callback(&wsi,
200                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
201                                                context->ssl_ctx, NULL, 0);
202         }
203
204         if (info->options & LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT)
205                 /* Normally SSL listener rejects non-ssl, optionally allow */
206                 context->allow_non_ssl_on_ssl_port = 1;
207
208         if (context->use_ssl) {
209                 /* openssl init for server sockets */
210
211                 /* set the local certificate from CertFile */
212                 n = SSL_CTX_use_certificate_chain_file(context->ssl_ctx,
213                                         info->ssl_cert_filepath);
214                 if (n != 1) {
215                         error = ERR_get_error();
216                         lwsl_err("problem getting cert '%s' %lu: %s\n",
217                                 info->ssl_cert_filepath,
218                                 error,
219                                 ERR_error_string(error,
220                                               (char *)context->pt[0].serv_buf));
221                         return 1;
222                 }
223                 lws_ssl_bind_passphrase(context->ssl_ctx, info);
224
225                 if (info->ssl_private_key_filepath != NULL) {
226                         /* set the private key from KeyFile */
227                         if (SSL_CTX_use_PrivateKey_file(context->ssl_ctx,
228                                      info->ssl_private_key_filepath,
229                                                        SSL_FILETYPE_PEM) != 1) {
230                                 error = ERR_get_error();
231                                 lwsl_err("ssl problem getting key '%s' %lu: %s\n",
232                                          info->ssl_private_key_filepath, error,
233                                          ERR_error_string(error,
234                                               (char *)context->pt[0].serv_buf));
235                                 return 1;
236                         }
237                 } else
238                         if (context->protocols[0].callback(&wsi,
239                                 LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
240                                                 context->ssl_ctx, NULL, 0)) {
241                                 lwsl_err("ssl private key not set\n");
242
243                                 return 1;
244                         }
245
246                 /* verify private key */
247                 if (!SSL_CTX_check_private_key(context->ssl_ctx)) {
248                         lwsl_err("Private SSL key doesn't match cert\n");
249                         return 1;
250                 }
251
252 #ifdef LWS_SSL_SERVER_WITH_ECDH_CERT
253                 if (context->options & LWS_SERVER_OPTION_SSL_ECDH) {
254                         lwsl_notice(" Using ECDH certificate support\n");
255
256                         /* Get X509 certificate from ssl context */
257                         x = sk_X509_value(context->ssl_ctx->extra_certs, 0);
258                         /* Get the public key from certificate */
259                         pkey = X509_get_pubkey(x);
260                         /* Get the key type */
261                         KeyType = EVP_PKEY_type(pkey->type);
262
263                         if (EVP_PKEY_EC != KeyType) {
264                                 lwsl_err("Key type is not EC\n");
265                                 return 1;
266                         }
267                         /* Get the key */
268                         EC_key = EVP_PKEY_get1_EC_KEY(pkey);
269                         /* Set ECDH parameter */
270                         if (!EC_key) {
271                                 error = ERR_get_error();
272                                 lwsl_err("ECDH key is NULL \n");
273                                 return 1;
274                         }
275                         SSL_CTX_set_tmp_ecdh(context->ssl_ctx, EC_key);
276                         EC_KEY_free(EC_key);
277                 }
278 #endif
279
280                 /*
281                  * SSL is happy and has a cert it's content with
282                  * If we're supporting HTTP2, initialize that
283                  */
284
285                 lws_context_init_http2_ssl(context);
286         }
287
288         return 0;
289 }
290 #endif
291
292 LWS_VISIBLE void
293 lws_ssl_destroy(struct lws_context *context)
294 {
295         if (context->ssl_ctx)
296                 SSL_CTX_free(context->ssl_ctx);
297         if (!context->user_supplied_ssl_ctx && context->ssl_client_ctx)
298                 SSL_CTX_free(context->ssl_client_ctx);
299
300 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
301         ERR_remove_state(0);
302 #else
303         ERR_remove_thread_state(NULL);
304 #endif
305         ERR_free_strings();
306         EVP_cleanup();
307         CRYPTO_cleanup_all_ex_data();
308 }
309
310 LWS_VISIBLE void
311 lws_decode_ssl_error(void)
312 {
313         char buf[256];
314         u_long err;
315
316         while ((err = ERR_get_error()) != 0) {
317                 ERR_error_string_n(err, buf, sizeof(buf));
318                 lwsl_err("*** %lu %s\n", err, buf);
319         }
320 }
321
322 #ifndef LWS_NO_CLIENT
323
324 int lws_context_init_client_ssl(struct lws_context_creation_info *info,
325                                 struct lws_context *context)
326 {
327         int error;
328         int n;
329         SSL_METHOD *method;
330         struct lws wsi;
331
332         if (info->provided_client_ssl_ctx) {
333                 /* use the provided OpenSSL context if given one */
334                 context->ssl_client_ctx = info->provided_client_ssl_ctx;
335                 /* nothing for lib to delete */
336                 context->user_supplied_ssl_ctx = 1;
337                 return 0;
338         }
339
340         if (info->port != CONTEXT_PORT_NO_LISTEN)
341                 return 0;
342
343         /* basic openssl init */
344
345         SSL_library_init();
346
347         OpenSSL_add_all_algorithms();
348         SSL_load_error_strings();
349
350         method = (SSL_METHOD *)SSLv23_client_method();
351         if (!method) {
352                 error = ERR_get_error();
353                 lwsl_err("problem creating ssl method %lu: %s\n",
354                         error, ERR_error_string(error,
355                                       (char *)context->pt[0].serv_buf));
356                 return 1;
357         }
358         /* create context */
359         context->ssl_client_ctx = SSL_CTX_new(method);
360         if (!context->ssl_client_ctx) {
361                 error = ERR_get_error();
362                 lwsl_err("problem creating ssl context %lu: %s\n",
363                         error, ERR_error_string(error,
364                                       (char *)context->pt[0].serv_buf));
365                 return 1;
366         }
367
368 #ifdef SSL_OP_NO_COMPRESSION
369         SSL_CTX_set_options(context->ssl_client_ctx,
370                                                  SSL_OP_NO_COMPRESSION);
371 #endif
372         SSL_CTX_set_options(context->ssl_client_ctx,
373                                        SSL_OP_CIPHER_SERVER_PREFERENCE);
374         if (info->ssl_cipher_list)
375                 SSL_CTX_set_cipher_list(context->ssl_client_ctx,
376                                                 info->ssl_cipher_list);
377
378 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
379         if (!(info->options & LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
380                 /* loads OS default CA certs */
381                 SSL_CTX_set_default_verify_paths(context->ssl_client_ctx);
382 #endif
383
384         /* openssl init for cert verification (for client sockets) */
385         if (!info->ssl_ca_filepath) {
386                 if (!SSL_CTX_load_verify_locations(
387                         context->ssl_client_ctx, NULL,
388                                              LWS_OPENSSL_CLIENT_CERTS))
389                         lwsl_err(
390                             "Unable to load SSL Client certs from %s "
391                             "(set by --with-client-cert-dir= "
392                             "in configure) --  client ssl isn't "
393                             "going to work", LWS_OPENSSL_CLIENT_CERTS);
394         } else
395                 if (!SSL_CTX_load_verify_locations(
396                         context->ssl_client_ctx, info->ssl_ca_filepath,
397                                                           NULL))
398                         lwsl_err(
399                                 "Unable to load SSL Client certs "
400                                 "file from %s -- client ssl isn't "
401                                 "going to work", info->ssl_ca_filepath);
402                 else
403                         lwsl_info("loaded ssl_ca_filepath\n");
404
405         /*
406          * callback allowing user code to load extra verification certs
407          * helping the client to verify server identity
408          */
409
410         /* support for client-side certificate authentication */
411         if (info->ssl_cert_filepath) {
412                 n = SSL_CTX_use_certificate_chain_file(context->ssl_client_ctx,
413                                                        info->ssl_cert_filepath);
414                 if (n != 1) {
415                         lwsl_err("problem getting cert '%s' %lu: %s\n",
416                                 info->ssl_cert_filepath,
417                                 ERR_get_error(),
418                                 ERR_error_string(ERR_get_error(),
419                                 (char *)context->pt[0].serv_buf));
420                         return 1;
421                 }
422         }
423         if (info->ssl_private_key_filepath) {
424                 lws_ssl_bind_passphrase(context->ssl_client_ctx, info);
425                 /* set the private key from KeyFile */
426                 if (SSL_CTX_use_PrivateKey_file(context->ssl_client_ctx,
427                     info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
428                         lwsl_err("use_PrivateKey_file '%s' %lu: %s\n",
429                                 info->ssl_private_key_filepath,
430                                 ERR_get_error(),
431                                 ERR_error_string(ERR_get_error(),
432                                       (char *)context->pt[0].serv_buf));
433                         return 1;
434                 }
435
436                 /* verify private key */
437                 if (!SSL_CTX_check_private_key(context->ssl_client_ctx)) {
438                         lwsl_err("Private SSL key doesn't match cert\n");
439                         return 1;
440                 }
441         }
442
443         /*
444          * give him a fake wsi with context set, so he can use
445          * lws_get_context() in the callback
446          */
447         memset(&wsi, 0, sizeof(wsi));
448         wsi.context = context;
449
450         context->protocols[0].callback(&wsi,
451                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
452                                        context->ssl_client_ctx, NULL, 0);
453
454         return 0;
455 }
456 #endif
457
458 LWS_VISIBLE void
459 lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi)
460 {
461         struct lws_context *context = wsi->context;
462         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
463
464         if (!wsi->pending_read_list_prev &&
465             !wsi->pending_read_list_next &&
466             pt->pending_read_list != wsi)
467                 /* we are not on the list */
468                 return;
469
470         /* point previous guy's next to our next */
471         if (!wsi->pending_read_list_prev)
472                 pt->pending_read_list = wsi->pending_read_list_next;
473         else
474                 wsi->pending_read_list_prev->pending_read_list_next =
475                         wsi->pending_read_list_next;
476
477         /* point next guy's previous to our previous */
478         if (wsi->pending_read_list_next)
479                 wsi->pending_read_list_next->pending_read_list_prev =
480                         wsi->pending_read_list_prev;
481
482         wsi->pending_read_list_prev = NULL;
483         wsi->pending_read_list_next = NULL;
484 }
485
486 LWS_VISIBLE int
487 lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
488 {
489         struct lws_context *context = wsi->context;
490         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
491         int n;
492
493         if (!wsi->ssl)
494                 return lws_ssl_capable_read_no_ssl(wsi, buf, len);
495
496         n = SSL_read(wsi->ssl, buf, len);
497         /* manpage: returning 0 means connection shut down */
498         if (!n)
499                 return LWS_SSL_CAPABLE_ERROR;
500
501         if (n < 0) {
502                 n = SSL_get_error(wsi->ssl, n);
503                 if (n ==  SSL_ERROR_WANT_READ || n ==  SSL_ERROR_WANT_WRITE)
504                         return LWS_SSL_CAPABLE_MORE_SERVICE;
505
506                 return LWS_SSL_CAPABLE_ERROR;
507         }
508
509         /*
510          * if it was our buffer that limited what we read,
511          * check if SSL has additional data pending inside SSL buffers.
512          *
513          * Because these won't signal at the network layer with POLLIN
514          * and if we don't realize, this data will sit there forever
515          */
516         if (n != len)
517                 goto bail;
518         if (!wsi->ssl)
519                 goto bail;
520         if (!SSL_pending(wsi->ssl))
521                 goto bail;
522         if (wsi->pending_read_list_next)
523                 return n;
524         if (wsi->pending_read_list_prev)
525                 return n;
526         if (pt->pending_read_list == wsi)
527                 return n;
528
529         /* add us to the linked list of guys with pending ssl */
530         if (pt->pending_read_list)
531                 pt->pending_read_list->pending_read_list_prev = wsi;
532
533         wsi->pending_read_list_next = pt->pending_read_list;
534         wsi->pending_read_list_prev = NULL;
535         pt->pending_read_list = wsi;
536
537         return n;
538 bail:
539         lws_ssl_remove_wsi_from_buffered_list(wsi);
540
541         return n;
542 }
543
544 LWS_VISIBLE int
545 lws_ssl_pending(struct lws *wsi)
546 {
547         if (!wsi->ssl)
548                 return 0;
549
550         return SSL_pending(wsi->ssl);
551 }
552
553 LWS_VISIBLE int
554 lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
555 {
556         int n;
557
558         if (!wsi->ssl)
559                 return lws_ssl_capable_write_no_ssl(wsi, buf, len);
560
561         n = SSL_write(wsi->ssl, buf, len);
562         if (n > 0)
563                 return n;
564
565         n = SSL_get_error(wsi->ssl, n);
566         if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE) {
567                 if (n == SSL_ERROR_WANT_WRITE)
568                         lws_set_blocking_send(wsi);
569                 return LWS_SSL_CAPABLE_MORE_SERVICE;
570         }
571
572         return LWS_SSL_CAPABLE_ERROR;
573 }
574
575 LWS_VISIBLE int
576 lws_ssl_close(struct lws *wsi)
577 {
578         int n;
579
580         if (!wsi->ssl)
581                 return 0; /* not handled */
582
583         n = SSL_get_fd(wsi->ssl);
584         SSL_shutdown(wsi->ssl);
585         compatible_close(n);
586         SSL_free(wsi->ssl);
587         wsi->ssl = NULL;
588
589         return 1; /* handled */
590 }
591
592 /* leave all wsi close processing to the caller */
593
594 LWS_VISIBLE int
595 lws_server_socket_service_ssl(struct lws **pwsi, struct lws *new_wsi,
596                               lws_sockfd_type accept_fd,
597                               struct lws_pollfd *pollfd)
598 {
599         struct lws *wsi = *pwsi;
600         struct lws_context *context = wsi->context;
601         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
602         int n, m;
603 #ifndef USE_WOLFSSL
604         BIO *bio;
605 #endif
606
607         if (!LWS_SSL_ENABLED(context))
608                 return 0;
609
610         switch (wsi->mode) {
611         case LWSCM_SERVER_LISTENER:
612
613                 if (!new_wsi) {
614                         lwsl_err("no new_wsi\n");
615                         return 0;
616                 }
617
618                 new_wsi->ssl = SSL_new(context->ssl_ctx);
619                 if (new_wsi->ssl == NULL) {
620                         lwsl_err("SSL_new failed: %s\n",
621                                  ERR_error_string(SSL_get_error(new_wsi->ssl, 0), NULL));
622                         lws_decode_ssl_error();
623                         compatible_close(accept_fd);
624                         goto fail;
625                 }
626
627                 SSL_set_ex_data(new_wsi->ssl,
628                         openssl_websocket_private_data_index, context);
629
630                 SSL_set_fd(new_wsi->ssl, accept_fd);
631
632 #ifdef USE_WOLFSSL
633 #ifdef USE_OLD_CYASSL
634                 CyaSSL_set_using_nonblock(new_wsi->ssl, 1);
635 #else
636                 wolfSSL_set_using_nonblock(new_wsi->ssl, 1);
637 #endif
638 #else
639                 SSL_set_mode(new_wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
640                 bio = SSL_get_rbio(new_wsi->ssl);
641                 if (bio)
642                         BIO_set_nbio(bio, 1); /* nonblocking */
643                 else
644                         lwsl_notice("NULL rbio\n");
645                 bio = SSL_get_wbio(new_wsi->ssl);
646                 if (bio)
647                         BIO_set_nbio(bio, 1); /* nonblocking */
648                 else
649                         lwsl_notice("NULL rbio\n");
650 #endif
651
652                 /*
653                  * we are not accepted yet, but we need to enter ourselves
654                  * as a live connection.  That way we can retry when more
655                  * pieces come if we're not sorted yet
656                  */
657
658                 *pwsi = new_wsi;
659                 wsi = *pwsi;
660                 wsi->mode = LWSCM_SSL_ACK_PENDING;
661                 if (insert_wsi_socket_into_fds(context, wsi))
662                         goto fail;
663
664                 lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT,
665                                                         AWAITING_TIMEOUT);
666
667                 lwsl_info("inserted SSL accept into fds, trying SSL_accept\n");
668
669                 /* fallthru */
670
671         case LWSCM_SSL_ACK_PENDING:
672
673                 if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
674                         goto fail;
675
676                 lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_WRITE);
677
678                 lws_latency_pre(context, wsi);
679
680                 n = recv(wsi->sock, (char *)pt->serv_buf, LWS_MAX_SOCKET_IO_BUF,
681                          MSG_PEEK);
682
683                 /*
684                  * optionally allow non-SSL connect on SSL listening socket
685                  * This is disabled by default, if enabled it goes around any
686                  * SSL-level access control (eg, client-side certs) so leave
687                  * it disabled unless you know it's not a problem for you
688                  */
689
690                 if (context->allow_non_ssl_on_ssl_port) {
691                         if (n >= 1 && pt->serv_buf[0] >= ' ') {
692                                 /*
693                                 * TLS content-type for Handshake is 0x16, and
694                                 * for ChangeCipherSpec Record, it's 0x14
695                                 *
696                                 * A non-ssl session will start with the HTTP
697                                 * method in ASCII.  If we see it's not a legit
698                                 * SSL handshake kill the SSL for this
699                                 * connection and try to handle as a HTTP
700                                 * connection upgrade directly.
701                                 */
702                                 wsi->use_ssl = 0;
703                                 SSL_shutdown(wsi->ssl);
704                                 SSL_free(wsi->ssl);
705                                 wsi->ssl = NULL;
706                                 goto accepted;
707                         }
708                         if (!n) /*
709                                  * connection is gone, or nothing to read
710                                  * if it's gone, we will timeout on
711                                  * PENDING_TIMEOUT_SSL_ACCEPT
712                                  */
713                                 break;
714                         if (n < 0 && (LWS_ERRNO == LWS_EAGAIN ||
715                                       LWS_ERRNO == LWS_EWOULDBLOCK)) {
716                                 /*
717                                  * well, we get no way to know ssl or not
718                                  * so go around again waiting for something
719                                  * to come and give us a hint, or timeout the
720                                  * connection.
721                                  */
722                                 m = SSL_ERROR_WANT_READ;
723                                 goto go_again;
724                         }
725                 }
726
727                 /* normal SSL connection processing path */
728
729                 n = SSL_accept(wsi->ssl);
730                 lws_latency(context, wsi,
731                         "SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);
732
733                 if (n == 1)
734                         goto accepted;
735
736                 m = SSL_get_error(wsi->ssl, n);
737                 lwsl_debug("SSL_accept failed %d / %s\n",
738                            m, ERR_error_string(m, NULL));
739 go_again:
740                 if (m == SSL_ERROR_WANT_READ) {
741                         if (lws_change_pollfd(wsi, 0, LWS_POLLIN))
742                                 goto fail;
743
744                         lws_libev_io(wsi, LWS_EV_START | LWS_EV_READ);
745
746                         lwsl_info("SSL_ERROR_WANT_READ\n");
747                         break;
748                 }
749                 if (m == SSL_ERROR_WANT_WRITE) {
750                         if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
751                                 goto fail;
752
753                         lws_libev_io(wsi, LWS_EV_START | LWS_EV_WRITE);
754                         break;
755                 }
756                 lwsl_debug("SSL_accept failed skt %u: %s\n",
757                            pollfd->fd, ERR_error_string(m, NULL));
758                 goto fail;
759
760 accepted:
761                 /* OK, we are accepted... give him some time to negotiate */
762                 lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
763                                 AWAITING_TIMEOUT);
764
765                 wsi->mode = LWSCM_HTTP_SERVING;
766
767                 lws_http2_configure_if_upgraded(wsi);
768
769                 lwsl_debug("accepted new SSL conn\n");
770                 break;
771         }
772
773         return 0;
774
775 fail:
776         return 1;
777 }
778
779 LWS_VISIBLE void
780 lws_ssl_context_destroy(struct lws_context *context)
781 {
782         if (context->ssl_ctx)
783                 SSL_CTX_free(context->ssl_ctx);
784         if (!context->user_supplied_ssl_ctx && context->ssl_client_ctx)
785                 SSL_CTX_free(context->ssl_client_ctx);
786
787 #if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
788         ERR_remove_state(0);
789 #else
790         ERR_remove_thread_state(NULL);
791 #endif
792         ERR_free_strings();
793         EVP_cleanup();
794         CRYPTO_cleanup_all_ex_data();
795 }