• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "private-lib-core.h"
26 #include "private-lib-tls-mbedtls.h"
27 
28 
29 void
lws_ssl_destroy(struct lws_vhost * vhost)30 lws_ssl_destroy(struct lws_vhost *vhost)
31 {
32 	if (!lws_check_opt(vhost->context->options,
33 			   LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
34 		return;
35 
36 	if (vhost->tls.ssl_ctx)
37 		SSL_CTX_free(vhost->tls.ssl_ctx);
38 	if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
39 		SSL_CTX_free(vhost->tls.ssl_client_ctx);
40 
41 	if (vhost->tls.x509_client_CA)
42 		X509_free(vhost->tls.x509_client_CA);
43 }
44 
45 int
lws_ssl_capable_read(struct lws * wsi,unsigned char * buf,int len)46 lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
47 {
48 	struct lws_context *context = wsi->context;
49 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
50 	int n = 0, m;
51 
52 	if (!wsi->tls.ssl)
53 		return lws_ssl_capable_read_no_ssl(wsi, buf, len);
54 
55 	lws_stats_bump(pt, LWSSTATS_C_API_READ, 1);
56 
57 	errno = 0;
58 	n = SSL_read(wsi->tls.ssl, buf, len);
59 #if defined(LWS_PLAT_FREERTOS)
60 	if (!n && errno == LWS_ENOTCONN) {
61 		lwsl_debug("%p: SSL_read ENOTCONN\n", wsi);
62 		return LWS_SSL_CAPABLE_ERROR;
63 	}
64 #endif
65 #if defined(LWS_WITH_STATS)
66 	if (!wsi->seen_rx && wsi->accept_start_us) {
67                 lws_stats_bump(pt, LWSSTATS_US_SSL_RX_DELAY_AVG,
68 			lws_now_usecs() - wsi->accept_start_us);
69                 lws_stats_bump(pt, LWSSTATS_C_SSL_CONNS_HAD_RX, 1);
70 		wsi->seen_rx = 1;
71 	}
72 #endif
73 
74 
75 	lwsl_debug("%p: SSL_read says %d\n", wsi, n);
76 	/* manpage: returning 0 means connection shut down */
77 	if (!n) {
78 		wsi->socket_is_permanently_unusable = 1;
79 
80 		return LWS_SSL_CAPABLE_ERROR;
81 	}
82 
83 	if (n < 0) {
84 		m = SSL_get_error(wsi->tls.ssl, n);
85 		lwsl_debug("%p: ssl err %d errno %d\n", wsi, m, errno);
86 		if (errno == LWS_ENOTCONN) {
87 			/* If the socket isn't connected anymore, bail out. */
88 			wsi->socket_is_permanently_unusable = 1;
89 			return LWS_SSL_CAPABLE_ERROR;
90 		}
91 		if (m == SSL_ERROR_ZERO_RETURN ||
92 		    m == SSL_ERROR_SYSCALL)
93 			return LWS_SSL_CAPABLE_ERROR;
94 
95 		if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
96 			lwsl_debug("%s: WANT_READ\n", __func__);
97 			lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi);
98 			return LWS_SSL_CAPABLE_MORE_SERVICE;
99 		}
100 		if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
101 			lwsl_debug("%s: WANT_WRITE\n", __func__);
102 			lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi);
103 			return LWS_SSL_CAPABLE_MORE_SERVICE;
104 		}
105 		wsi->socket_is_permanently_unusable = 1;
106 
107 		return LWS_SSL_CAPABLE_ERROR;
108 	}
109 
110 	lws_stats_bump(pt, LWSSTATS_B_READ, n);
111 
112 #if defined(LWS_WITH_SERVER_STATUS)
113 	if (wsi->vhost)
114 		wsi->vhost->conn_stats.rx += n;
115 #endif
116 #if defined(LWS_WITH_DETAILED_LATENCY)
117 	if (context->detailed_latency_cb) {
118 		wsi->detlat.req_size = len;
119 		wsi->detlat.acc_size = n;
120 		wsi->detlat.type = LDLT_READ;
121 		wsi->detlat.latencies[LAT_DUR_PROXY_RX_TO_ONWARD_TX] =
122 			lws_now_usecs() - pt->ust_left_poll;
123 		wsi->detlat.latencies[LAT_DUR_USERCB] = 0;
124 		lws_det_lat_cb(wsi->context, &wsi->detlat);
125 	}
126 #endif
127 	/*
128 	 * if it was our buffer that limited what we read,
129 	 * check if SSL has additional data pending inside SSL buffers.
130 	 *
131 	 * Because these won't signal at the network layer with POLLIN
132 	 * and if we don't realize, this data will sit there forever
133 	 */
134 	if (n != len)
135 		goto bail;
136 	if (!wsi->tls.ssl)
137 		goto bail;
138 
139 	if (SSL_pending(wsi->tls.ssl) &&
140 	    lws_dll2_is_detached(&wsi->tls.dll_pending_tls))
141 		lws_dll2_add_head(&wsi->tls.dll_pending_tls,
142 				 &pt->tls.dll_pending_tls_owner);
143 
144 	return n;
145 bail:
146 	lws_ssl_remove_wsi_from_buffered_list(wsi);
147 
148 	return n;
149 }
150 
151 int
lws_ssl_pending(struct lws * wsi)152 lws_ssl_pending(struct lws *wsi)
153 {
154 	if (!wsi->tls.ssl)
155 		return 0;
156 
157 	return SSL_pending(wsi->tls.ssl);
158 }
159 
160 int
lws_ssl_capable_write(struct lws * wsi,unsigned char * buf,int len)161 lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
162 {
163 	int n, m;
164 
165 	if (!wsi->tls.ssl)
166 		return lws_ssl_capable_write_no_ssl(wsi, buf, len);
167 
168 	n = SSL_write(wsi->tls.ssl, buf, len);
169 	if (n > 0)
170 		return n;
171 
172 	m = SSL_get_error(wsi->tls.ssl, n);
173 	if (m != SSL_ERROR_SYSCALL) {
174 		if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
175 			lwsl_notice("%s: want read\n", __func__);
176 
177 			return LWS_SSL_CAPABLE_MORE_SERVICE;
178 		}
179 
180 		if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
181 			lws_set_blocking_send(wsi);
182 			lwsl_debug("%s: want write\n", __func__);
183 
184 			return LWS_SSL_CAPABLE_MORE_SERVICE;
185 		}
186 	}
187 
188 	lwsl_debug("%s failed: %d\n",__func__, m);
189 	wsi->socket_is_permanently_unusable = 1;
190 
191 	return LWS_SSL_CAPABLE_ERROR;
192 }
193 
194 int openssl_SSL_CTX_private_data_index;
195 
196 void
lws_ssl_info_callback(const SSL * ssl,int where,int ret)197 lws_ssl_info_callback(const SSL *ssl, int where, int ret)
198 {
199 	struct lws *wsi;
200 	struct lws_context *context;
201 	struct lws_ssl_info si;
202 
203 	context = (struct lws_context *)SSL_CTX_get_ex_data(
204 					SSL_get_SSL_CTX(ssl),
205 					openssl_SSL_CTX_private_data_index);
206 	if (!context)
207 		return;
208 	wsi = wsi_from_fd(context, SSL_get_fd(ssl));
209 	if (!wsi)
210 		return;
211 
212 	if (!(where & wsi->vhost->tls.ssl_info_event_mask))
213 		return;
214 
215 	si.where = where;
216 	si.ret = ret;
217 
218 	if (user_callback_handle_rxflow(wsi->protocol->callback,
219 					wsi, LWS_CALLBACK_SSL_INFO,
220 					wsi->user_space, &si, 0))
221 		lws_set_timeout(wsi, PENDING_TIMEOUT_KILLED_BY_SSL_INFO, -1);
222 }
223 
224 
225 int
lws_ssl_close(struct lws * wsi)226 lws_ssl_close(struct lws *wsi)
227 {
228 	lws_sockfd_type n;
229 
230 	if (!wsi->tls.ssl)
231 		return 0; /* not handled */
232 
233 #if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
234 	/* kill ssl callbacks, becausse we will remove the fd from the
235 	 * table linking it to the wsi
236 	 */
237 	if (wsi->vhost->tls.ssl_info_event_mask)
238 		SSL_set_info_callback(wsi->tls.ssl, NULL);
239 #endif
240 
241 	n = SSL_get_fd(wsi->tls.ssl);
242 	if (!wsi->socket_is_permanently_unusable)
243 		SSL_shutdown(wsi->tls.ssl);
244 	compatible_close(n);
245 	SSL_free(wsi->tls.ssl);
246 	wsi->tls.ssl = NULL;
247 
248 	lws_tls_restrict_return(wsi->context);
249 
250 	return 1; /* handled */
251 }
252 
253 void
lws_ssl_SSL_CTX_destroy(struct lws_vhost * vhost)254 lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
255 {
256 	if (vhost->tls.ssl_ctx)
257 		SSL_CTX_free(vhost->tls.ssl_ctx);
258 
259 	if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx)
260 		SSL_CTX_free(vhost->tls.ssl_client_ctx);
261 #if defined(LWS_WITH_ACME)
262 	lws_tls_acme_sni_cert_destroy(vhost);
263 #endif
264 }
265 
266 void
lws_ssl_context_destroy(struct lws_context * context)267 lws_ssl_context_destroy(struct lws_context *context)
268 {
269 }
270 
271 lws_tls_ctx *
lws_tls_ctx_from_wsi(struct lws * wsi)272 lws_tls_ctx_from_wsi(struct lws *wsi)
273 {
274 	if (!wsi->tls.ssl)
275 		return NULL;
276 
277 	return SSL_get_SSL_CTX(wsi->tls.ssl);
278 }
279 
280 enum lws_ssl_capable_status
__lws_tls_shutdown(struct lws * wsi)281 __lws_tls_shutdown(struct lws *wsi)
282 {
283 	int n = SSL_shutdown(wsi->tls.ssl);
284 
285 	lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd);
286 
287 	switch (n) {
288 	case 1: /* successful completion */
289 		n = shutdown(wsi->desc.sockfd, SHUT_WR);
290 		return LWS_SSL_CAPABLE_DONE;
291 
292 	case 0: /* needs a retry */
293 		__lws_change_pollfd(wsi, 0, LWS_POLLIN);
294 		return LWS_SSL_CAPABLE_MORE_SERVICE;
295 
296 	default: /* fatal error, or WANT */
297 		n = SSL_get_error(wsi->tls.ssl, n);
298 		if (n != SSL_ERROR_SYSCALL && n != SSL_ERROR_SSL) {
299 			if (SSL_want_read(wsi->tls.ssl)) {
300 				lwsl_debug("(wants read)\n");
301 				__lws_change_pollfd(wsi, 0, LWS_POLLIN);
302 				return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
303 			}
304 			if (SSL_want_write(wsi->tls.ssl)) {
305 				lwsl_debug("(wants write)\n");
306 				__lws_change_pollfd(wsi, 0, LWS_POLLOUT);
307 				return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
308 			}
309 		}
310 		return LWS_SSL_CAPABLE_ERROR;
311 	}
312 }
313 
314 
315 static int
tops_fake_POLLIN_for_buffered_mbedtls(struct lws_context_per_thread * pt)316 tops_fake_POLLIN_for_buffered_mbedtls(struct lws_context_per_thread *pt)
317 {
318 	return lws_tls_fake_POLLIN_for_buffered(pt);
319 }
320 
321 const struct lws_tls_ops tls_ops_mbedtls = {
322 	/* fake_POLLIN_for_buffered */	tops_fake_POLLIN_for_buffered_mbedtls,
323 };
324