summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbeck <>2021-09-04 15:21:45 +0000
committerbeck <>2021-09-04 15:21:45 +0000
commit5f9c147b857183086592529152aa63fc86fa2e56 (patch)
tree46fbd6affcb71c4e2e66851ce0f93e1601588d37
parente5fd1ea5108181e48a2884ce779c8cfeff9d5ea1 (diff)
downloadopenbsd-5f9c147b857183086592529152aa63fc86fa2e56.tar.gz
openbsd-5f9c147b857183086592529152aa63fc86fa2e56.tar.bz2
openbsd-5f9c147b857183086592529152aa63fc86fa2e56.zip
Refactor ssl_update_cache. This now matches the logic used for TLS 1.3
in Openssl 1.1.1 for when to call the session callbacks. I believe it to also generates a lot less eye bleed, confirmed by tb@ ok jsing@ tb@
-rw-r--r--src/lib/libssl/ssl_lib.c128
1 files changed, 106 insertions, 22 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index c5cc6d05fa..142771c423 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_lib.c,v 1.263 2021/08/30 19:25:43 jsing Exp $ */ 1/* $OpenBSD: ssl_lib.c,v 1.264 2021/09/04 15:21:45 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -2242,35 +2242,119 @@ ssl_get_auto_dh(SSL *s)
2242 return (dhp); 2242 return (dhp);
2243} 2243}
2244 2244
2245void 2245static int
2246ssl_update_cache(SSL *s, int mode) 2246ssl_should_update_external_cache(SSL *s, int mode)
2247{ 2247{
2248 int i; 2248 int cache_mode;
2249
2250 cache_mode = s->session_ctx->internal->session_cache_mode;
2251
2252 /* Don't cache if mode says not to */
2253 if ((cache_mode & mode) == 0)
2254 return 0;
2255
2256 /* if it is not already cached, cache it */
2257 if (!s->internal->hit)
2258 return 1;
2259
2260 /* If it's TLS 1.3, do it to match OpenSSL */
2261 if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION)
2262 return 1;
2263
2264 return 0;
2265}
2266
2267static int
2268ssl_should_update_internal_cache(SSL *s, int mode)
2269{
2270 int cache_mode;
2271
2272 cache_mode = s->session_ctx->internal->session_cache_mode;
2273
2274 /* Don't cache if mode says not to */
2275 if ((cache_mode & mode) == 0)
2276 return 0;
2277
2278 /* If it is already cached, don't cache it again */
2279 if (s->internal->hit)
2280 return 0;
2281
2282 if ((cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
2283 return 0;
2284
2285 /* If we are lesser than TLS 1.3, Cache it. */
2286 if (S3I(s)->hs.negotiated_tls_version < TLS1_3_VERSION)
2287 return 1;
2288
2289 /* Below this we consider TLS 1.3 or later */
2290
2291 /* If it's not a server, add it? OpenSSL does this. */
2292 if (!s->server)
2293 return 1;
2294
2295 /* XXX if we support early data / PSK need to add */
2249 2296
2250 /* 2297 /*
2251 * If the session_id_length is 0, we are not supposed to cache it, 2298 * If we have the remove session callback, we will want
2252 * and it would be rather hard to do anyway :-) 2299 * to know about this even if it's a stateless ticket
2300 * from 1.3 so we can know when it is removed.
2253 */ 2301 */
2302 if (s->session_ctx->internal->remove_session_cb != NULL)
2303 return 1;
2304
2305 /* If we have set OP_NO_TICKET, cache it. */
2306 if ((s->internal->options & SSL_OP_NO_TICKET) != 0)
2307 return 1;
2308
2309 /* Otherwise do not cache */
2310 return 0;
2311}
2312
2313void
2314ssl_update_cache(SSL *s, int mode)
2315{
2316 int cache_mode, do_callback;
2317
2254 if (s->session->session_id_length == 0) 2318 if (s->session->session_id_length == 0)
2255 return; 2319 return;
2256 2320
2257 i = s->session_ctx->internal->session_cache_mode; 2321 cache_mode = s->session_ctx->internal->session_cache_mode;
2258 if ((i & mode) && (!s->internal->hit) && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) 2322 do_callback = ssl_should_update_external_cache(s, mode);
2259 || SSL_CTX_add_session(s->session_ctx, s->session)) 2323
2260 && (s->session_ctx->internal->new_session_cb != NULL)) { 2324 if (ssl_should_update_internal_cache(s, mode)) {
2261 CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); 2325 /*
2262 if (!s->session_ctx->internal->new_session_cb(s, s->session)) 2326 * XXX should we fail if the add to the internal cache
2263 SSL_SESSION_free(s->session); 2327 * fails? OpenSSL doesn't care..
2264 } 2328 */
2265 2329 (void) SSL_CTX_add_session(s->session_ctx, s->session);
2266 /* auto flush every 255 connections */ 2330 }
2267 if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && 2331
2268 ((i & mode) == mode)) { 2332 /*
2269 if ((((mode & SSL_SESS_CACHE_CLIENT) ? 2333 * Update the "external cache" by calling the new session
2270 s->session_ctx->internal->stats.sess_connect_good : 2334 * callback if present, even with TLS 1.3 without early data
2271 s->session_ctx->internal->stats.sess_accept_good) & 0xff) == 0xff) { 2335 * "because some application just want to know about the
2336 * creation of a session and aren't doing a full cache".
2337 * Apparently, if they are doing a full cache, they'll have
2338 * some fun, but we endeavour to give application writers the
2339 * same glorious experience they expect from OpenSSL which
2340 * does it this way.
2341 */
2342 if (do_callback && s->session_ctx->internal->new_session_cb != NULL) {
2343 CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION);
2344 if (!s->session_ctx->internal->new_session_cb(s, s->session))
2345 SSL_SESSION_free(s->session);
2346 }
2347
2348 /* Auto flush every 255 connections. */
2349 if (!(cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) &&
2350 (cache_mode & mode) != 0) {
2351 int connections;
2352 if (mode & SSL_SESS_CACHE_CLIENT)
2353 connections = s->session_ctx->internal->stats.sess_connect_good;
2354 else
2355 connections = s->session_ctx->internal->stats.sess_accept_good;
2356 if ((connections & 0xff) == 0xff)
2272 SSL_CTX_flush_sessions(s->session_ctx, time(NULL)); 2357 SSL_CTX_flush_sessions(s->session_ctx, time(NULL));
2273 }
2274 } 2358 }
2275} 2359}
2276 2360