diff options
| author | jsing <> | 2020-01-24 08:21:24 +0000 |
|---|---|---|
| committer | jsing <> | 2020-01-24 08:21:24 +0000 |
| commit | 9cdf522cbbcfe7a838754388ced1226cb5f6440a (patch) | |
| tree | b029df2949c6e8b7fb725c02cd0e29b13384c989 /src | |
| parent | a5c73b953c2cae57930e88d747efc6e34adbb9cb (diff) | |
| download | openbsd-9cdf522cbbcfe7a838754388ced1226cb5f6440a.tar.gz openbsd-9cdf522cbbcfe7a838754388ced1226cb5f6440a.tar.bz2 openbsd-9cdf522cbbcfe7a838754388ced1226cb5f6440a.zip | |
Complete the initial TLSv1.3 implementation.
ok beck@ tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/tls13_handshake.c | 3 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_internal.h | 3 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_server.c | 308 |
3 files changed, 300 insertions, 14 deletions
diff --git a/src/lib/libssl/tls13_handshake.c b/src/lib/libssl/tls13_handshake.c index 2c5b72a912..29a22225f7 100644 --- a/src/lib/libssl/tls13_handshake.c +++ b/src/lib/libssl/tls13_handshake.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_handshake.c,v 1.43 2020/01/24 06:45:09 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_handshake.c,v 1.44 2020/01/24 08:21:24 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> |
| 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> |
| @@ -141,6 +141,7 @@ struct tls13_handshake_action state_machine[] = { | |||
| 141 | .recv_preserve_transcript_hash = 1, | 141 | .recv_preserve_transcript_hash = 1, |
| 142 | .send_preserve_transcript_hash = 1, | 142 | .send_preserve_transcript_hash = 1, |
| 143 | .send = tls13_server_finished_send, | 143 | .send = tls13_server_finished_send, |
| 144 | .sent = tls13_server_finished_sent, | ||
| 144 | .recv = tls13_server_finished_recv, | 145 | .recv = tls13_server_finished_recv, |
| 145 | }, | 146 | }, |
| 146 | [APPLICATION_DATA] = { | 147 | [APPLICATION_DATA] = { |
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index b42889712f..4ff2df6e97 100644 --- a/src/lib/libssl/tls13_internal.h +++ b/src/lib/libssl/tls13_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_internal.h,v 1.52 2020/01/24 04:43:09 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.53 2020/01/24 08:21:24 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> |
| 4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> |
| @@ -293,6 +293,7 @@ int tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb); | |||
| 293 | int tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs); | 293 | int tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs); |
| 294 | int tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs); | 294 | int tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs); |
| 295 | int tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb); | 295 | int tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb); |
| 296 | int tls13_server_finished_sent(struct tls13_ctx *ctx); | ||
| 296 | 297 | ||
| 297 | void tls13_error_clear(struct tls13_error *error); | 298 | void tls13_error_clear(struct tls13_error *error); |
| 298 | 299 | ||
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index a5a39d092c..628e824313 100644 --- a/src/lib/libssl/tls13_server.c +++ b/src/lib/libssl/tls13_server.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_server.c,v 1.15 2020/01/24 04:47:13 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.16 2020/01/24 08:21:24 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| @@ -336,14 +336,6 @@ tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | int | 338 | int |
| 339 | tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs) | ||
| 340 | { | ||
| 341 | tls13_record_layer_allow_ccs(ctx->rl, 0); | ||
| 342 | |||
| 343 | return 0; | ||
| 344 | } | ||
| 345 | |||
| 346 | int | ||
| 347 | tls13_client_key_update_send(struct tls13_ctx *ctx, CBB *cbb) | 339 | tls13_client_key_update_send(struct tls13_ctx *ctx, CBB *cbb) |
| 348 | { | 340 | { |
| 349 | return 0; | 341 | return 0; |
| @@ -484,12 +476,76 @@ tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb) | |||
| 484 | return 0; | 476 | return 0; |
| 485 | } | 477 | } |
| 486 | 478 | ||
| 479 | static int | ||
| 480 | tls13_cert_add(CBB *cbb, X509 *cert) | ||
| 481 | { | ||
| 482 | CBB cert_data, cert_exts; | ||
| 483 | uint8_t *data; | ||
| 484 | int cert_len; | ||
| 485 | |||
| 486 | if ((cert_len = i2d_X509(cert, NULL)) < 0) | ||
| 487 | return 0; | ||
| 488 | |||
| 489 | if (!CBB_add_u24_length_prefixed(cbb, &cert_data)) | ||
| 490 | return 0; | ||
| 491 | if (!CBB_add_space(&cert_data, &data, cert_len)) | ||
| 492 | return 0; | ||
| 493 | if (i2d_X509(cert, &data) != cert_len) | ||
| 494 | return 0; | ||
| 495 | |||
| 496 | if (!CBB_add_u16_length_prefixed(cbb, &cert_exts)) | ||
| 497 | return 0; | ||
| 498 | |||
| 499 | if (!CBB_flush(cbb)) | ||
| 500 | return 0; | ||
| 501 | |||
| 502 | return 1; | ||
| 503 | } | ||
| 504 | |||
| 487 | int | 505 | int |
| 488 | tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | 506 | tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) |
| 489 | { | 507 | { |
| 490 | return 0; | 508 | SSL *s = ctx->ssl; |
| 509 | CBB cert_request_context, cert_list; | ||
| 510 | STACK_OF(X509) *chain; | ||
| 511 | CERT_PKEY *cpk; | ||
| 512 | X509 *cert; | ||
| 513 | int i, ret = 0; | ||
| 514 | |||
| 515 | /* XXX - Need to revisit certificate selection. */ | ||
| 516 | cpk = &s->cert->pkeys[SSL_PKEY_RSA_ENC]; | ||
| 517 | |||
| 518 | if ((chain = cpk->chain) == NULL) | ||
| 519 | chain = s->ctx->extra_certs; | ||
| 520 | |||
| 521 | if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context)) | ||
| 522 | goto err; | ||
| 523 | if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) | ||
| 524 | goto err; | ||
| 525 | |||
| 526 | if (cpk->x509 == NULL) | ||
| 527 | goto done; | ||
| 528 | |||
| 529 | if (!tls13_cert_add(&cert_list, cpk->x509)) | ||
| 530 | goto err; | ||
| 531 | |||
| 532 | for (i = 0; i < sk_X509_num(chain); i++) { | ||
| 533 | cert = sk_X509_value(chain, i); | ||
| 534 | if (!tls13_cert_add(&cert_list, cert)) | ||
| 535 | goto err; | ||
| 536 | } | ||
| 537 | |||
| 538 | done: | ||
| 539 | if (!CBB_flush(cbb)) | ||
| 540 | goto err; | ||
| 541 | |||
| 542 | ret = 1; | ||
| 543 | |||
| 544 | err: | ||
| 545 | return ret; | ||
| 491 | } | 546 | } |
| 492 | 547 | ||
| 548 | /* XXX - move up. */ | ||
| 493 | int | 549 | int |
| 494 | tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb) | 550 | tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb) |
| 495 | { | 551 | { |
| @@ -508,14 +564,242 @@ tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb) | |||
| 508 | return 0; | 564 | return 0; |
| 509 | } | 565 | } |
| 510 | 566 | ||
| 567 | /* | ||
| 568 | * Certificate Verify padding - RFC 8446 section 4.4.3. | ||
| 569 | */ | ||
| 570 | static uint8_t cert_verify_pad[64] = { | ||
| 571 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 572 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 573 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 574 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 575 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 576 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 577 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 578 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
| 579 | }; | ||
| 580 | |||
| 581 | static uint8_t server_cert_verify_context[] = "TLS 1.3, server CertificateVerify"; | ||
| 582 | |||
| 511 | int | 583 | int |
| 512 | tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) | 584 | tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) |
| 513 | { | 585 | { |
| 514 | return 0; | 586 | SSL *s = ctx->ssl; |
| 587 | const struct ssl_sigalg *sigalg = NULL; | ||
| 588 | uint8_t *sig = NULL, *sig_content = NULL; | ||
| 589 | size_t sig_len, sig_content_len; | ||
| 590 | EVP_MD_CTX *mdctx = NULL; | ||
| 591 | EVP_PKEY_CTX *pctx; | ||
| 592 | EVP_PKEY *pkey; | ||
| 593 | CERT_PKEY *cpk; | ||
| 594 | CBB sig_cbb; | ||
| 595 | int ret = 0; | ||
| 596 | |||
| 597 | memset(&sig_cbb, 0, sizeof(sig_cbb)); | ||
| 598 | |||
| 599 | /* XXX - Need to revisit certificate selection. */ | ||
| 600 | cpk = &s->cert->pkeys[SSL_PKEY_RSA_ENC]; | ||
| 601 | pkey = cpk->privatekey; | ||
| 602 | |||
| 603 | if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) { | ||
| 604 | /* XXX - SSL_R_SIGNATURE_ALGORITHMS_ERROR */ | ||
| 605 | goto err; | ||
| 606 | } | ||
| 607 | |||
| 608 | if (!CBB_init(&sig_cbb, 0)) | ||
| 609 | goto err; | ||
| 610 | if (!CBB_add_bytes(&sig_cbb, cert_verify_pad, sizeof(cert_verify_pad))) | ||
| 611 | goto err; | ||
| 612 | if (!CBB_add_bytes(&sig_cbb, server_cert_verify_context, | ||
| 613 | strlen(server_cert_verify_context))) | ||
| 614 | goto err; | ||
| 615 | if (!CBB_add_u8(&sig_cbb, 0)) | ||
| 616 | goto err; | ||
| 617 | if (!CBB_add_bytes(&sig_cbb, ctx->hs->transcript_hash, | ||
| 618 | ctx->hs->transcript_hash_len)) | ||
| 619 | goto err; | ||
| 620 | if (!CBB_finish(&sig_cbb, &sig_content, &sig_content_len)) | ||
| 621 | goto err; | ||
| 622 | |||
| 623 | if ((mdctx = EVP_MD_CTX_new()) == NULL) | ||
| 624 | goto err; | ||
| 625 | if (!EVP_DigestSignInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) | ||
| 626 | goto err; | ||
| 627 | if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { | ||
| 628 | if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) | ||
| 629 | goto err; | ||
| 630 | if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) | ||
| 631 | goto err; | ||
| 632 | } | ||
| 633 | if (!EVP_DigestSignUpdate(mdctx, sig_content, sig_content_len)) | ||
| 634 | goto err; | ||
| 635 | if (EVP_DigestSignFinal(mdctx, NULL, &sig_len) <= 0) | ||
| 636 | goto err; | ||
| 637 | if ((sig = calloc(1, sig_len)) == NULL) | ||
| 638 | goto err; | ||
| 639 | if (EVP_DigestSignFinal(mdctx, sig, &sig_len) <= 0) | ||
| 640 | goto err; | ||
| 641 | |||
| 642 | if (!CBB_add_u16(cbb, sigalg->value)) | ||
| 643 | goto err; | ||
| 644 | if (!CBB_add_u16_length_prefixed(cbb, &sig_cbb)) | ||
| 645 | goto err; | ||
| 646 | if (!CBB_add_bytes(&sig_cbb, sig, sig_len)) | ||
| 647 | goto err; | ||
| 648 | |||
| 649 | if (!CBB_flush(cbb)) | ||
| 650 | goto err; | ||
| 651 | |||
| 652 | ret = 1; | ||
| 653 | |||
| 654 | err: | ||
| 655 | if (!ret && ctx->alert == 0) | ||
| 656 | ctx->alert = TLS1_AD_INTERNAL_ERROR; | ||
| 657 | |||
| 658 | CBB_cleanup(&sig_cbb); | ||
| 659 | EVP_MD_CTX_free(mdctx); | ||
| 660 | free(sig_content); | ||
| 661 | free(sig); | ||
| 662 | |||
| 663 | return ret; | ||
| 515 | } | 664 | } |
| 516 | 665 | ||
| 517 | int | 666 | int |
| 518 | tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb) | 667 | tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb) |
| 519 | { | 668 | { |
| 520 | return 0; | 669 | struct tls13_secrets *secrets = ctx->hs->secrets; |
| 670 | struct tls13_secret context = { .data = "", .len = 0 }; | ||
| 671 | struct tls13_secret finished_key; | ||
| 672 | uint8_t transcript_hash[EVP_MAX_MD_SIZE]; | ||
| 673 | size_t transcript_hash_len; | ||
| 674 | uint8_t key[EVP_MAX_MD_SIZE]; | ||
| 675 | uint8_t *verify_data; | ||
| 676 | size_t hmac_len; | ||
| 677 | unsigned int hlen; | ||
| 678 | HMAC_CTX *hmac_ctx = NULL; | ||
| 679 | int ret = 0; | ||
| 680 | |||
| 681 | finished_key.data = key; | ||
| 682 | finished_key.len = EVP_MD_size(ctx->hash); | ||
| 683 | |||
| 684 | if (!tls13_hkdf_expand_label(&finished_key, ctx->hash, | ||
| 685 | &secrets->server_handshake_traffic, "finished", | ||
| 686 | &context)) | ||
| 687 | goto err; | ||
| 688 | |||
| 689 | if (!tls1_transcript_hash_value(ctx->ssl, transcript_hash, | ||
| 690 | sizeof(transcript_hash), &transcript_hash_len)) | ||
| 691 | goto err; | ||
| 692 | |||
| 693 | if ((hmac_ctx = HMAC_CTX_new()) == NULL) | ||
| 694 | goto err; | ||
| 695 | if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len, | ||
| 696 | ctx->hash, NULL)) | ||
| 697 | goto err; | ||
| 698 | if (!HMAC_Update(hmac_ctx, transcript_hash, transcript_hash_len)) | ||
| 699 | goto err; | ||
| 700 | |||
| 701 | hmac_len = HMAC_size(hmac_ctx); | ||
| 702 | if (!CBB_add_space(cbb, &verify_data, hmac_len)) | ||
| 703 | goto err; | ||
| 704 | if (!HMAC_Final(hmac_ctx, verify_data, &hlen)) | ||
| 705 | goto err; | ||
| 706 | if (hlen != hmac_len) | ||
| 707 | goto err; | ||
| 708 | |||
| 709 | ret = 1; | ||
| 710 | |||
| 711 | err: | ||
| 712 | HMAC_CTX_free(hmac_ctx); | ||
| 713 | |||
| 714 | return ret; | ||
| 715 | } | ||
| 716 | |||
| 717 | int | ||
| 718 | tls13_server_finished_sent(struct tls13_ctx *ctx) | ||
| 719 | { | ||
| 720 | struct tls13_secrets *secrets = ctx->hs->secrets; | ||
| 721 | struct tls13_secret context = { .data = "", .len = 0 }; | ||
| 722 | |||
| 723 | /* | ||
| 724 | * Derive application traffic keys. | ||
| 725 | */ | ||
| 726 | context.data = ctx->hs->transcript_hash; | ||
| 727 | context.len = ctx->hs->transcript_hash_len; | ||
| 728 | |||
| 729 | if (!tls13_derive_application_secrets(secrets, &context)) | ||
| 730 | return 0; | ||
| 731 | |||
| 732 | /* | ||
| 733 | * Any records following the server finished message must be encrypted | ||
| 734 | * using the server application traffic keys. | ||
| 735 | */ | ||
| 736 | return tls13_record_layer_set_write_traffic_key(ctx->rl, | ||
| 737 | &secrets->server_application_traffic); | ||
| 738 | } | ||
| 739 | |||
| 740 | int | ||
| 741 | tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs) | ||
| 742 | { | ||
| 743 | struct tls13_secrets *secrets = ctx->hs->secrets; | ||
| 744 | struct tls13_secret context = { .data = "", .len = 0 }; | ||
| 745 | struct tls13_secret finished_key; | ||
| 746 | uint8_t *verify_data = NULL; | ||
| 747 | size_t verify_data_len; | ||
| 748 | uint8_t key[EVP_MAX_MD_SIZE]; | ||
| 749 | HMAC_CTX *hmac_ctx = NULL; | ||
| 750 | unsigned int hlen; | ||
| 751 | int ret = 0; | ||
| 752 | |||
| 753 | /* | ||
| 754 | * Verify client finished. | ||
| 755 | */ | ||
| 756 | finished_key.data = key; | ||
| 757 | finished_key.len = EVP_MD_size(ctx->hash); | ||
| 758 | |||
| 759 | if (!tls13_hkdf_expand_label(&finished_key, ctx->hash, | ||
| 760 | &secrets->client_handshake_traffic, "finished", | ||
| 761 | &context)) | ||
| 762 | goto err; | ||
| 763 | |||
| 764 | if ((hmac_ctx = HMAC_CTX_new()) == NULL) | ||
| 765 | goto err; | ||
| 766 | if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len, | ||
| 767 | ctx->hash, NULL)) | ||
| 768 | goto err; | ||
| 769 | if (!HMAC_Update(hmac_ctx, ctx->hs->transcript_hash, | ||
| 770 | ctx->hs->transcript_hash_len)) | ||
| 771 | goto err; | ||
| 772 | verify_data_len = HMAC_size(hmac_ctx); | ||
| 773 | if ((verify_data = calloc(1, verify_data_len)) == NULL) | ||
| 774 | goto err; | ||
| 775 | if (!HMAC_Final(hmac_ctx, verify_data, &hlen)) | ||
| 776 | goto err; | ||
| 777 | if (hlen != verify_data_len) | ||
| 778 | goto err; | ||
| 779 | |||
| 780 | if (!CBS_mem_equal(cbs, verify_data, verify_data_len)) { | ||
| 781 | ctx->alert = TLS1_AD_DECRYPTION_FAILED; | ||
| 782 | goto err; | ||
| 783 | } | ||
| 784 | |||
| 785 | if (!CBS_skip(cbs, verify_data_len)) | ||
| 786 | goto err; | ||
| 787 | |||
| 788 | /* | ||
| 789 | * Any records following the client finished message must be encrypted | ||
| 790 | * using the client application traffic keys. | ||
| 791 | */ | ||
| 792 | if (!tls13_record_layer_set_read_traffic_key(ctx->rl, | ||
| 793 | &secrets->client_application_traffic)) | ||
| 794 | goto err; | ||
| 795 | |||
| 796 | tls13_record_layer_allow_ccs(ctx->rl, 0); | ||
| 797 | |||
| 798 | ret = 1; | ||
| 799 | |||
| 800 | err: | ||
| 801 | HMAC_CTX_free(hmac_ctx); | ||
| 802 | free(verify_data); | ||
| 803 | |||
| 804 | return ret; | ||
| 521 | } | 805 | } |
