diff options
author | jsing <> | 2020-02-06 13:19:18 +0000 |
---|---|---|
committer | jsing <> | 2020-02-06 13:19:18 +0000 |
commit | d69e69c9cb2bd0bf58a6ab0f826b459e7208214b (patch) | |
tree | 1a34cff2cb69be3ab6e85e9f4c2645339e0d35d0 /src | |
parent | 0a603f6ba38c0a87a61171ce8cf9545da70287d4 (diff) | |
download | openbsd-d69e69c9cb2bd0bf58a6ab0f826b459e7208214b.tar.gz openbsd-d69e69c9cb2bd0bf58a6ab0f826b459e7208214b.tar.bz2 openbsd-d69e69c9cb2bd0bf58a6ab0f826b459e7208214b.zip |
Add support for handling hello retry requests in the TLSv1.3 client.
In the case of a hello retry request, we need to replace the client hello
with a synthetic handshake message, switch key share to that selected by
the server, build and send a new client hello, then process the resulting
server hello.
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_client.c | 105 |
1 files changed, 100 insertions, 5 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index d9ef85753e..dd123f867b 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.42 2020/02/05 17:30:30 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.43 2020/02/06 13:19:18 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 | * |
@@ -233,6 +233,8 @@ tls13_client_hello_sent(struct tls13_ctx *ctx) | |||
233 | tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION); | 233 | tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION); |
234 | tls13_record_layer_allow_ccs(ctx->rl, 1); | 234 | tls13_record_layer_allow_ccs(ctx->rl, 1); |
235 | 235 | ||
236 | tls1_transcript_freeze(ctx->ssl); | ||
237 | |||
236 | return 1; | 238 | return 1; |
237 | } | 239 | } |
238 | 240 | ||
@@ -400,6 +402,49 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) | |||
400 | } | 402 | } |
401 | 403 | ||
402 | static int | 404 | static int |
405 | tls13_client_synthetic_handshake_message(struct tls13_ctx *ctx) | ||
406 | { | ||
407 | struct tls13_handshake_msg *hm = NULL; | ||
408 | unsigned char buf[EVP_MAX_MD_SIZE]; | ||
409 | size_t hash_len; | ||
410 | CBB cbb; | ||
411 | CBS cbs; | ||
412 | SSL *s = ctx->ssl; | ||
413 | int ret = 0; | ||
414 | |||
415 | /* | ||
416 | * Replace ClientHello with synthetic handshake message - see | ||
417 | * RFC 8446 section 4.4.1. | ||
418 | */ | ||
419 | if (!tls1_transcript_hash_init(s)) | ||
420 | goto err; | ||
421 | if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len)) | ||
422 | goto err; | ||
423 | |||
424 | if ((hm = tls13_handshake_msg_new()) == NULL) | ||
425 | goto err; | ||
426 | if (!tls13_handshake_msg_start(hm, &cbb, TLS13_MT_MESSAGE_HASH)) | ||
427 | goto err; | ||
428 | if (!CBB_add_bytes(&cbb, buf, hash_len)) | ||
429 | goto err; | ||
430 | if (!tls13_handshake_msg_finish(hm)) | ||
431 | goto err; | ||
432 | |||
433 | tls13_handshake_msg_data(hm, &cbs); | ||
434 | |||
435 | tls1_transcript_reset(ctx->ssl); | ||
436 | if (!tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs))) | ||
437 | goto err; | ||
438 | |||
439 | ret = 1; | ||
440 | |||
441 | err: | ||
442 | tls13_handshake_msg_free(hm); | ||
443 | |||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | static int | ||
403 | tls13_client_engage_record_protection(struct tls13_ctx *ctx) | 448 | tls13_client_engage_record_protection(struct tls13_ctx *ctx) |
404 | { | 449 | { |
405 | struct tls13_secrets *secrets; | 450 | struct tls13_secrets *secrets; |
@@ -469,6 +514,8 @@ tls13_client_engage_record_protection(struct tls13_ctx *ctx) | |||
469 | int | 514 | int |
470 | tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs) | 515 | tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs) |
471 | { | 516 | { |
517 | SSL *s = ctx->ssl; | ||
518 | |||
472 | /* | 519 | /* |
473 | * We may have received a legacy (pre-TLSv1.3) server hello, | 520 | * We may have received a legacy (pre-TLSv1.3) server hello, |
474 | * a TLSv1.3 server hello or a TLSv1.3 hello retry request. | 521 | * a TLSv1.3 server hello or a TLSv1.3 hello retry request. |
@@ -476,11 +523,23 @@ tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
476 | if (!tls13_server_hello_process(ctx, cbs)) | 523 | if (!tls13_server_hello_process(ctx, cbs)) |
477 | return 0; | 524 | return 0; |
478 | 525 | ||
526 | tls1_transcript_unfreeze(s); | ||
527 | |||
528 | if (ctx->hs->hrr) { | ||
529 | if (!tls13_client_synthetic_handshake_message(ctx)) | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | if (!tls13_handshake_msg_record(ctx)) | ||
534 | return 0; | ||
535 | |||
479 | if (ctx->hs->use_legacy) | 536 | if (ctx->hs->use_legacy) |
480 | return tls13_use_legacy_client(ctx); | 537 | return tls13_use_legacy_client(ctx); |
481 | 538 | ||
482 | if (!tls13_client_engage_record_protection(ctx)) | 539 | if (!ctx->hs->hrr) { |
483 | return 0; | 540 | if (!tls13_client_engage_record_protection(ctx)) |
541 | return 0; | ||
542 | } | ||
484 | 543 | ||
485 | ctx->handshake_stage.hs_type |= NEGOTIATED; | 544 | ctx->handshake_stage.hs_type |= NEGOTIATED; |
486 | if (ctx->hs->hrr) | 545 | if (ctx->hs->hrr) |
@@ -494,13 +553,49 @@ tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
494 | int | 553 | int |
495 | tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb) | 554 | tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb) |
496 | { | 555 | { |
497 | return 0; | 556 | int nid; |
557 | |||
558 | /* | ||
559 | * Ensure that the server supported group is not the same | ||
560 | * as the one we previously offered and that it was one that | ||
561 | * we listed in our supported groups. | ||
562 | */ | ||
563 | if (ctx->hs->server_group == tls13_key_share_group(ctx->hs->key_share)) | ||
564 | return 0; /* XXX alert */ | ||
565 | if ((nid = tls1_ec_curve_id2nid(ctx->hs->server_group)) == 0) | ||
566 | return 0; | ||
567 | if (nid != NID_X25519 && nid != NID_X9_62_prime256v1 && nid != NID_secp384r1) | ||
568 | return 0; /* XXX alert */ | ||
569 | |||
570 | /* Switch to new key share. */ | ||
571 | tls13_key_share_free(ctx->hs->key_share); | ||
572 | if ((ctx->hs->key_share = tls13_key_share_new(nid)) == NULL) | ||
573 | return 0; | ||
574 | if (!tls13_key_share_generate(ctx->hs->key_share)) | ||
575 | return 0; | ||
576 | |||
577 | if (!tls13_client_hello_build(ctx, cbb)) | ||
578 | return 0; | ||
579 | |||
580 | return 1; | ||
498 | } | 581 | } |
499 | 582 | ||
500 | int | 583 | int |
501 | tls13_server_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs) | 584 | tls13_server_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs) |
502 | { | 585 | { |
503 | return 0; | 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; | ||
504 | } | 599 | } |
505 | 600 | ||
506 | int | 601 | int |