1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker */
24*1c60b9acSAndroid Build Coastguard Worker
25*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
26*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-tls-openssl.h"
27*1c60b9acSAndroid Build Coastguard Worker
28*1c60b9acSAndroid Build Coastguard Worker int openssl_websocket_private_data_index,
29*1c60b9acSAndroid Build Coastguard Worker openssl_SSL_CTX_private_data_index;
30*1c60b9acSAndroid Build Coastguard Worker
31*1c60b9acSAndroid Build Coastguard Worker /*
32*1c60b9acSAndroid Build Coastguard Worker * Care: many openssl apis return 1 for success. These are translated to the
33*1c60b9acSAndroid Build Coastguard Worker * lws convention of 0 for success.
34*1c60b9acSAndroid Build Coastguard Worker */
35*1c60b9acSAndroid Build Coastguard Worker
lws_openssl_describe_cipher(struct lws * wsi)36*1c60b9acSAndroid Build Coastguard Worker int lws_openssl_describe_cipher(struct lws *wsi)
37*1c60b9acSAndroid Build Coastguard Worker {
38*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_WITH_NO_LOGS) && !defined(USE_WOLFSSL)
39*1c60b9acSAndroid Build Coastguard Worker int np = -1;
40*1c60b9acSAndroid Build Coastguard Worker SSL *s = wsi->tls.ssl;
41*1c60b9acSAndroid Build Coastguard Worker
42*1c60b9acSAndroid Build Coastguard Worker SSL_get_cipher_bits(s, &np);
43*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: %s: %s, %s, %d bits, %s\n", __func__, lws_wsi_tag(wsi),
44*1c60b9acSAndroid Build Coastguard Worker SSL_get_cipher_name(s), SSL_get_cipher(s), np,
45*1c60b9acSAndroid Build Coastguard Worker SSL_get_cipher_version(s));
46*1c60b9acSAndroid Build Coastguard Worker #endif
47*1c60b9acSAndroid Build Coastguard Worker
48*1c60b9acSAndroid Build Coastguard Worker return 0;
49*1c60b9acSAndroid Build Coastguard Worker }
50*1c60b9acSAndroid Build Coastguard Worker
lws_ssl_get_error(struct lws * wsi,int n)51*1c60b9acSAndroid Build Coastguard Worker int lws_ssl_get_error(struct lws *wsi, int n)
52*1c60b9acSAndroid Build Coastguard Worker {
53*1c60b9acSAndroid Build Coastguard Worker int m;
54*1c60b9acSAndroid Build Coastguard Worker
55*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
56*1c60b9acSAndroid Build Coastguard Worker return 99;
57*1c60b9acSAndroid Build Coastguard Worker
58*1c60b9acSAndroid Build Coastguard Worker m = SSL_get_error(wsi->tls.ssl, n);
59*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: %p %d -> %d (errno %d)\n", __func__, wsi->tls.ssl, n, m, LWS_ERRNO);
60*1c60b9acSAndroid Build Coastguard Worker if (m == SSL_ERROR_SSL)
61*1c60b9acSAndroid Build Coastguard Worker lws_tls_err_describe_clear();
62*1c60b9acSAndroid Build Coastguard Worker
63*1c60b9acSAndroid Build Coastguard Worker // assert (LWS_ERRNO != 9);
64*1c60b9acSAndroid Build Coastguard Worker
65*1c60b9acSAndroid Build Coastguard Worker return m;
66*1c60b9acSAndroid Build Coastguard Worker }
67*1c60b9acSAndroid Build Coastguard Worker
68*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
69*1c60b9acSAndroid Build Coastguard Worker static int
lws_context_init_ssl_pem_passwd_cb(char * buf,int size,int rwflag,void * userdata)70*1c60b9acSAndroid Build Coastguard Worker lws_context_init_ssl_pem_passwd_cb(char *buf, int size, int rwflag,
71*1c60b9acSAndroid Build Coastguard Worker void *userdata)
72*1c60b9acSAndroid Build Coastguard Worker {
73*1c60b9acSAndroid Build Coastguard Worker struct lws_context_creation_info * info =
74*1c60b9acSAndroid Build Coastguard Worker (struct lws_context_creation_info *)userdata;
75*1c60b9acSAndroid Build Coastguard Worker
76*1c60b9acSAndroid Build Coastguard Worker strncpy(buf, info->ssl_private_key_password, (unsigned int)size);
77*1c60b9acSAndroid Build Coastguard Worker buf[size - 1] = '\0';
78*1c60b9acSAndroid Build Coastguard Worker
79*1c60b9acSAndroid Build Coastguard Worker return (int)strlen(buf);
80*1c60b9acSAndroid Build Coastguard Worker }
81*1c60b9acSAndroid Build Coastguard Worker #endif
82*1c60b9acSAndroid Build Coastguard Worker
83*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CLIENT)
84*1c60b9acSAndroid Build Coastguard Worker static int
lws_context_init_ssl_pem_passwd_client_cb(char * buf,int size,int rwflag,void * userdata)85*1c60b9acSAndroid Build Coastguard Worker lws_context_init_ssl_pem_passwd_client_cb(char *buf, int size, int rwflag,
86*1c60b9acSAndroid Build Coastguard Worker void *userdata)
87*1c60b9acSAndroid Build Coastguard Worker {
88*1c60b9acSAndroid Build Coastguard Worker struct lws_context_creation_info * info =
89*1c60b9acSAndroid Build Coastguard Worker (struct lws_context_creation_info *)userdata;
90*1c60b9acSAndroid Build Coastguard Worker const char *p = info->ssl_private_key_password;
91*1c60b9acSAndroid Build Coastguard Worker
92*1c60b9acSAndroid Build Coastguard Worker if (info->client_ssl_private_key_password)
93*1c60b9acSAndroid Build Coastguard Worker p = info->client_ssl_private_key_password;
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard Worker strncpy(buf, p, (unsigned int)size);
96*1c60b9acSAndroid Build Coastguard Worker buf[size - 1] = '\0';
97*1c60b9acSAndroid Build Coastguard Worker
98*1c60b9acSAndroid Build Coastguard Worker return (int)strlen(buf);
99*1c60b9acSAndroid Build Coastguard Worker }
100*1c60b9acSAndroid Build Coastguard Worker #endif
101*1c60b9acSAndroid Build Coastguard Worker
102*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_bind_passphrase(SSL_CTX * ssl_ctx,int is_client,const struct lws_context_creation_info * info)103*1c60b9acSAndroid Build Coastguard Worker lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, int is_client,
104*1c60b9acSAndroid Build Coastguard Worker const struct lws_context_creation_info *info)
105*1c60b9acSAndroid Build Coastguard Worker {
106*1c60b9acSAndroid Build Coastguard Worker if (
107*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
108*1c60b9acSAndroid Build Coastguard Worker !info->ssl_private_key_password
109*1c60b9acSAndroid Build Coastguard Worker #endif
110*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_CLIENT)
111*1c60b9acSAndroid Build Coastguard Worker &&
112*1c60b9acSAndroid Build Coastguard Worker #endif
113*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CLIENT)
114*1c60b9acSAndroid Build Coastguard Worker !info->client_ssl_private_key_password
115*1c60b9acSAndroid Build Coastguard Worker #endif
116*1c60b9acSAndroid Build Coastguard Worker )
117*1c60b9acSAndroid Build Coastguard Worker return;
118*1c60b9acSAndroid Build Coastguard Worker /*
119*1c60b9acSAndroid Build Coastguard Worker * password provided, set ssl callback and user data
120*1c60b9acSAndroid Build Coastguard Worker * for checking password which will be trigered during
121*1c60b9acSAndroid Build Coastguard Worker * SSL_CTX_use_PrivateKey_file function
122*1c60b9acSAndroid Build Coastguard Worker */
123*1c60b9acSAndroid Build Coastguard Worker SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)info);
124*1c60b9acSAndroid Build Coastguard Worker SSL_CTX_set_default_passwd_cb(ssl_ctx, is_client ?
125*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CLIENT)
126*1c60b9acSAndroid Build Coastguard Worker lws_context_init_ssl_pem_passwd_client_cb:
127*1c60b9acSAndroid Build Coastguard Worker #else
128*1c60b9acSAndroid Build Coastguard Worker NULL:
129*1c60b9acSAndroid Build Coastguard Worker #endif
130*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
131*1c60b9acSAndroid Build Coastguard Worker lws_context_init_ssl_pem_passwd_cb
132*1c60b9acSAndroid Build Coastguard Worker #else
133*1c60b9acSAndroid Build Coastguard Worker NULL
134*1c60b9acSAndroid Build Coastguard Worker #endif
135*1c60b9acSAndroid Build Coastguard Worker );
136*1c60b9acSAndroid Build Coastguard Worker }
137*1c60b9acSAndroid Build Coastguard Worker
138*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CLIENT)
139*1c60b9acSAndroid Build Coastguard Worker static void
lws_ssl_destroy_client_ctx(struct lws_vhost * vhost)140*1c60b9acSAndroid Build Coastguard Worker lws_ssl_destroy_client_ctx(struct lws_vhost *vhost)
141*1c60b9acSAndroid Build Coastguard Worker {
142*1c60b9acSAndroid Build Coastguard Worker if (vhost->tls.user_supplied_ssl_ctx || !vhost->tls.ssl_client_ctx)
143*1c60b9acSAndroid Build Coastguard Worker return;
144*1c60b9acSAndroid Build Coastguard Worker
145*1c60b9acSAndroid Build Coastguard Worker if (vhost->tls.tcr && --vhost->tls.tcr->refcount)
146*1c60b9acSAndroid Build Coastguard Worker return;
147*1c60b9acSAndroid Build Coastguard Worker
148*1c60b9acSAndroid Build Coastguard Worker SSL_CTX_free(vhost->tls.ssl_client_ctx);
149*1c60b9acSAndroid Build Coastguard Worker vhost->tls.ssl_client_ctx = NULL;
150*1c60b9acSAndroid Build Coastguard Worker
151*1c60b9acSAndroid Build Coastguard Worker vhost->context->tls.count_client_contexts--;
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard Worker if (vhost->tls.tcr) {
154*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(&vhost->tls.tcr->cc_list);
155*1c60b9acSAndroid Build Coastguard Worker lws_free(vhost->tls.tcr);
156*1c60b9acSAndroid Build Coastguard Worker vhost->tls.tcr = NULL;
157*1c60b9acSAndroid Build Coastguard Worker }
158*1c60b9acSAndroid Build Coastguard Worker }
159*1c60b9acSAndroid Build Coastguard Worker #endif
160*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_destroy(struct lws_vhost * vhost)161*1c60b9acSAndroid Build Coastguard Worker lws_ssl_destroy(struct lws_vhost *vhost)
162*1c60b9acSAndroid Build Coastguard Worker {
163*1c60b9acSAndroid Build Coastguard Worker if (!lws_check_opt(vhost->context->options,
164*1c60b9acSAndroid Build Coastguard Worker LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
165*1c60b9acSAndroid Build Coastguard Worker return;
166*1c60b9acSAndroid Build Coastguard Worker
167*1c60b9acSAndroid Build Coastguard Worker if (vhost->tls.ssl_ctx)
168*1c60b9acSAndroid Build Coastguard Worker SSL_CTX_free(vhost->tls.ssl_ctx);
169*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CLIENT)
170*1c60b9acSAndroid Build Coastguard Worker lws_ssl_destroy_client_ctx(vhost);
171*1c60b9acSAndroid Build Coastguard Worker #endif
172*1c60b9acSAndroid Build Coastguard Worker
173*1c60b9acSAndroid Build Coastguard Worker // after 1.1.0 no need
174*1c60b9acSAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER < 0x10100000)
175*1c60b9acSAndroid Build Coastguard Worker // <= 1.0.1f = old api, 1.0.1g+ = new api
176*1c60b9acSAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER <= 0x1000106f) || defined(USE_WOLFSSL)
177*1c60b9acSAndroid Build Coastguard Worker ERR_remove_state(0);
178*1c60b9acSAndroid Build Coastguard Worker #else
179*1c60b9acSAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x1010005f && \
180*1c60b9acSAndroid Build Coastguard Worker !defined(LIBRESSL_VERSION_NUMBER) && \
181*1c60b9acSAndroid Build Coastguard Worker !defined(OPENSSL_IS_BORINGSSL)
182*1c60b9acSAndroid Build Coastguard Worker ERR_remove_thread_state();
183*1c60b9acSAndroid Build Coastguard Worker #else
184*1c60b9acSAndroid Build Coastguard Worker ERR_remove_thread_state(NULL);
185*1c60b9acSAndroid Build Coastguard Worker #endif
186*1c60b9acSAndroid Build Coastguard Worker #endif
187*1c60b9acSAndroid Build Coastguard Worker /* not needed after 1.1.0 */
188*1c60b9acSAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10002000) && \
189*1c60b9acSAndroid Build Coastguard Worker (OPENSSL_VERSION_NUMBER <= 0x10100000)
190*1c60b9acSAndroid Build Coastguard Worker SSL_COMP_free_compression_methods();
191*1c60b9acSAndroid Build Coastguard Worker #endif
192*1c60b9acSAndroid Build Coastguard Worker ERR_free_strings();
193*1c60b9acSAndroid Build Coastguard Worker EVP_cleanup();
194*1c60b9acSAndroid Build Coastguard Worker CRYPTO_cleanup_all_ex_data();
195*1c60b9acSAndroid Build Coastguard Worker #endif
196*1c60b9acSAndroid Build Coastguard Worker }
197*1c60b9acSAndroid Build Coastguard Worker
198*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_capable_read(struct lws * wsi,unsigned char * buf,size_t len)199*1c60b9acSAndroid Build Coastguard Worker lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, size_t len)
200*1c60b9acSAndroid Build Coastguard Worker {
201*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = wsi->a.context;
202*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
203*1c60b9acSAndroid Build Coastguard Worker int n = 0, m;
204*1c60b9acSAndroid Build Coastguard Worker
205*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
206*1c60b9acSAndroid Build Coastguard Worker return lws_ssl_capable_read_no_ssl(wsi, buf, len);
207*1c60b9acSAndroid Build Coastguard Worker
208*1c60b9acSAndroid Build Coastguard Worker #ifndef WIN32
209*1c60b9acSAndroid Build Coastguard Worker errno = 0;
210*1c60b9acSAndroid Build Coastguard Worker #else
211*1c60b9acSAndroid Build Coastguard Worker WSASetLastError(0);
212*1c60b9acSAndroid Build Coastguard Worker #endif
213*1c60b9acSAndroid Build Coastguard Worker ERR_clear_error();
214*1c60b9acSAndroid Build Coastguard Worker n = SSL_read(wsi->tls.ssl, buf, (int)(ssize_t)len);
215*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_FREERTOS)
216*1c60b9acSAndroid Build Coastguard Worker if (!n && errno == LWS_ENOTCONN) {
217*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: SSL_read ENOTCONN\n", lws_wsi_tag(wsi));
218*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_ERROR;
219*1c60b9acSAndroid Build Coastguard Worker }
220*1c60b9acSAndroid Build Coastguard Worker #endif
221*1c60b9acSAndroid Build Coastguard Worker
222*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: SSL_read says %d\n", lws_wsi_tag(wsi), n);
223*1c60b9acSAndroid Build Coastguard Worker /* manpage: returning 0 means connection shut down
224*1c60b9acSAndroid Build Coastguard Worker *
225*1c60b9acSAndroid Build Coastguard Worker * 2018-09-10: https://github.com/openssl/openssl/issues/1903
226*1c60b9acSAndroid Build Coastguard Worker *
227*1c60b9acSAndroid Build Coastguard Worker * So, in summary, if you get a 0 or -1 return from SSL_read() /
228*1c60b9acSAndroid Build Coastguard Worker * SSL_write(), you should call SSL_get_error():
229*1c60b9acSAndroid Build Coastguard Worker *
230*1c60b9acSAndroid Build Coastguard Worker * - If you get back SSL_ERROR_RETURN_ZERO then you know the connection
231*1c60b9acSAndroid Build Coastguard Worker * has been cleanly shutdown by the peer. To fully close the
232*1c60b9acSAndroid Build Coastguard Worker * connection you may choose to call SSL_shutdown() to send a
233*1c60b9acSAndroid Build Coastguard Worker * close_notify back.
234*1c60b9acSAndroid Build Coastguard Worker *
235*1c60b9acSAndroid Build Coastguard Worker * - If you get back SSL_ERROR_SSL then some kind of internal or
236*1c60b9acSAndroid Build Coastguard Worker * protocol error has occurred. More details will be on the SSL error
237*1c60b9acSAndroid Build Coastguard Worker * queue. You can also call SSL_get_shutdown(). If this indicates a
238*1c60b9acSAndroid Build Coastguard Worker * state of SSL_RECEIVED_SHUTDOWN then you know a fatal alert has
239*1c60b9acSAndroid Build Coastguard Worker * been received from the peer (if it had been a close_notify then
240*1c60b9acSAndroid Build Coastguard Worker * SSL_get_error() would have returned SSL_ERROR_RETURN_ZERO).
241*1c60b9acSAndroid Build Coastguard Worker * SSL_ERROR_SSL is considered fatal - you should not call
242*1c60b9acSAndroid Build Coastguard Worker * SSL_shutdown() in this case.
243*1c60b9acSAndroid Build Coastguard Worker *
244*1c60b9acSAndroid Build Coastguard Worker * - If you get back SSL_ERROR_SYSCALL then some kind of fatal (i.e.
245*1c60b9acSAndroid Build Coastguard Worker * non-retryable) error has occurred in a system call.
246*1c60b9acSAndroid Build Coastguard Worker */
247*1c60b9acSAndroid Build Coastguard Worker if (n <= 0) {
248*1c60b9acSAndroid Build Coastguard Worker m = lws_ssl_get_error(wsi, n);
249*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: ssl err %d errno %d\n", lws_wsi_tag(wsi), m, LWS_ERRNO);
250*1c60b9acSAndroid Build Coastguard Worker if (m == SSL_ERROR_ZERO_RETURN) /* cleanly shut down */
251*1c60b9acSAndroid Build Coastguard Worker goto do_err;
252*1c60b9acSAndroid Build Coastguard Worker
253*1c60b9acSAndroid Build Coastguard Worker /* hm not retryable.. could be 0 size pkt or error */
254*1c60b9acSAndroid Build Coastguard Worker
255*1c60b9acSAndroid Build Coastguard Worker if (m == SSL_ERROR_SSL || m == SSL_ERROR_SYSCALL ||
256*1c60b9acSAndroid Build Coastguard Worker LWS_ERRNO == LWS_ENOTCONN) {
257*1c60b9acSAndroid Build Coastguard Worker
258*1c60b9acSAndroid Build Coastguard Worker /* unclean, eg closed conn */
259*1c60b9acSAndroid Build Coastguard Worker
260*1c60b9acSAndroid Build Coastguard Worker wsi->socket_is_permanently_unusable = 1;
261*1c60b9acSAndroid Build Coastguard Worker do_err:
262*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
263*1c60b9acSAndroid Build Coastguard Worker if (wsi->a.vhost)
264*1c60b9acSAndroid Build Coastguard Worker lws_metric_event(wsi->a.vhost->mt_traffic_rx,
265*1c60b9acSAndroid Build Coastguard Worker METRES_NOGO, 0);
266*1c60b9acSAndroid Build Coastguard Worker #endif
267*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_ERROR;
268*1c60b9acSAndroid Build Coastguard Worker }
269*1c60b9acSAndroid Build Coastguard Worker
270*1c60b9acSAndroid Build Coastguard Worker /* retryable? */
271*1c60b9acSAndroid Build Coastguard Worker
272*1c60b9acSAndroid Build Coastguard Worker if (SSL_want_read(wsi->tls.ssl)) {
273*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: WANT_READ\n", __func__);
274*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: LWS_SSL_CAPABLE_MORE_SERVICE\n", lws_wsi_tag(wsi));
275*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE;
276*1c60b9acSAndroid Build Coastguard Worker }
277*1c60b9acSAndroid Build Coastguard Worker if (SSL_want_write(wsi->tls.ssl)) {
278*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: WANT_WRITE\n", __func__);
279*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: LWS_SSL_CAPABLE_MORE_SERVICE\n", lws_wsi_tag(wsi));
280*1c60b9acSAndroid Build Coastguard Worker wsi->tls_read_wanted_write = 1;
281*1c60b9acSAndroid Build Coastguard Worker lws_callback_on_writable(wsi);
282*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE;
283*1c60b9acSAndroid Build Coastguard Worker }
284*1c60b9acSAndroid Build Coastguard Worker
285*1c60b9acSAndroid Build Coastguard Worker /* keep on trucking it seems */
286*1c60b9acSAndroid Build Coastguard Worker }
287*1c60b9acSAndroid Build Coastguard Worker
288*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_TLS_LOG_PLAINTEXT_RX)
289*1c60b9acSAndroid Build Coastguard Worker /*
290*1c60b9acSAndroid Build Coastguard Worker * If using openssl type tls library, this is the earliest point for all
291*1c60b9acSAndroid Build Coastguard Worker * paths to dump what was received as decrypted data from the tls tunnel
292*1c60b9acSAndroid Build Coastguard Worker */
293*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: len %d\n", __func__, n);
294*1c60b9acSAndroid Build Coastguard Worker lwsl_hexdump_notice(buf, (unsigned int)n);
295*1c60b9acSAndroid Build Coastguard Worker #endif
296*1c60b9acSAndroid Build Coastguard Worker
297*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
298*1c60b9acSAndroid Build Coastguard Worker if (wsi->a.vhost)
299*1c60b9acSAndroid Build Coastguard Worker lws_metric_event(wsi->a.vhost->mt_traffic_rx, METRES_GO, (u_mt_t)n);
300*1c60b9acSAndroid Build Coastguard Worker #endif
301*1c60b9acSAndroid Build Coastguard Worker
302*1c60b9acSAndroid Build Coastguard Worker /*
303*1c60b9acSAndroid Build Coastguard Worker * if it was our buffer that limited what we read,
304*1c60b9acSAndroid Build Coastguard Worker * check if SSL has additional data pending inside SSL buffers.
305*1c60b9acSAndroid Build Coastguard Worker *
306*1c60b9acSAndroid Build Coastguard Worker * Because these won't signal at the network layer with POLLIN
307*1c60b9acSAndroid Build Coastguard Worker * and if we don't realize, this data will sit there forever
308*1c60b9acSAndroid Build Coastguard Worker */
309*1c60b9acSAndroid Build Coastguard Worker if (n != (int)(ssize_t)len)
310*1c60b9acSAndroid Build Coastguard Worker goto bail;
311*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
312*1c60b9acSAndroid Build Coastguard Worker goto bail;
313*1c60b9acSAndroid Build Coastguard Worker
314*1c60b9acSAndroid Build Coastguard Worker if (SSL_pending(wsi->tls.ssl)) {
315*1c60b9acSAndroid Build Coastguard Worker if (lws_dll2_is_detached(&wsi->tls.dll_pending_tls))
316*1c60b9acSAndroid Build Coastguard Worker lws_dll2_add_head(&wsi->tls.dll_pending_tls,
317*1c60b9acSAndroid Build Coastguard Worker &pt->tls.dll_pending_tls_owner);
318*1c60b9acSAndroid Build Coastguard Worker } else
319*1c60b9acSAndroid Build Coastguard Worker __lws_ssl_remove_wsi_from_buffered_list(wsi);
320*1c60b9acSAndroid Build Coastguard Worker
321*1c60b9acSAndroid Build Coastguard Worker return n;
322*1c60b9acSAndroid Build Coastguard Worker bail:
323*1c60b9acSAndroid Build Coastguard Worker lws_ssl_remove_wsi_from_buffered_list(wsi);
324*1c60b9acSAndroid Build Coastguard Worker
325*1c60b9acSAndroid Build Coastguard Worker return n;
326*1c60b9acSAndroid Build Coastguard Worker }
327*1c60b9acSAndroid Build Coastguard Worker
328*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_pending(struct lws * wsi)329*1c60b9acSAndroid Build Coastguard Worker lws_ssl_pending(struct lws *wsi)
330*1c60b9acSAndroid Build Coastguard Worker {
331*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
332*1c60b9acSAndroid Build Coastguard Worker return 0;
333*1c60b9acSAndroid Build Coastguard Worker
334*1c60b9acSAndroid Build Coastguard Worker return SSL_pending(wsi->tls.ssl);
335*1c60b9acSAndroid Build Coastguard Worker }
336*1c60b9acSAndroid Build Coastguard Worker
337*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_capable_write(struct lws * wsi,unsigned char * buf,size_t len)338*1c60b9acSAndroid Build Coastguard Worker lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, size_t len)
339*1c60b9acSAndroid Build Coastguard Worker {
340*1c60b9acSAndroid Build Coastguard Worker int n, m;
341*1c60b9acSAndroid Build Coastguard Worker
342*1c60b9acSAndroid Build Coastguard Worker
343*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_TLS_LOG_PLAINTEXT_TX)
344*1c60b9acSAndroid Build Coastguard Worker /*
345*1c60b9acSAndroid Build Coastguard Worker * If using OpenSSL type tls library, this is the last point for all
346*1c60b9acSAndroid Build Coastguard Worker * paths before sending data into the tls tunnel, where you can dump it
347*1c60b9acSAndroid Build Coastguard Worker * and see what is being sent.
348*1c60b9acSAndroid Build Coastguard Worker */
349*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: len %u\n", __func__, (unsigned int)len);
350*1c60b9acSAndroid Build Coastguard Worker lwsl_hexdump_notice(buf, len);
351*1c60b9acSAndroid Build Coastguard Worker #endif
352*1c60b9acSAndroid Build Coastguard Worker
353*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
354*1c60b9acSAndroid Build Coastguard Worker return lws_ssl_capable_write_no_ssl(wsi, buf, len);
355*1c60b9acSAndroid Build Coastguard Worker
356*1c60b9acSAndroid Build Coastguard Worker errno = 0;
357*1c60b9acSAndroid Build Coastguard Worker ERR_clear_error();
358*1c60b9acSAndroid Build Coastguard Worker n = SSL_write(wsi->tls.ssl, buf, (int)(ssize_t)len);
359*1c60b9acSAndroid Build Coastguard Worker if (n > 0) {
360*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
361*1c60b9acSAndroid Build Coastguard Worker if (wsi->a.vhost)
362*1c60b9acSAndroid Build Coastguard Worker lws_metric_event(wsi->a.vhost->mt_traffic_tx,
363*1c60b9acSAndroid Build Coastguard Worker METRES_GO, (u_mt_t)n);
364*1c60b9acSAndroid Build Coastguard Worker #endif
365*1c60b9acSAndroid Build Coastguard Worker return n;
366*1c60b9acSAndroid Build Coastguard Worker }
367*1c60b9acSAndroid Build Coastguard Worker
368*1c60b9acSAndroid Build Coastguard Worker m = lws_ssl_get_error(wsi, n);
369*1c60b9acSAndroid Build Coastguard Worker if (m != SSL_ERROR_SYSCALL) {
370*1c60b9acSAndroid Build Coastguard Worker if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
371*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: want read\n", __func__);
372*1c60b9acSAndroid Build Coastguard Worker
373*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE;
374*1c60b9acSAndroid Build Coastguard Worker }
375*1c60b9acSAndroid Build Coastguard Worker
376*1c60b9acSAndroid Build Coastguard Worker if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
377*1c60b9acSAndroid Build Coastguard Worker lws_set_blocking_send(wsi);
378*1c60b9acSAndroid Build Coastguard Worker
379*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: want write\n", __func__);
380*1c60b9acSAndroid Build Coastguard Worker
381*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE;
382*1c60b9acSAndroid Build Coastguard Worker }
383*1c60b9acSAndroid Build Coastguard Worker }
384*1c60b9acSAndroid Build Coastguard Worker
385*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s failed: %s\n",__func__, ERR_error_string((unsigned int)m, NULL));
386*1c60b9acSAndroid Build Coastguard Worker lws_tls_err_describe_clear();
387*1c60b9acSAndroid Build Coastguard Worker
388*1c60b9acSAndroid Build Coastguard Worker wsi->socket_is_permanently_unusable = 1;
389*1c60b9acSAndroid Build Coastguard Worker
390*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
391*1c60b9acSAndroid Build Coastguard Worker if (wsi->a.vhost)
392*1c60b9acSAndroid Build Coastguard Worker lws_metric_event(wsi->a.vhost->mt_traffic_tx,
393*1c60b9acSAndroid Build Coastguard Worker METRES_NOGO, 0);
394*1c60b9acSAndroid Build Coastguard Worker #endif
395*1c60b9acSAndroid Build Coastguard Worker
396*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_ERROR;
397*1c60b9acSAndroid Build Coastguard Worker }
398*1c60b9acSAndroid Build Coastguard Worker
399*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_info_callback(const SSL * ssl,int where,int ret)400*1c60b9acSAndroid Build Coastguard Worker lws_ssl_info_callback(const SSL *ssl, int where, int ret)
401*1c60b9acSAndroid Build Coastguard Worker {
402*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi;
403*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context;
404*1c60b9acSAndroid Build Coastguard Worker struct lws_ssl_info si;
405*1c60b9acSAndroid Build Coastguard Worker int fd;
406*1c60b9acSAndroid Build Coastguard Worker
407*1c60b9acSAndroid Build Coastguard Worker #ifndef USE_WOLFSSL
408*1c60b9acSAndroid Build Coastguard Worker context = (struct lws_context *)SSL_CTX_get_ex_data(
409*1c60b9acSAndroid Build Coastguard Worker SSL_get_SSL_CTX(ssl),
410*1c60b9acSAndroid Build Coastguard Worker openssl_SSL_CTX_private_data_index);
411*1c60b9acSAndroid Build Coastguard Worker #else
412*1c60b9acSAndroid Build Coastguard Worker context = (struct lws_context *)SSL_CTX_get_ex_data(
413*1c60b9acSAndroid Build Coastguard Worker SSL_get_SSL_CTX((SSL*) ssl),
414*1c60b9acSAndroid Build Coastguard Worker openssl_SSL_CTX_private_data_index);
415*1c60b9acSAndroid Build Coastguard Worker #endif
416*1c60b9acSAndroid Build Coastguard Worker if (!context)
417*1c60b9acSAndroid Build Coastguard Worker return;
418*1c60b9acSAndroid Build Coastguard Worker
419*1c60b9acSAndroid Build Coastguard Worker fd = SSL_get_fd(ssl);
420*1c60b9acSAndroid Build Coastguard Worker if (fd < 0 || (fd - lws_plat_socket_offset()) < 0)
421*1c60b9acSAndroid Build Coastguard Worker return;
422*1c60b9acSAndroid Build Coastguard Worker
423*1c60b9acSAndroid Build Coastguard Worker wsi = wsi_from_fd(context, fd);
424*1c60b9acSAndroid Build Coastguard Worker if (!wsi)
425*1c60b9acSAndroid Build Coastguard Worker return;
426*1c60b9acSAndroid Build Coastguard Worker
427*1c60b9acSAndroid Build Coastguard Worker if (!(where & wsi->a.vhost->tls.ssl_info_event_mask))
428*1c60b9acSAndroid Build Coastguard Worker return;
429*1c60b9acSAndroid Build Coastguard Worker
430*1c60b9acSAndroid Build Coastguard Worker si.where = where;
431*1c60b9acSAndroid Build Coastguard Worker si.ret = ret;
432*1c60b9acSAndroid Build Coastguard Worker
433*1c60b9acSAndroid Build Coastguard Worker if (user_callback_handle_rxflow(wsi->a.protocol->callback,
434*1c60b9acSAndroid Build Coastguard Worker wsi, LWS_CALLBACK_SSL_INFO,
435*1c60b9acSAndroid Build Coastguard Worker wsi->user_space, &si, 0))
436*1c60b9acSAndroid Build Coastguard Worker lws_set_timeout(wsi, PENDING_TIMEOUT_KILLED_BY_SSL_INFO, -1);
437*1c60b9acSAndroid Build Coastguard Worker }
438*1c60b9acSAndroid Build Coastguard Worker
439*1c60b9acSAndroid Build Coastguard Worker
440*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_close(struct lws * wsi)441*1c60b9acSAndroid Build Coastguard Worker lws_ssl_close(struct lws *wsi)
442*1c60b9acSAndroid Build Coastguard Worker {
443*1c60b9acSAndroid Build Coastguard Worker lws_sockfd_type n;
444*1c60b9acSAndroid Build Coastguard Worker
445*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
446*1c60b9acSAndroid Build Coastguard Worker return 0; /* not handled */
447*1c60b9acSAndroid Build Coastguard Worker
448*1c60b9acSAndroid Build Coastguard Worker #if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
449*1c60b9acSAndroid Build Coastguard Worker /* kill ssl callbacks, because we will remove the fd from the
450*1c60b9acSAndroid Build Coastguard Worker * table linking it to the wsi
451*1c60b9acSAndroid Build Coastguard Worker */
452*1c60b9acSAndroid Build Coastguard Worker if (wsi->a.vhost->tls.ssl_info_event_mask)
453*1c60b9acSAndroid Build Coastguard Worker SSL_set_info_callback(wsi->tls.ssl, NULL);
454*1c60b9acSAndroid Build Coastguard Worker #endif
455*1c60b9acSAndroid Build Coastguard Worker
456*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_TLS_SYNTHESIZE_CB)
457*1c60b9acSAndroid Build Coastguard Worker lws_sul_cancel(&wsi->tls.sul_cb_synth);
458*1c60b9acSAndroid Build Coastguard Worker /*
459*1c60b9acSAndroid Build Coastguard Worker * ... check the session in case it did not live long enough to get
460*1c60b9acSAndroid Build Coastguard Worker * the scheduled callback to sample it
461*1c60b9acSAndroid Build Coastguard Worker */
462*1c60b9acSAndroid Build Coastguard Worker lws_sess_cache_synth_cb(&wsi->tls.sul_cb_synth);
463*1c60b9acSAndroid Build Coastguard Worker #endif
464*1c60b9acSAndroid Build Coastguard Worker
465*1c60b9acSAndroid Build Coastguard Worker n = SSL_get_fd(wsi->tls.ssl);
466*1c60b9acSAndroid Build Coastguard Worker if (!wsi->socket_is_permanently_unusable)
467*1c60b9acSAndroid Build Coastguard Worker SSL_shutdown(wsi->tls.ssl);
468*1c60b9acSAndroid Build Coastguard Worker compatible_close(n);
469*1c60b9acSAndroid Build Coastguard Worker SSL_free(wsi->tls.ssl);
470*1c60b9acSAndroid Build Coastguard Worker wsi->tls.ssl = NULL;
471*1c60b9acSAndroid Build Coastguard Worker
472*1c60b9acSAndroid Build Coastguard Worker lws_tls_restrict_return(wsi);
473*1c60b9acSAndroid Build Coastguard Worker
474*1c60b9acSAndroid Build Coastguard Worker // lwsl_notice("%s: ssl restr %d, simul %d\n", __func__,
475*1c60b9acSAndroid Build Coastguard Worker // wsi->a.context->simultaneous_ssl_restriction,
476*1c60b9acSAndroid Build Coastguard Worker // wsi->a.context->simultaneous_ssl);
477*1c60b9acSAndroid Build Coastguard Worker
478*1c60b9acSAndroid Build Coastguard Worker return 1; /* handled */
479*1c60b9acSAndroid Build Coastguard Worker }
480*1c60b9acSAndroid Build Coastguard Worker
481*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_SSL_CTX_destroy(struct lws_vhost * vhost)482*1c60b9acSAndroid Build Coastguard Worker lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
483*1c60b9acSAndroid Build Coastguard Worker {
484*1c60b9acSAndroid Build Coastguard Worker if (vhost->tls.ssl_ctx)
485*1c60b9acSAndroid Build Coastguard Worker SSL_CTX_free(vhost->tls.ssl_ctx);
486*1c60b9acSAndroid Build Coastguard Worker
487*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CLIENT)
488*1c60b9acSAndroid Build Coastguard Worker lws_ssl_destroy_client_ctx(vhost);
489*1c60b9acSAndroid Build Coastguard Worker #endif
490*1c60b9acSAndroid Build Coastguard Worker
491*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_ACME)
492*1c60b9acSAndroid Build Coastguard Worker lws_tls_acme_sni_cert_destroy(vhost);
493*1c60b9acSAndroid Build Coastguard Worker #endif
494*1c60b9acSAndroid Build Coastguard Worker }
495*1c60b9acSAndroid Build Coastguard Worker
496*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_context_destroy(struct lws_context * context)497*1c60b9acSAndroid Build Coastguard Worker lws_ssl_context_destroy(struct lws_context *context)
498*1c60b9acSAndroid Build Coastguard Worker {
499*1c60b9acSAndroid Build Coastguard Worker // after 1.1.0 no need
500*1c60b9acSAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER < 0x10100000)
501*1c60b9acSAndroid Build Coastguard Worker // <= 1.0.1f = old api, 1.0.1g+ = new api
502*1c60b9acSAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER <= 0x1000106f) || defined(USE_WOLFSSL)
503*1c60b9acSAndroid Build Coastguard Worker ERR_remove_state(0);
504*1c60b9acSAndroid Build Coastguard Worker #else
505*1c60b9acSAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x1010005f && \
506*1c60b9acSAndroid Build Coastguard Worker !defined(LIBRESSL_VERSION_NUMBER) && \
507*1c60b9acSAndroid Build Coastguard Worker !defined(OPENSSL_IS_BORINGSSL)
508*1c60b9acSAndroid Build Coastguard Worker ERR_remove_thread_state();
509*1c60b9acSAndroid Build Coastguard Worker #else
510*1c60b9acSAndroid Build Coastguard Worker ERR_remove_thread_state(NULL);
511*1c60b9acSAndroid Build Coastguard Worker #endif
512*1c60b9acSAndroid Build Coastguard Worker #endif
513*1c60b9acSAndroid Build Coastguard Worker // after 1.1.0 no need
514*1c60b9acSAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10002000) && (OPENSSL_VERSION_NUMBER <= 0x10100000)
515*1c60b9acSAndroid Build Coastguard Worker SSL_COMP_free_compression_methods();
516*1c60b9acSAndroid Build Coastguard Worker #endif
517*1c60b9acSAndroid Build Coastguard Worker ERR_free_strings();
518*1c60b9acSAndroid Build Coastguard Worker EVP_cleanup();
519*1c60b9acSAndroid Build Coastguard Worker CRYPTO_cleanup_all_ex_data();
520*1c60b9acSAndroid Build Coastguard Worker #endif
521*1c60b9acSAndroid Build Coastguard Worker }
522*1c60b9acSAndroid Build Coastguard Worker
523*1c60b9acSAndroid Build Coastguard Worker lws_tls_ctx *
lws_tls_ctx_from_wsi(struct lws * wsi)524*1c60b9acSAndroid Build Coastguard Worker lws_tls_ctx_from_wsi(struct lws *wsi)
525*1c60b9acSAndroid Build Coastguard Worker {
526*1c60b9acSAndroid Build Coastguard Worker if (!wsi->tls.ssl)
527*1c60b9acSAndroid Build Coastguard Worker return NULL;
528*1c60b9acSAndroid Build Coastguard Worker
529*1c60b9acSAndroid Build Coastguard Worker return SSL_get_SSL_CTX(wsi->tls.ssl);
530*1c60b9acSAndroid Build Coastguard Worker }
531*1c60b9acSAndroid Build Coastguard Worker
532*1c60b9acSAndroid Build Coastguard Worker enum lws_ssl_capable_status
__lws_tls_shutdown(struct lws * wsi)533*1c60b9acSAndroid Build Coastguard Worker __lws_tls_shutdown(struct lws *wsi)
534*1c60b9acSAndroid Build Coastguard Worker {
535*1c60b9acSAndroid Build Coastguard Worker int n;
536*1c60b9acSAndroid Build Coastguard Worker
537*1c60b9acSAndroid Build Coastguard Worker #ifndef WIN32
538*1c60b9acSAndroid Build Coastguard Worker errno = 0;
539*1c60b9acSAndroid Build Coastguard Worker #else
540*1c60b9acSAndroid Build Coastguard Worker WSASetLastError(0);
541*1c60b9acSAndroid Build Coastguard Worker #endif
542*1c60b9acSAndroid Build Coastguard Worker ERR_clear_error();
543*1c60b9acSAndroid Build Coastguard Worker n = SSL_shutdown(wsi->tls.ssl);
544*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd);
545*1c60b9acSAndroid Build Coastguard Worker switch (n) {
546*1c60b9acSAndroid Build Coastguard Worker case 1: /* successful completion */
547*1c60b9acSAndroid Build Coastguard Worker n = shutdown(wsi->desc.sockfd, SHUT_WR);
548*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_DONE;
549*1c60b9acSAndroid Build Coastguard Worker
550*1c60b9acSAndroid Build Coastguard Worker case 0: /* needs a retry */
551*1c60b9acSAndroid Build Coastguard Worker __lws_change_pollfd(wsi, 0, LWS_POLLIN);
552*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE;
553*1c60b9acSAndroid Build Coastguard Worker
554*1c60b9acSAndroid Build Coastguard Worker default: /* fatal error, or WANT */
555*1c60b9acSAndroid Build Coastguard Worker n = SSL_get_error(wsi->tls.ssl, n);
556*1c60b9acSAndroid Build Coastguard Worker if (n != SSL_ERROR_SYSCALL && n != SSL_ERROR_SSL) {
557*1c60b9acSAndroid Build Coastguard Worker if (SSL_want_read(wsi->tls.ssl)) {
558*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("(wants read)\n");
559*1c60b9acSAndroid Build Coastguard Worker __lws_change_pollfd(wsi, 0, LWS_POLLIN);
560*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
561*1c60b9acSAndroid Build Coastguard Worker }
562*1c60b9acSAndroid Build Coastguard Worker if (SSL_want_write(wsi->tls.ssl)) {
563*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("(wants write)\n");
564*1c60b9acSAndroid Build Coastguard Worker __lws_change_pollfd(wsi, 0, LWS_POLLOUT);
565*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
566*1c60b9acSAndroid Build Coastguard Worker }
567*1c60b9acSAndroid Build Coastguard Worker }
568*1c60b9acSAndroid Build Coastguard Worker return LWS_SSL_CAPABLE_ERROR;
569*1c60b9acSAndroid Build Coastguard Worker }
570*1c60b9acSAndroid Build Coastguard Worker }
571*1c60b9acSAndroid Build Coastguard Worker
572*1c60b9acSAndroid Build Coastguard Worker
573*1c60b9acSAndroid Build Coastguard Worker static int
tops_fake_POLLIN_for_buffered_openssl(struct lws_context_per_thread * pt)574*1c60b9acSAndroid Build Coastguard Worker tops_fake_POLLIN_for_buffered_openssl(struct lws_context_per_thread *pt)
575*1c60b9acSAndroid Build Coastguard Worker {
576*1c60b9acSAndroid Build Coastguard Worker return lws_tls_fake_POLLIN_for_buffered(pt);
577*1c60b9acSAndroid Build Coastguard Worker }
578*1c60b9acSAndroid Build Coastguard Worker
579*1c60b9acSAndroid Build Coastguard Worker const struct lws_tls_ops tls_ops_openssl = {
580*1c60b9acSAndroid Build Coastguard Worker /* fake_POLLIN_for_buffered */ tops_fake_POLLIN_for_buffered_openssl,
581*1c60b9acSAndroid Build Coastguard Worker };
582