summaryrefslogtreecommitdiff
path: root/src/lib/libssl/tls13_client.c
diff options
context:
space:
mode:
authorjsing <>2020-04-22 17:05:07 +0000
committerjsing <>2020-04-22 17:05:07 +0000
commitc18a60d45888295bb8cf344e076d84ef817a65a5 (patch)
treec7a924ebca094d3b2e25924b18e7bcf1cf4da7b7 /src/lib/libssl/tls13_client.c
parentc430432c2ef1ea560124b642f581c3e1ddb24f69 (diff)
downloadopenbsd-c18a60d45888295bb8cf344e076d84ef817a65a5.tar.gz
openbsd-c18a60d45888295bb8cf344e076d84ef817a65a5.tar.bz2
openbsd-c18a60d45888295bb8cf344e076d84ef817a65a5.zip
Improve TLSv1.3 state machine for HelloRetryRequest handling.
The state machine currently handles the HelloRetryRequest case by using WITH_HRR - in other words, we're explicitly indicating when we transition to the alternate path. The problem here is that we do not know if we're going to receive a ServerHello or a HelloRetryRequest until we process the message. This means that the ServerHello processing code has to handle both types of messages. The state machine and associated processing code becomes cleaner if we flip this around so that we assume we are going to receive a HelloRetryRequest and upon discovering that it is not, trigger WITHOUT_HRR and hand off to the ServerHello processing function. In particular, this makes the logic much more straight forward on the server side, when adding support for HRR. With feedback from tb@ ok tb@
Diffstat (limited to 'src/lib/libssl/tls13_client.c')
-rw-r--r--src/lib/libssl/tls13_client.c110
1 files changed, 73 insertions, 37 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c
index 0da08f62c3..dffabf1753 100644
--- a/src/lib/libssl/tls13_client.c
+++ b/src/lib/libssl/tls13_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_client.c,v 1.50 2020/04/21 16:55:17 jsing Exp $ */ 1/* $OpenBSD: tls13_client.c,v 1.51 2020/04/22 17:05:07 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -281,6 +281,24 @@ tls13_server_hello_is_legacy(CBS *cbs)
281} 281}
282 282
283static int 283static int
284tls13_server_hello_is_retry(CBS *cbs)
285{
286 CBS server_hello, server_random;
287 uint16_t legacy_version;
288
289 CBS_dup(cbs, &server_hello);
290
291 if (!CBS_get_u16(&server_hello, &legacy_version))
292 return 0;
293 if (!CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE))
294 return 0;
295
296 /* See if this is a HelloRetryRequest. */
297 return CBS_mem_equal(&server_random, tls13_hello_retry_request_hash,
298 sizeof(tls13_hello_retry_request_hash));
299}
300
301static int
284tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) 302tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
285{ 303{
286 CBS server_random, session_id; 304 CBS server_random, session_id;
@@ -331,7 +349,8 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
331 /* From here on in we know we are doing TLSv1.3. */ 349 /* From here on in we know we are doing TLSv1.3. */
332 tls13_record_layer_allow_legacy_alerts(ctx->rl, 0); 350 tls13_record_layer_allow_legacy_alerts(ctx->rl, 0);
333 351
334 /* See if this is a Hello Retry Request. */ 352 /* See if this is a HelloRetryRequest. */
353 /* XXX - see if we can avoid doing this twice. */
335 if (CBS_mem_equal(&server_random, tls13_hello_retry_request_hash, 354 if (CBS_mem_equal(&server_random, tls13_hello_retry_request_hash,
336 sizeof(tls13_hello_retry_request_hash))) { 355 sizeof(tls13_hello_retry_request_hash))) {
337 tlsext_msg_type = SSL_TLSEXT_MSG_HRR; 356 tlsext_msg_type = SSL_TLSEXT_MSG_HRR;
@@ -515,40 +534,75 @@ tls13_client_engage_record_protection(struct tls13_ctx *ctx)
515} 534}
516 535
517int 536int
537tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs)
538{
539 /*
540 * The state machine has no way of knowing if we're going to receive a
541 * HelloRetryRequest or a ServerHello. As such, we have to handle
542 * this case here and hand off to the appropriate function.
543 */
544 if (!tls13_server_hello_is_retry(cbs)) {
545 ctx->handshake_stage.hs_type |= WITHOUT_HRR;
546 return tls13_server_hello_recv(ctx, cbs);
547 }
548
549 if (!tls13_server_hello_process(ctx, cbs))
550 return 0;
551
552 /*
553 * This may have been a TLSv1.2 or earlier ServerHello that just happened
554 * to have matching server random...
555 */
556 if (ctx->hs->use_legacy)
557 return tls13_use_legacy_client(ctx);
558
559 if (!ctx->hs->hrr)
560 return 0;
561
562 if (!tls13_client_synthetic_handshake_message(ctx))
563 return 0;
564 if (!tls13_handshake_msg_record(ctx))
565 return 0;
566
567 ctx->hs->hrr = 0;
568
569 return 1;
570}
571
572int
518tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs) 573tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs)
519{ 574{
520 SSL *s = ctx->ssl; 575 SSL *s = ctx->ssl;
521 576
522 /* 577 /*
523 * We may have received a legacy (pre-TLSv1.3) server hello, 578 * We may have received a legacy (pre-TLSv1.3) ServerHello or a TLSv1.3
524 * a TLSv1.3 server hello or a TLSv1.3 hello retry request. 579 * ServerHello. HelloRetryRequests have already been handled.
525 */ 580 */
526 if (!tls13_server_hello_process(ctx, cbs)) 581 if (!tls13_server_hello_process(ctx, cbs))
527 return 0; 582 return 0;
528 583
529 tls1_transcript_unfreeze(s); 584 if (ctx->handshake_stage.hs_type & WITHOUT_HRR) {
530 585 tls1_transcript_unfreeze(s);
531 if (ctx->hs->hrr) { 586 if (!tls13_handshake_msg_record(ctx))
532 if (!tls13_client_synthetic_handshake_message(ctx))
533 return 0; 587 return 0;
534 } 588 }
535 589
536 if (!tls13_handshake_msg_record(ctx)) 590 if (ctx->hs->use_legacy) {
537 return 0; 591 if (!(ctx->handshake_stage.hs_type & WITHOUT_HRR))
538 592 return 0;
539 if (ctx->hs->use_legacy)
540 return tls13_use_legacy_client(ctx); 593 return tls13_use_legacy_client(ctx);
594 }
541 595
542 if (!ctx->hs->hrr) { 596 if (ctx->hs->hrr) {
543 if (!tls13_client_engage_record_protection(ctx)) 597 /* The server has sent two HelloRetryRequests. */
544 return 0; 598 ctx->alert = SSL_AD_ILLEGAL_PARAMETER;
599 return 0;
545 } 600 }
546 601
547 ctx->handshake_stage.hs_type |= NEGOTIATED; 602 if (!tls13_client_engage_record_protection(ctx))
548 if (ctx->hs->hrr) 603 return 0;
549 ctx->handshake_stage.hs_type |= WITH_HRR;
550 604
551 ctx->hs->hrr = 0; 605 ctx->handshake_stage.hs_type |= NEGOTIATED;
552 606
553 return 1; 607 return 1;
554} 608}
@@ -581,24 +635,6 @@ tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb)
581} 635}
582 636
583int 637int
584tls13_server_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs)
585{
586 if (!tls13_server_hello_process(ctx, cbs))
587 return 0;
588
589 if (ctx->hs->use_legacy)
590 return 0; /* XXX alert */
591
592 if (ctx->hs->hrr)
593 return 0; /* XXX alert */
594
595 if (!tls13_client_engage_record_protection(ctx))
596 return 0;
597
598 return 1;
599}
600
601int
602tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs) 638tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs)
603{ 639{
604 int alert_desc; 640 int alert_desc;