summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2022-10-20 15:26:25 +0000
committertb <>2022-10-20 15:26:25 +0000
commitbcc6795d7c9d440c0bfb13e305709deacb2110ce (patch)
treef724dfe9f8a9633dfc51e7454baf1d4613e94baf /src
parent7eb2eff3bb0dfb8fb87e37ef0ca182f8109d908f (diff)
downloadopenbsd-bcc6795d7c9d440c0bfb13e305709deacb2110ce.tar.gz
openbsd-bcc6795d7c9d440c0bfb13e305709deacb2110ce.tar.bz2
openbsd-bcc6795d7c9d440c0bfb13e305709deacb2110ce.zip
Initial parsing of the NewSessionTicket message
TLSv1.3 introduces a New Session Ticket post-handshake handshake message that allows a unique association between a ticket value and a pre-shared key derived from the resumption master secret. Servers may send this message arbitrarily often at any time after receiving the client's Finished message. Implement tls13_new_session_ticket_recv() which parses the contents of the NewSessionTicket message into a fresh session derived from the current session so as to avoid modifying sessions that are already in the session cache. This uses tls13_new_session_ticket_recv() in tls13_phh_received_cb(). We currently rely on the general rate limiting of 100 PHH messages per connection and hour to avoid problems from connecting to a misbehaving or malicious server. ok jsing
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/tls13_lib.c105
1 files changed, 103 insertions, 2 deletions
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c
index be8343c7f5..54c98af15c 100644
--- a/src/lib/libssl/tls13_lib.c
+++ b/src/lib/libssl/tls13_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_lib.c,v 1.73 2022/10/20 15:23:43 tb Exp $ */ 1/* $OpenBSD: tls13_lib.c,v 1.74 2022/10/20 15:26:25 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2019 Bob Beck <beck@openbsd.org> 4 * Copyright (c) 2019 Bob Beck <beck@openbsd.org>
@@ -335,6 +335,107 @@ tls13_key_update_recv(struct tls13_ctx *ctx, CBS *cbs)
335 return tls13_send_alert(ctx->rl, alert); 335 return tls13_send_alert(ctx->rl, alert);
336} 336}
337 337
338/* RFC 8446 section 4.6.1 */
339static ssize_t
340tls13_new_session_ticket_recv(struct tls13_ctx *ctx, CBS *cbs)
341{
342 struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
343 struct tls13_secret nonce;
344 uint32_t ticket_lifetime, ticket_age_add;
345 CBS ticket_nonce, ticket;
346 SSL_SESSION *sess = NULL;
347 int alert, session_id_length;
348 ssize_t ret = 0;
349
350 memset(&nonce, 0, sizeof(nonce));
351
352 if (ctx->mode != TLS13_HS_CLIENT) {
353 alert = TLS13_ALERT_UNEXPECTED_MESSAGE;
354 goto err;
355 }
356
357 alert = TLS13_ALERT_DECODE_ERROR;
358
359 if (!CBS_get_u32(cbs, &ticket_lifetime))
360 goto err;
361 if (!CBS_get_u32(cbs, &ticket_age_add))
362 goto err;
363 if (!CBS_get_u8_length_prefixed(cbs, &ticket_nonce))
364 goto err;
365 if (!CBS_get_u16_length_prefixed(cbs, &ticket))
366 goto err;
367 /* Extensions can only contain early_data, which we currently ignore. */
368 if (!tlsext_client_parse(ctx->ssl, SSL_TLSEXT_MSG_NST, cbs, &alert))
369 goto err;
370
371 if (CBS_len(cbs) != 0)
372 goto err;
373
374 /* Zero indicates that the ticket should be discarded immediately. */
375 if (ticket_lifetime == 0) {
376 ret = TLS13_IO_SUCCESS;
377 goto done;
378 }
379
380 /* Servers MUST NOT use any value larger than 7 days. */
381 if (ticket_lifetime > TLS13_MAX_TICKET_LIFETIME) {
382 alert = TLS13_ALERT_ILLEGAL_PARAMETER;
383 goto err;
384 }
385
386 alert = TLS13_ALERT_INTERNAL_ERROR;
387
388 /*
389 * Create new session instead of modifying the current session.
390 * The current session could already be in the session cache.
391 */
392 if ((sess = ssl_session_dup(ctx->ssl->session, 0)) == NULL)
393 goto err;
394
395 sess->time = time(NULL);
396
397 sess->tlsext_tick_lifetime_hint = ticket_lifetime;
398 sess->tlsext_tick_age_add = ticket_age_add;
399
400 if (!CBS_stow(&ticket, &sess->tlsext_tick, &sess->tlsext_ticklen))
401 goto err;
402
403 /* XXX - ensure this doesn't overflow session_id if hash is changed. */
404 if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket),
405 sess->session_id, &session_id_length, EVP_sha256(), NULL))
406 goto err;
407 sess->session_id_length = session_id_length;
408
409 if (!CBS_stow(&ticket_nonce, &nonce.data, &nonce.len))
410 goto err;
411
412 if (!tls13_secret_init(&sess->resumption_master_secret, 256))
413 goto err;
414
415 if (!tls13_derive_secret(&sess->resumption_master_secret,
416 secrets->digest, &secrets->resumption_master, "resumption",
417 &nonce))
418 goto err;
419
420 SSL_SESSION_free(ctx->ssl->session);
421 ctx->ssl->session = sess;
422 sess = NULL;
423
424 ssl_update_cache(ctx->ssl, SSL_SESS_CACHE_CLIENT);
425
426 ret = TLS13_IO_SUCCESS;
427 goto done;
428
429 err:
430 ret = tls13_send_alert(ctx->rl, alert);
431
432 done:
433 tls13_secret_cleanup(&nonce);
434 SSL_SESSION_free(sess);
435
436 return ret;
437}
438
338ssize_t 439ssize_t
339tls13_phh_received_cb(void *cb_arg) 440tls13_phh_received_cb(void *cb_arg)
340{ 441{
@@ -361,7 +462,7 @@ tls13_phh_received_cb(void *cb_arg)
361 ret = tls13_key_update_recv(ctx, &cbs); 462 ret = tls13_key_update_recv(ctx, &cbs);
362 break; 463 break;
363 case TLS13_MT_NEW_SESSION_TICKET: 464 case TLS13_MT_NEW_SESSION_TICKET:
364 /* XXX do nothing for now and ignore this */ 465 ret = tls13_new_session_ticket_recv(ctx, &cbs);
365 break; 466 break;
366 case TLS13_MT_CERTIFICATE_REQUEST: 467 case TLS13_MT_CERTIFICATE_REQUEST:
367 /* XXX add support if we choose to advertise this */ 468 /* XXX add support if we choose to advertise this */