diff options
| author | jsing <> | 2020-05-29 18:00:10 +0000 | 
|---|---|---|
| committer | jsing <> | 2020-05-29 18:00:10 +0000 | 
| commit | 0ef5f8585d34b9d2de88692d29e28b65e20c9562 (patch) | |
| tree | e48fe26edb46ce97cad12ada94c4e75d004a357d /src/lib | |
| parent | ed3918023e9cb56cd8b5aee0647135d4088a65b0 (diff) | |
| download | openbsd-0ef5f8585d34b9d2de88692d29e28b65e20c9562.tar.gz openbsd-0ef5f8585d34b9d2de88692d29e28b65e20c9562.tar.bz2 openbsd-0ef5f8585d34b9d2de88692d29e28b65e20c9562.zip | |
Improve server certificate selection for TLSv1.3.
This allows an EC certificate to be selected and used, if the client
sigalgs would allow it.
With feedback from tb@
ok inoguchi@ tb@
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/libssl/ssl_locl.h | 18 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_server.c | 99 | 
2 files changed, 94 insertions, 23 deletions
| diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 046c4bba52..e7e3e56154 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_locl.h,v 1.276 2020/05/29 17:39:42 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.277 2020/05/29 18:00:10 jsing Exp $ */ | 
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 
| 3 | * All rights reserved. | 3 | * All rights reserved. | 
| 4 | * | 4 | * | 
| @@ -435,6 +435,12 @@ typedef struct ssl_handshake_st { | |||
| 435 | uint8_t *sigalgs; | 435 | uint8_t *sigalgs; | 
| 436 | } SSL_HANDSHAKE; | 436 | } SSL_HANDSHAKE; | 
| 437 | 437 | ||
| 438 | typedef struct cert_pkey_st { | ||
| 439 | X509 *x509; | ||
| 440 | EVP_PKEY *privatekey; | ||
| 441 | STACK_OF(X509) *chain; | ||
| 442 | } CERT_PKEY; | ||
| 443 | |||
| 438 | typedef struct ssl_handshake_tls13_st { | 444 | typedef struct ssl_handshake_tls13_st { | 
| 439 | uint16_t min_version; | 445 | uint16_t min_version; | 
| 440 | uint16_t max_version; | 446 | uint16_t max_version; | 
| @@ -443,6 +449,10 @@ typedef struct ssl_handshake_tls13_st { | |||
| 443 | int use_legacy; | 449 | int use_legacy; | 
| 444 | int hrr; | 450 | int hrr; | 
| 445 | 451 | ||
| 452 | /* Certificate and sigalg selected for use (static pointers). */ | ||
| 453 | const CERT_PKEY *cpk; | ||
| 454 | const struct ssl_sigalg *sigalg; | ||
| 455 | |||
| 446 | /* Version proposed by peer server. */ | 456 | /* Version proposed by peer server. */ | 
| 447 | uint16_t server_version; | 457 | uint16_t server_version; | 
| 448 | 458 | ||
| @@ -985,12 +995,6 @@ typedef struct dtls1_state_internal_st { | |||
| 985 | } DTLS1_STATE_INTERNAL; | 995 | } DTLS1_STATE_INTERNAL; | 
| 986 | #define D1I(s) (s->d1->internal) | 996 | #define D1I(s) (s->d1->internal) | 
| 987 | 997 | ||
| 988 | typedef struct cert_pkey_st { | ||
| 989 | X509 *x509; | ||
| 990 | EVP_PKEY *privatekey; | ||
| 991 | STACK_OF(X509) *chain; | ||
| 992 | } CERT_PKEY; | ||
| 993 | |||
| 994 | typedef struct cert_st { | 998 | typedef struct cert_st { | 
| 995 | /* Current active set */ | 999 | /* Current active set */ | 
| 996 | CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array | 1000 | CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array | 
| diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index 181ba583a0..e9fecdee26 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.54 2020/05/29 17:47:30 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.55 2020/05/29 18:00:10 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> | 
| @@ -16,6 +16,8 @@ | |||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
| 17 | */ | 17 | */ | 
| 18 | 18 | ||
| 19 | #include <openssl/x509v3.h> | ||
| 20 | |||
| 19 | #include "ssl_locl.h" | 21 | #include "ssl_locl.h" | 
| 20 | #include "ssl_tlsext.h" | 22 | #include "ssl_tlsext.h" | 
| 21 | 23 | ||
| @@ -448,19 +450,85 @@ tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb) | |||
| 448 | return 0; | 450 | return 0; | 
| 449 | } | 451 | } | 
| 450 | 452 | ||
| 453 | static int | ||
| 454 | tls13_server_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk, | ||
| 455 | int *ok, const struct ssl_sigalg **out_sigalg) | ||
| 456 | { | ||
| 457 | const struct ssl_sigalg *sigalg; | ||
| 458 | SSL *s = ctx->ssl; | ||
| 459 | |||
| 460 | *ok = 0; | ||
| 461 | *out_sigalg = NULL; | ||
| 462 | |||
| 463 | if (cpk->x509 == NULL || cpk->privatekey == NULL) | ||
| 464 | goto done; | ||
| 465 | |||
| 466 | if (!X509_check_purpose(cpk->x509, -1, 0)) | ||
| 467 | return 0; | ||
| 468 | |||
| 469 | /* | ||
| 470 | * The digitalSignature bit MUST be set if the Key Usage extension is | ||
| 471 | * present as per RFC 8446 section 4.4.2.2. | ||
| 472 | */ | ||
| 473 | if ((cpk->x509->ex_flags & EXFLAG_KUSAGE) && | ||
| 474 | !(cpk->x509->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) | ||
| 475 | goto done; | ||
| 476 | |||
| 477 | if ((sigalg = ssl_sigalg_select(s, cpk->privatekey)) == NULL) | ||
| 478 | goto done; | ||
| 479 | |||
| 480 | *ok = 1; | ||
| 481 | *out_sigalg = sigalg; | ||
| 482 | |||
| 483 | done: | ||
| 484 | return 1; | ||
| 485 | } | ||
| 486 | |||
| 487 | static int | ||
| 488 | tls13_server_select_certificate(struct tls13_ctx *ctx, CERT_PKEY **out_cpk, | ||
| 489 | const struct ssl_sigalg **out_sigalg) | ||
| 490 | { | ||
| 491 | SSL *s = ctx->ssl; | ||
| 492 | const struct ssl_sigalg *sigalg; | ||
| 493 | CERT_PKEY *cpk; | ||
| 494 | int cert_ok; | ||
| 495 | |||
| 496 | *out_cpk = NULL; | ||
| 497 | *out_sigalg = NULL; | ||
| 498 | |||
| 499 | cpk = &s->cert->pkeys[SSL_PKEY_ECC]; | ||
| 500 | if (!tls13_server_check_certificate(ctx, cpk, &cert_ok, &sigalg)) | ||
| 501 | return 0; | ||
| 502 | if (cert_ok) | ||
| 503 | goto done; | ||
| 504 | |||
| 505 | cpk = &s->cert->pkeys[SSL_PKEY_RSA]; | ||
| 506 | if (!tls13_server_check_certificate(ctx, cpk, &cert_ok, &sigalg)) | ||
| 507 | return 0; | ||
| 508 | if (cert_ok) | ||
| 509 | goto done; | ||
| 510 | |||
| 511 | return 0; | ||
| 512 | |||
| 513 | done: | ||
| 514 | *out_cpk = cpk; | ||
| 515 | *out_sigalg = sigalg; | ||
| 516 | |||
| 517 | return 1; | ||
| 518 | } | ||
| 519 | |||
| 451 | int | 520 | int | 
| 452 | tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | 521 | tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | 
| 453 | { | 522 | { | 
| 454 | SSL *s = ctx->ssl; | 523 | SSL *s = ctx->ssl; | 
| 455 | CBB cert_request_context, cert_list; | 524 | CBB cert_request_context, cert_list; | 
| 525 | const struct ssl_sigalg *sigalg; | ||
| 456 | STACK_OF(X509) *chain; | 526 | STACK_OF(X509) *chain; | 
| 457 | CERT_PKEY *cpk; | 527 | CERT_PKEY *cpk; | 
| 458 | X509 *cert; | 528 | X509 *cert; | 
| 459 | int i, ret = 0; | 529 | int i, ret = 0; | 
| 460 | 530 | ||
| 461 | /* XXX - Need to revisit certificate selection. */ | 531 | if (!tls13_server_select_certificate(ctx, &cpk, &sigalg)) { | 
| 462 | cpk = &s->cert->pkeys[SSL_PKEY_RSA]; | ||
| 463 | if (cpk->x509 == NULL) { | ||
| 464 | /* A server must always provide a certificate. */ | 532 | /* A server must always provide a certificate. */ | 
| 465 | ctx->alert = TLS13_ALERT_HANDSHAKE_FAILURE; | 533 | ctx->alert = TLS13_ALERT_HANDSHAKE_FAILURE; | 
| 466 | tls13_set_errorx(ctx, TLS13_ERR_NO_CERTIFICATE, 0, | 534 | tls13_set_errorx(ctx, TLS13_ERR_NO_CERTIFICATE, 0, | 
| @@ -468,6 +536,9 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | |||
| 468 | goto err; | 536 | goto err; | 
| 469 | } | 537 | } | 
| 470 | 538 | ||
| 539 | ctx->hs->cpk = cpk; | ||
| 540 | ctx->hs->sigalg = sigalg; | ||
| 541 | |||
| 471 | if ((chain = cpk->chain) == NULL) | 542 | if ((chain = cpk->chain) == NULL) | 
| 472 | chain = s->ctx->extra_certs; | 543 | chain = s->ctx->extra_certs; | 
| 473 | 544 | ||
| @@ -502,27 +573,23 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | |||
| 502 | int | 573 | int | 
| 503 | tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) | 574 | tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) | 
| 504 | { | 575 | { | 
| 505 | SSL *s = ctx->ssl; | 576 | const struct ssl_sigalg *sigalg; | 
| 506 | const struct ssl_sigalg *sigalg = NULL; | ||
| 507 | uint8_t *sig = NULL, *sig_content = NULL; | 577 | uint8_t *sig = NULL, *sig_content = NULL; | 
| 508 | size_t sig_len, sig_content_len; | 578 | size_t sig_len, sig_content_len; | 
| 509 | EVP_MD_CTX *mdctx = NULL; | 579 | EVP_MD_CTX *mdctx = NULL; | 
| 510 | EVP_PKEY_CTX *pctx; | 580 | EVP_PKEY_CTX *pctx; | 
| 511 | EVP_PKEY *pkey; | 581 | EVP_PKEY *pkey; | 
| 512 | CERT_PKEY *cpk; | 582 | const CERT_PKEY *cpk; | 
| 513 | CBB sig_cbb; | 583 | CBB sig_cbb; | 
| 514 | int ret = 0; | 584 | int ret = 0; | 
| 515 | 585 | ||
| 516 | memset(&sig_cbb, 0, sizeof(sig_cbb)); | 586 | memset(&sig_cbb, 0, sizeof(sig_cbb)); | 
| 517 | 587 | ||
| 518 | /* XXX - Need to revisit certificate selection. */ | 588 | if ((cpk = ctx->hs->cpk) == NULL) | 
| 519 | cpk = &s->cert->pkeys[SSL_PKEY_RSA]; | 589 | goto err; | 
| 520 | pkey = cpk->privatekey; | 590 | if ((sigalg = ctx->hs->sigalg) == NULL) | 
| 521 | |||
| 522 | if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) { | ||
| 523 | /* XXX - SSL_R_SIGNATURE_ALGORITHMS_ERROR */ | ||
| 524 | goto err; | 591 | goto err; | 
| 525 | } | 592 | pkey = cpk->privatekey; | 
| 526 | 593 | ||
| 527 | if (!CBB_init(&sig_cbb, 0)) | 594 | if (!CBB_init(&sig_cbb, 0)) | 
| 528 | goto err; | 595 | goto err; | 
| @@ -829,9 +896,9 @@ tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 829 | ret = 1; | 896 | ret = 1; | 
| 830 | 897 | ||
| 831 | err: | 898 | err: | 
| 832 | if (!ret && ctx->alert == 0) { | 899 | if (!ret && ctx->alert == 0) | 
| 833 | ctx->alert = TLS13_ALERT_DECODE_ERROR; | 900 | ctx->alert = TLS13_ALERT_DECODE_ERROR; | 
| 834 | } | 901 | |
| 835 | CBB_cleanup(&cbb); | 902 | CBB_cleanup(&cbb); | 
| 836 | EVP_MD_CTX_free(mdctx); | 903 | EVP_MD_CTX_free(mdctx); | 
| 837 | free(sig_content); | 904 | free(sig_content); | 
