2424
2525#include "private-lib-core.h"
2626
27+ typedef struct lws_serialized_mbedtls_session {
28+ size_t len ;
29+ uint8_t data [2048 ]; /* Sized to hold a typical serialized session */
30+ } lws_ser_sess_t ;
31+
2732typedef struct lws_tls_session_cache_mbedtls {
2833 lws_dll2_t list ;
2934
30- mbedtls_ssl_session session ;
3135 lws_sorted_usec_list_t sul_ttl ;
36+ lws_ser_sess_t * ser_data ;
3237
3338 /* name is overallocated here */
3439} lws_tls_scm_t ;
@@ -44,8 +49,9 @@ __lws_tls_session_destroy(lws_tls_scm_t *ts)
4449 (unsigned int )(ts -> list .owner -> count - 1 ));
4550
4651 lws_sul_cancel (& ts -> sul_ttl );
47- mbedtls_ssl_session_free (& ts -> session );
4852 lws_dll2_remove (& ts -> list ); /* vh lock */
53+ if (ts -> ser_data )
54+ lws_free (ts -> ser_data );
4955
5056 lws_free (ts );
5157}
@@ -76,6 +82,7 @@ lws_tls_reuse_session(struct lws *wsi)
7682 char buf [LWS_SESSION_TAG_LEN ];
7783 mbedtls_ssl_context * msc ;
7884 lws_tls_scm_t * ts ;
85+ mbedtls_ssl_session session ;
7986
8087 if (!wsi -> a .vhost ||
8188 wsi -> a .vhost -> options & LWS_SERVER_OPTION_DISABLE_TLS_SESSION_CACHE )
@@ -94,11 +101,25 @@ lws_tls_reuse_session(struct lws *wsi)
94101 goto bail ;
95102 }
96103
104+ if (!ts -> ser_data ) /* cache entry is invalid */
105+ goto bail ;
106+
107+ mbedtls_ssl_session_init (& session );
108+
109+ if (mbedtls_ssl_session_load (& session , ts -> ser_data -> data ,
110+ ts -> ser_data -> len )) {
111+ mbedtls_ssl_session_free (& session );
112+ goto bail ;
113+ }
114+
97115 lwsl_tlssess ("%s: %s\n" , __func__ , (const char * )& ts [1 ]);
98116 wsi -> tls_session_reused = 1 ;
99117
100118 msc = SSL_mbedtls_ssl_context_from_SSL (wsi -> tls .ssl );
101- mbedtls_ssl_set_session (msc , & ts -> session );
119+ if (mbedtls_ssl_set_session (msc , & session )) {
120+ /* Failed to set session, clean up and bail */
121+ }
122+ mbedtls_ssl_session_free (& session );
102123
103124 /* keep our session list sorted in lru -> mru order */
104125
@@ -168,6 +189,7 @@ lws_tls_session_new_mbedtls(struct lws *wsi)
168189 struct lws_vhost * vh ;
169190 lws_tls_scm_t * ts ;
170191 size_t nl ;
192+ mbedtls_ssl_session temp_session ;
171193#if !defined(LWS_WITH_NO_LOGS ) && defined(_DEBUG )
172194 const char * disposition = "reuse" ;
173195#endif
@@ -183,6 +205,8 @@ lws_tls_session_new_mbedtls(struct lws *wsi)
183205
184206 msc = SSL_mbedtls_ssl_context_from_SSL (wsi -> tls .ssl );
185207
208+ mbedtls_ssl_session_init (& temp_session );
209+
186210 lws_context_lock (vh -> context , __func__ ); /* -------------- cx { */
187211 lws_vhost_lock (vh ); /* -------------- vh { */
188212
@@ -219,12 +243,27 @@ lws_tls_session_new_mbedtls(struct lws *wsi)
219243 memset (ts , 0 , sizeof (* ts ));
220244 memcpy (& ts [1 ], buf , nl + 1 );
221245
222- if (mbedtls_ssl_get_session (msc , & ts -> session )) {
246+ ts -> ser_data = lws_malloc (sizeof (* ts -> ser_data ), __func__ );
247+ if (!ts -> ser_data ) {
248+ lws_free (ts );
249+ goto bail ;
250+ }
251+
252+ if (mbedtls_ssl_get_session (msc , & temp_session )) {
253+ lws_free (ts -> ser_data );
223254 lws_free (ts );
224255 /* no joy for whatever reason */
225256 goto bail ;
226257 }
227258
259+ if (mbedtls_ssl_session_save (& temp_session , ts -> ser_data -> data ,
260+ sizeof (ts -> ser_data -> data ),
261+ & ts -> ser_data -> len )) {
262+ /* Serialization failed, cache entry will be invalid */
263+ lws_free (ts -> ser_data );
264+ ts -> ser_data = NULL ;
265+ }
266+
228267 lws_dll2_add_tail (& ts -> list , & vh -> tls_sessions );
229268
230269 lws_sul_schedule (wsi -> a .context , wsi -> tsi , & ts -> sul_ttl ,
@@ -236,18 +275,30 @@ lws_tls_session_new_mbedtls(struct lws *wsi)
236275 disposition = "new" ;
237276#endif
238277 } else {
239-
240- mbedtls_ssl_session_free (& ts -> session );
241-
242- if (mbedtls_ssl_get_session (msc , & ts -> session ))
278+ if (mbedtls_ssl_get_session (msc , & temp_session ))
243279 /* no joy for whatever reason */
244280 goto bail ;
245281
282+ if (!ts -> ser_data ) {
283+ ts -> ser_data = lws_malloc (sizeof (* ts -> ser_data ), __func__ );
284+ if (!ts -> ser_data )
285+ goto bail ;
286+ }
287+
288+ if (mbedtls_ssl_session_save (& temp_session , ts -> ser_data -> data ,
289+ sizeof (ts -> ser_data -> data ),
290+ & ts -> ser_data -> len )) {
291+ /* Serialization failed, cache entry will be invalid */
292+ lws_free (ts -> ser_data );
293+ ts -> ser_data = NULL ;
294+ }
295+
246296 /* keep our session list sorted in lru -> mru order */
247297
248298 lws_dll2_remove (& ts -> list );
249299 lws_dll2_add_tail (& ts -> list , & vh -> tls_sessions );
250300 }
301+ mbedtls_ssl_session_free (& temp_session );
251302
252303 lws_vhost_unlock (vh ); /* } vh -------------- */
253304 lws_context_unlock (vh -> context ); /* } cx -------------- */
@@ -264,6 +315,7 @@ lws_tls_session_new_mbedtls(struct lws *wsi)
264315 return 1 ;
265316
266317bail :
318+ mbedtls_ssl_session_free (& temp_session );
267319 lws_vhost_unlock (vh ); /* } vh -------------- */
268320 lws_context_unlock (vh -> context ); /* } cx -------------- */
269321
0 commit comments