xref: /aosp_15_r20/external/libwebsockets/lib/tls/mbedtls/mbedtls-ssl.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
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-mbedtls.h"
27*1c60b9acSAndroid Build Coastguard Worker 
28*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_destroy(struct lws_vhost * vhost)29*1c60b9acSAndroid Build Coastguard Worker lws_ssl_destroy(struct lws_vhost *vhost)
30*1c60b9acSAndroid Build Coastguard Worker {
31*1c60b9acSAndroid Build Coastguard Worker 	if (!lws_check_opt(vhost->context->options,
32*1c60b9acSAndroid Build Coastguard Worker 			   LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
33*1c60b9acSAndroid Build Coastguard Worker 		return;
34*1c60b9acSAndroid Build Coastguard Worker 
35*1c60b9acSAndroid Build Coastguard Worker 	if (vhost->tls.ssl_ctx)
36*1c60b9acSAndroid Build Coastguard Worker 		SSL_CTX_free(vhost->tls.ssl_ctx);
37*1c60b9acSAndroid Build Coastguard Worker 	if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
38*1c60b9acSAndroid Build Coastguard Worker 		SSL_CTX_free(vhost->tls.ssl_client_ctx);
39*1c60b9acSAndroid Build Coastguard Worker 
40*1c60b9acSAndroid Build Coastguard Worker 	if (vhost->tls.x509_client_CA)
41*1c60b9acSAndroid Build Coastguard Worker 		X509_free(vhost->tls.x509_client_CA);
42*1c60b9acSAndroid Build Coastguard Worker }
43*1c60b9acSAndroid Build Coastguard Worker 
44*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_capable_read(struct lws * wsi,unsigned char * buf,size_t len)45*1c60b9acSAndroid Build Coastguard Worker lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, size_t len)
46*1c60b9acSAndroid Build Coastguard Worker {
47*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context = wsi->a.context;
48*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
49*1c60b9acSAndroid Build Coastguard Worker 	int n = 0, m;
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->tls.ssl)
52*1c60b9acSAndroid Build Coastguard Worker 		return lws_ssl_capable_read_no_ssl(wsi, buf, len);
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker 	errno = 0;
55*1c60b9acSAndroid Build Coastguard Worker 	n = SSL_read(wsi->tls.ssl, buf, (int)len);
56*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_FREERTOS)
57*1c60b9acSAndroid Build Coastguard Worker 	if (!n && errno == LWS_ENOTCONN) {
58*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: SSL_read ENOTCONN\n", lws_wsi_tag(wsi));
59*1c60b9acSAndroid Build Coastguard Worker 		return LWS_SSL_CAPABLE_ERROR;
60*1c60b9acSAndroid Build Coastguard Worker 	}
61*1c60b9acSAndroid Build Coastguard Worker #endif
62*1c60b9acSAndroid Build Coastguard Worker 
63*1c60b9acSAndroid Build Coastguard Worker 	lwsl_debug("%s: %s: SSL_read says %d\n", __func__, lws_wsi_tag(wsi), n);
64*1c60b9acSAndroid Build Coastguard Worker 	/* manpage: returning 0 means connection shut down */
65*1c60b9acSAndroid Build Coastguard Worker 	if (!n) {
66*1c60b9acSAndroid Build Coastguard Worker 		wsi->socket_is_permanently_unusable = 1;
67*1c60b9acSAndroid Build Coastguard Worker 
68*1c60b9acSAndroid Build Coastguard Worker 		return LWS_SSL_CAPABLE_ERROR;
69*1c60b9acSAndroid Build Coastguard Worker 	}
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker 	if (n < 0) {
72*1c60b9acSAndroid Build Coastguard Worker 		m = SSL_get_error(wsi->tls.ssl, n);
73*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: %s: ssl err %d errno %d\n", __func__, lws_wsi_tag(wsi), m, errno);
74*1c60b9acSAndroid Build Coastguard Worker 		if (errno == LWS_ENOTCONN)
75*1c60b9acSAndroid Build Coastguard Worker 			/* If the socket isn't connected anymore, bail out. */
76*1c60b9acSAndroid Build Coastguard Worker 			goto do_err1;
77*1c60b9acSAndroid Build Coastguard Worker 
78*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_FREERTOS)
79*1c60b9acSAndroid Build Coastguard Worker 		if (errno == LWS_ECONNABORTED)
80*1c60b9acSAndroid Build Coastguard Worker 			goto do_err1;
81*1c60b9acSAndroid Build Coastguard Worker #endif
82*1c60b9acSAndroid Build Coastguard Worker 
83*1c60b9acSAndroid Build Coastguard Worker 		if (m == SSL_ERROR_ZERO_RETURN ||
84*1c60b9acSAndroid Build Coastguard Worker 		    m == SSL_ERROR_SYSCALL)
85*1c60b9acSAndroid Build Coastguard Worker 			goto do_err;
86*1c60b9acSAndroid Build Coastguard Worker 
87*1c60b9acSAndroid Build Coastguard Worker 		if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
88*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: WANT_READ\n", __func__);
89*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: LWS_SSL_CAPABLE_MORE_SERVICE\n", lws_wsi_tag(wsi));
90*1c60b9acSAndroid Build Coastguard Worker 			return LWS_SSL_CAPABLE_MORE_SERVICE;
91*1c60b9acSAndroid Build Coastguard Worker 		}
92*1c60b9acSAndroid Build Coastguard Worker 		if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
93*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: WANT_WRITE\n", __func__);
94*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: LWS_SSL_CAPABLE_MORE_SERVICE\n", lws_wsi_tag(wsi));
95*1c60b9acSAndroid Build Coastguard Worker 			wsi->tls_read_wanted_write = 1;
96*1c60b9acSAndroid Build Coastguard Worker 			lws_callback_on_writable(wsi);
97*1c60b9acSAndroid Build Coastguard Worker 			return LWS_SSL_CAPABLE_MORE_SERVICE;
98*1c60b9acSAndroid Build Coastguard Worker 		}
99*1c60b9acSAndroid Build Coastguard Worker 
100*1c60b9acSAndroid Build Coastguard Worker do_err1:
101*1c60b9acSAndroid Build Coastguard Worker 		wsi->socket_is_permanently_unusable = 1;
102*1c60b9acSAndroid Build Coastguard Worker 
103*1c60b9acSAndroid Build Coastguard Worker do_err:
104*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
105*1c60b9acSAndroid Build Coastguard Worker 	if (wsi->a.vhost)
106*1c60b9acSAndroid Build Coastguard Worker 		lws_metric_event(wsi->a.vhost->mt_traffic_rx, METRES_NOGO, 0);
107*1c60b9acSAndroid Build Coastguard Worker #endif
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker 		return LWS_SSL_CAPABLE_ERROR;
110*1c60b9acSAndroid Build Coastguard Worker 	}
111*1c60b9acSAndroid Build Coastguard Worker 
112*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_TLS_LOG_PLAINTEXT_RX)
113*1c60b9acSAndroid Build Coastguard Worker 	/*
114*1c60b9acSAndroid Build Coastguard Worker 	 * If using mbedtls type tls library, this is the earliest point for all
115*1c60b9acSAndroid Build Coastguard Worker 	 * paths to dump what was received as decrypted data from the tls tunnel
116*1c60b9acSAndroid Build Coastguard Worker 	 */
117*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("%s: len %d\n", __func__, n);
118*1c60b9acSAndroid Build Coastguard Worker 	lwsl_hexdump_notice(buf, (size_t)n);
119*1c60b9acSAndroid Build Coastguard Worker #endif
120*1c60b9acSAndroid Build Coastguard Worker 
121*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
122*1c60b9acSAndroid Build Coastguard Worker 	if (wsi->a.vhost)
123*1c60b9acSAndroid Build Coastguard Worker 		lws_metric_event(wsi->a.vhost->mt_traffic_rx,
124*1c60b9acSAndroid Build Coastguard Worker 				 METRES_GO /* rx */, (u_mt_t)n);
125*1c60b9acSAndroid Build Coastguard Worker #endif
126*1c60b9acSAndroid Build Coastguard Worker 
127*1c60b9acSAndroid Build Coastguard Worker 	/*
128*1c60b9acSAndroid Build Coastguard Worker 	 * if it was our buffer that limited what we read,
129*1c60b9acSAndroid Build Coastguard Worker 	 * check if SSL has additional data pending inside SSL buffers.
130*1c60b9acSAndroid Build Coastguard Worker 	 *
131*1c60b9acSAndroid Build Coastguard Worker 	 * Because these won't signal at the network layer with POLLIN
132*1c60b9acSAndroid Build Coastguard Worker 	 * and if we don't realize, this data will sit there forever
133*1c60b9acSAndroid Build Coastguard Worker 	 */
134*1c60b9acSAndroid Build Coastguard Worker 	if (n != (int)len)
135*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
136*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->tls.ssl)
137*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
138*1c60b9acSAndroid Build Coastguard Worker 
139*1c60b9acSAndroid Build Coastguard Worker 	if (SSL_pending(wsi->tls.ssl)) {
140*1c60b9acSAndroid Build Coastguard Worker 		if (lws_dll2_is_detached(&wsi->tls.dll_pending_tls))
141*1c60b9acSAndroid Build Coastguard Worker 			lws_dll2_add_head(&wsi->tls.dll_pending_tls,
142*1c60b9acSAndroid Build Coastguard Worker 					  &pt->tls.dll_pending_tls_owner);
143*1c60b9acSAndroid Build Coastguard Worker 	} else
144*1c60b9acSAndroid Build Coastguard Worker 		__lws_ssl_remove_wsi_from_buffered_list(wsi);
145*1c60b9acSAndroid Build Coastguard Worker 
146*1c60b9acSAndroid Build Coastguard Worker 	return n;
147*1c60b9acSAndroid Build Coastguard Worker bail:
148*1c60b9acSAndroid Build Coastguard Worker 	lws_ssl_remove_wsi_from_buffered_list(wsi);
149*1c60b9acSAndroid Build Coastguard Worker 
150*1c60b9acSAndroid Build Coastguard Worker 	return n;
151*1c60b9acSAndroid Build Coastguard Worker }
152*1c60b9acSAndroid Build Coastguard Worker 
153*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_pending(struct lws * wsi)154*1c60b9acSAndroid Build Coastguard Worker lws_ssl_pending(struct lws *wsi)
155*1c60b9acSAndroid Build Coastguard Worker {
156*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->tls.ssl)
157*1c60b9acSAndroid Build Coastguard Worker 		return 0;
158*1c60b9acSAndroid Build Coastguard Worker 
159*1c60b9acSAndroid Build Coastguard Worker 	return SSL_pending(wsi->tls.ssl);
160*1c60b9acSAndroid Build Coastguard Worker }
161*1c60b9acSAndroid Build Coastguard Worker 
162*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_capable_write(struct lws * wsi,unsigned char * buf,size_t len)163*1c60b9acSAndroid Build Coastguard Worker lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, size_t len)
164*1c60b9acSAndroid Build Coastguard Worker {
165*1c60b9acSAndroid Build Coastguard Worker 	int n, m;
166*1c60b9acSAndroid Build Coastguard Worker 
167*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_TLS_LOG_PLAINTEXT_TX)
168*1c60b9acSAndroid Build Coastguard Worker 	/*
169*1c60b9acSAndroid Build Coastguard Worker 	 * If using mbedtls type tls library, this is the last point for all
170*1c60b9acSAndroid Build Coastguard Worker 	 * paths before sending data into the tls tunnel, where you can dump it
171*1c60b9acSAndroid Build Coastguard Worker 	 * and see what is being sent.
172*1c60b9acSAndroid Build Coastguard Worker 	 */
173*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("%s: len %d\n", __func__, (int)len);
174*1c60b9acSAndroid Build Coastguard Worker 	lwsl_hexdump_notice(buf, len);
175*1c60b9acSAndroid Build Coastguard Worker #endif
176*1c60b9acSAndroid Build Coastguard Worker 
177*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->tls.ssl)
178*1c60b9acSAndroid Build Coastguard Worker 		return lws_ssl_capable_write_no_ssl(wsi, buf, len);
179*1c60b9acSAndroid Build Coastguard Worker 
180*1c60b9acSAndroid Build Coastguard Worker 	n = SSL_write(wsi->tls.ssl, buf, (int)len);
181*1c60b9acSAndroid Build Coastguard Worker 	if (n > 0) {
182*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
183*1c60b9acSAndroid Build Coastguard Worker 		if (wsi->a.vhost)
184*1c60b9acSAndroid Build Coastguard Worker 			lws_metric_event(wsi->a.vhost->mt_traffic_tx,
185*1c60b9acSAndroid Build Coastguard Worker 					 METRES_GO, (u_mt_t)n);
186*1c60b9acSAndroid Build Coastguard Worker #endif
187*1c60b9acSAndroid Build Coastguard Worker 		return n;
188*1c60b9acSAndroid Build Coastguard Worker 	}
189*1c60b9acSAndroid Build Coastguard Worker 
190*1c60b9acSAndroid Build Coastguard Worker 	m = SSL_get_error(wsi->tls.ssl, n);
191*1c60b9acSAndroid Build Coastguard Worker 	if (m != SSL_ERROR_SYSCALL) {
192*1c60b9acSAndroid Build Coastguard Worker 		if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
193*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: want read\n", __func__);
194*1c60b9acSAndroid Build Coastguard Worker 
195*1c60b9acSAndroid Build Coastguard Worker 			return LWS_SSL_CAPABLE_MORE_SERVICE;
196*1c60b9acSAndroid Build Coastguard Worker 		}
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker 		if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
199*1c60b9acSAndroid Build Coastguard Worker 			lws_set_blocking_send(wsi);
200*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: want write\n", __func__);
201*1c60b9acSAndroid Build Coastguard Worker 
202*1c60b9acSAndroid Build Coastguard Worker 			return LWS_SSL_CAPABLE_MORE_SERVICE;
203*1c60b9acSAndroid Build Coastguard Worker 		}
204*1c60b9acSAndroid Build Coastguard Worker 	}
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 	lwsl_debug("%s failed: %d\n",__func__, m);
207*1c60b9acSAndroid Build Coastguard Worker 	wsi->socket_is_permanently_unusable = 1;
208*1c60b9acSAndroid Build Coastguard Worker 
209*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
210*1c60b9acSAndroid Build Coastguard Worker 		if (wsi->a.vhost)
211*1c60b9acSAndroid Build Coastguard Worker 			lws_metric_event(wsi->a.vhost->mt_traffic_tx,
212*1c60b9acSAndroid Build Coastguard Worker 					 METRES_NOGO, (u_mt_t)n);
213*1c60b9acSAndroid Build Coastguard Worker #endif
214*1c60b9acSAndroid Build Coastguard Worker 
215*1c60b9acSAndroid Build Coastguard Worker 	return LWS_SSL_CAPABLE_ERROR;
216*1c60b9acSAndroid Build Coastguard Worker }
217*1c60b9acSAndroid Build Coastguard Worker 
218*1c60b9acSAndroid Build Coastguard Worker int openssl_SSL_CTX_private_data_index;
219*1c60b9acSAndroid Build Coastguard Worker 
220*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_info_callback(const SSL * ssl,int where,int ret)221*1c60b9acSAndroid Build Coastguard Worker lws_ssl_info_callback(const SSL *ssl, int where, int ret)
222*1c60b9acSAndroid Build Coastguard Worker {
223*1c60b9acSAndroid Build Coastguard Worker 	struct lws *wsi;
224*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context;
225*1c60b9acSAndroid Build Coastguard Worker 	struct lws_ssl_info si;
226*1c60b9acSAndroid Build Coastguard Worker 
227*1c60b9acSAndroid Build Coastguard Worker 	context = (struct lws_context *)SSL_CTX_get_ex_data(
228*1c60b9acSAndroid Build Coastguard Worker 					SSL_get_SSL_CTX(ssl),
229*1c60b9acSAndroid Build Coastguard Worker 					openssl_SSL_CTX_private_data_index);
230*1c60b9acSAndroid Build Coastguard Worker 	if (!context)
231*1c60b9acSAndroid Build Coastguard Worker 		return;
232*1c60b9acSAndroid Build Coastguard Worker 	wsi = wsi_from_fd(context, SSL_get_fd(ssl));
233*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi)
234*1c60b9acSAndroid Build Coastguard Worker 		return;
235*1c60b9acSAndroid Build Coastguard Worker 
236*1c60b9acSAndroid Build Coastguard Worker 	if (!(where & wsi->a.vhost->tls.ssl_info_event_mask))
237*1c60b9acSAndroid Build Coastguard Worker 		return;
238*1c60b9acSAndroid Build Coastguard Worker 
239*1c60b9acSAndroid Build Coastguard Worker 	si.where = where;
240*1c60b9acSAndroid Build Coastguard Worker 	si.ret = ret;
241*1c60b9acSAndroid Build Coastguard Worker 
242*1c60b9acSAndroid Build Coastguard Worker 	if (user_callback_handle_rxflow(wsi->a.protocol->callback,
243*1c60b9acSAndroid Build Coastguard Worker 					wsi, LWS_CALLBACK_SSL_INFO,
244*1c60b9acSAndroid Build Coastguard Worker 					wsi->user_space, &si, 0))
245*1c60b9acSAndroid Build Coastguard Worker 		lws_set_timeout(wsi, PENDING_TIMEOUT_KILLED_BY_SSL_INFO, -1);
246*1c60b9acSAndroid Build Coastguard Worker }
247*1c60b9acSAndroid Build Coastguard Worker 
248*1c60b9acSAndroid Build Coastguard Worker 
249*1c60b9acSAndroid Build Coastguard Worker int
lws_ssl_close(struct lws * wsi)250*1c60b9acSAndroid Build Coastguard Worker lws_ssl_close(struct lws *wsi)
251*1c60b9acSAndroid Build Coastguard Worker {
252*1c60b9acSAndroid Build Coastguard Worker 	lws_sockfd_type n;
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->tls.ssl)
255*1c60b9acSAndroid Build Coastguard Worker 		return 0; /* not handled */
256*1c60b9acSAndroid Build Coastguard Worker 
257*1c60b9acSAndroid Build Coastguard Worker #if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
258*1c60b9acSAndroid Build Coastguard Worker 	/* kill ssl callbacks, becausse we will remove the fd from the
259*1c60b9acSAndroid Build Coastguard Worker 	 * table linking it to the wsi
260*1c60b9acSAndroid Build Coastguard Worker 	 */
261*1c60b9acSAndroid Build Coastguard Worker 	if (wsi->a.vhost->tls.ssl_info_event_mask)
262*1c60b9acSAndroid Build Coastguard Worker 		SSL_set_info_callback(wsi->tls.ssl, NULL);
263*1c60b9acSAndroid Build Coastguard Worker #endif
264*1c60b9acSAndroid Build Coastguard Worker 
265*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_TLS_SYNTHESIZE_CB)
266*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_cancel(&wsi->tls.sul_cb_synth);
267*1c60b9acSAndroid Build Coastguard Worker 	/*
268*1c60b9acSAndroid Build Coastguard Worker 	 * ... check the session in case it did not live long enough to get
269*1c60b9acSAndroid Build Coastguard Worker 	 * the scheduled callback to sample it
270*1c60b9acSAndroid Build Coastguard Worker 	 */
271*1c60b9acSAndroid Build Coastguard Worker 	lws_sess_cache_synth_cb(&wsi->tls.sul_cb_synth);
272*1c60b9acSAndroid Build Coastguard Worker #endif
273*1c60b9acSAndroid Build Coastguard Worker 
274*1c60b9acSAndroid Build Coastguard Worker 	n = SSL_get_fd(wsi->tls.ssl);
275*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->socket_is_permanently_unusable)
276*1c60b9acSAndroid Build Coastguard Worker 		SSL_shutdown(wsi->tls.ssl);
277*1c60b9acSAndroid Build Coastguard Worker 	compatible_close(n);
278*1c60b9acSAndroid Build Coastguard Worker 	SSL_free(wsi->tls.ssl);
279*1c60b9acSAndroid Build Coastguard Worker 	wsi->tls.ssl = NULL;
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker 	lws_tls_restrict_return(wsi);
282*1c60b9acSAndroid Build Coastguard Worker 
283*1c60b9acSAndroid Build Coastguard Worker 	return 1; /* handled */
284*1c60b9acSAndroid Build Coastguard Worker }
285*1c60b9acSAndroid Build Coastguard Worker 
286*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_SSL_CTX_destroy(struct lws_vhost * vhost)287*1c60b9acSAndroid Build Coastguard Worker lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
288*1c60b9acSAndroid Build Coastguard Worker {
289*1c60b9acSAndroid Build Coastguard Worker 	if (vhost->tls.ssl_ctx)
290*1c60b9acSAndroid Build Coastguard Worker 		SSL_CTX_free(vhost->tls.ssl_ctx);
291*1c60b9acSAndroid Build Coastguard Worker 
292*1c60b9acSAndroid Build Coastguard Worker 	if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
293*1c60b9acSAndroid Build Coastguard Worker 		SSL_CTX_free(vhost->tls.ssl_client_ctx);
294*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_ACME)
295*1c60b9acSAndroid Build Coastguard Worker 	lws_tls_acme_sni_cert_destroy(vhost);
296*1c60b9acSAndroid Build Coastguard Worker #endif
297*1c60b9acSAndroid Build Coastguard Worker }
298*1c60b9acSAndroid Build Coastguard Worker 
299*1c60b9acSAndroid Build Coastguard Worker void
lws_ssl_context_destroy(struct lws_context * context)300*1c60b9acSAndroid Build Coastguard Worker lws_ssl_context_destroy(struct lws_context *context)
301*1c60b9acSAndroid Build Coastguard Worker {
302*1c60b9acSAndroid Build Coastguard Worker }
303*1c60b9acSAndroid Build Coastguard Worker 
304*1c60b9acSAndroid Build Coastguard Worker lws_tls_ctx *
lws_tls_ctx_from_wsi(struct lws * wsi)305*1c60b9acSAndroid Build Coastguard Worker lws_tls_ctx_from_wsi(struct lws *wsi)
306*1c60b9acSAndroid Build Coastguard Worker {
307*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi->tls.ssl)
308*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
309*1c60b9acSAndroid Build Coastguard Worker 
310*1c60b9acSAndroid Build Coastguard Worker 	return SSL_get_SSL_CTX(wsi->tls.ssl);
311*1c60b9acSAndroid Build Coastguard Worker }
312*1c60b9acSAndroid Build Coastguard Worker 
313*1c60b9acSAndroid Build Coastguard Worker enum lws_ssl_capable_status
__lws_tls_shutdown(struct lws * wsi)314*1c60b9acSAndroid Build Coastguard Worker __lws_tls_shutdown(struct lws *wsi)
315*1c60b9acSAndroid Build Coastguard Worker {
316*1c60b9acSAndroid Build Coastguard Worker 	int n = SSL_shutdown(wsi->tls.ssl);
317*1c60b9acSAndroid Build Coastguard Worker 
318*1c60b9acSAndroid Build Coastguard Worker 	lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd);
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker 	switch (n) {
321*1c60b9acSAndroid Build Coastguard Worker 	case 1: /* successful completion */
322*1c60b9acSAndroid Build Coastguard Worker 		(void)shutdown(wsi->desc.sockfd, SHUT_WR);
323*1c60b9acSAndroid Build Coastguard Worker 		return LWS_SSL_CAPABLE_DONE;
324*1c60b9acSAndroid Build Coastguard Worker 
325*1c60b9acSAndroid Build Coastguard Worker 	case 0: /* needs a retry */
326*1c60b9acSAndroid Build Coastguard Worker 		__lws_change_pollfd(wsi, 0, LWS_POLLIN);
327*1c60b9acSAndroid Build Coastguard Worker 		return LWS_SSL_CAPABLE_MORE_SERVICE;
328*1c60b9acSAndroid Build Coastguard Worker 
329*1c60b9acSAndroid Build Coastguard Worker 	default: /* fatal error, or WANT */
330*1c60b9acSAndroid Build Coastguard Worker 		n = SSL_get_error(wsi->tls.ssl, n);
331*1c60b9acSAndroid Build Coastguard Worker 		if (n != SSL_ERROR_SYSCALL && n != SSL_ERROR_SSL) {
332*1c60b9acSAndroid Build Coastguard Worker 			if (SSL_want_read(wsi->tls.ssl)) {
333*1c60b9acSAndroid Build Coastguard Worker 				lwsl_debug("(wants read)\n");
334*1c60b9acSAndroid Build Coastguard Worker 				__lws_change_pollfd(wsi, 0, LWS_POLLIN);
335*1c60b9acSAndroid Build Coastguard Worker 				return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
336*1c60b9acSAndroid Build Coastguard Worker 			}
337*1c60b9acSAndroid Build Coastguard Worker 			if (SSL_want_write(wsi->tls.ssl)) {
338*1c60b9acSAndroid Build Coastguard Worker 				lwsl_debug("(wants write)\n");
339*1c60b9acSAndroid Build Coastguard Worker 				__lws_change_pollfd(wsi, 0, LWS_POLLOUT);
340*1c60b9acSAndroid Build Coastguard Worker 				return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
341*1c60b9acSAndroid Build Coastguard Worker 			}
342*1c60b9acSAndroid Build Coastguard Worker 		}
343*1c60b9acSAndroid Build Coastguard Worker 		return LWS_SSL_CAPABLE_ERROR;
344*1c60b9acSAndroid Build Coastguard Worker 	}
345*1c60b9acSAndroid Build Coastguard Worker }
346*1c60b9acSAndroid Build Coastguard Worker 
347*1c60b9acSAndroid Build Coastguard Worker 
348*1c60b9acSAndroid Build Coastguard Worker static int
tops_fake_POLLIN_for_buffered_mbedtls(struct lws_context_per_thread * pt)349*1c60b9acSAndroid Build Coastguard Worker tops_fake_POLLIN_for_buffered_mbedtls(struct lws_context_per_thread *pt)
350*1c60b9acSAndroid Build Coastguard Worker {
351*1c60b9acSAndroid Build Coastguard Worker 	return lws_tls_fake_POLLIN_for_buffered(pt);
352*1c60b9acSAndroid Build Coastguard Worker }
353*1c60b9acSAndroid Build Coastguard Worker 
354*1c60b9acSAndroid Build Coastguard Worker const struct lws_tls_ops tls_ops_mbedtls = {
355*1c60b9acSAndroid Build Coastguard Worker 	/* fake_POLLIN_for_buffered */	tops_fake_POLLIN_for_buffered_mbedtls,
356*1c60b9acSAndroid Build Coastguard Worker };
357