diff options
author | jsing <> | 2020-01-24 08:21:24 +0000 |
---|---|---|
committer | jsing <> | 2020-01-24 08:21:24 +0000 |
commit | 659ab6a1018ad8fc2cd5c5801af96bdb482f623b (patch) | |
tree | b029df2949c6e8b7fb725c02cd0e29b13384c989 /src | |
parent | 79b127f70a38c4ebb13fe6c972a30467c4162485 (diff) | |
download | openbsd-659ab6a1018ad8fc2cd5c5801af96bdb482f623b.tar.gz openbsd-659ab6a1018ad8fc2cd5c5801af96bdb482f623b.tar.bz2 openbsd-659ab6a1018ad8fc2cd5c5801af96bdb482f623b.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 | } |