diff options
author | beck <> | 2021-09-04 15:21:45 +0000 |
---|---|---|
committer | beck <> | 2021-09-04 15:21:45 +0000 |
commit | 5f9c147b857183086592529152aa63fc86fa2e56 (patch) | |
tree | 46fbd6affcb71c4e2e66851ce0f93e1601588d37 | |
parent | e5fd1ea5108181e48a2884ce779c8cfeff9d5ea1 (diff) | |
download | openbsd-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.c | 128 |
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 | ||
2245 | void | 2245 | static int |
2246 | ssl_update_cache(SSL *s, int mode) | 2246 | ssl_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 | |||
2267 | static int | ||
2268 | ssl_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 | |||
2313 | void | ||
2314 | ssl_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 | ||