diff options
| author | beck <> | 2020-01-26 03:38:24 +0000 |
|---|---|---|
| committer | beck <> | 2020-01-26 03:38:24 +0000 |
| commit | c892a717bfcae95e43e5542131600505f63ebb6c (patch) | |
| tree | dc61e58f8b450b7e5af4a4a1f5207eb7c7e4e0fa | |
| parent | 16ae3b93865cf2df59efeef6b21d2f5b59759b28 (diff) | |
| download | openbsd-c892a717bfcae95e43e5542131600505f63ebb6c.tar.gz openbsd-c892a717bfcae95e43e5542131600505f63ebb6c.tar.bz2 openbsd-c892a717bfcae95e43e5542131600505f63ebb6c.zip | |
Add client certificate support for tls 1.3
ok jsing@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/tls13_client.c | 150 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_server.c | 14 |
2 files changed, 149 insertions, 15 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index 5dffd2d33a..74a4a4db69 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.35 2020/01/26 02:45:27 beck Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.36 2020/01/26 03:38:24 beck 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 | * |
| @@ -63,11 +63,13 @@ tls13_legacy_connect(SSL *ssl) | |||
| 63 | struct tls13_ctx *ctx = ssl->internal->tls13; | 63 | struct tls13_ctx *ctx = ssl->internal->tls13; |
| 64 | int ret; | 64 | int ret; |
| 65 | 65 | ||
| 66 | #ifdef TLS13_USE_LEGACY_CLIENT_AUTH | ||
| 66 | /* XXX drop back to legacy for client auth for now */ | 67 | /* XXX drop back to legacy for client auth for now */ |
| 67 | if (ssl->cert->key->privatekey != NULL) { | 68 | if (ssl->cert->key->privatekey != NULL) { |
| 68 | ssl->method = tls_legacy_client_method(); | 69 | ssl->method = tls_legacy_client_method(); |
| 69 | return ssl->method->internal->ssl_connect(ssl); | 70 | return ssl->method->internal->ssl_connect(ssl); |
| 70 | } | 71 | } |
| 72 | #endif | ||
| 71 | 73 | ||
| 72 | if (ctx == NULL) { | 74 | if (ctx == NULL) { |
| 73 | if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) { | 75 | if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) { |
| @@ -481,6 +483,9 @@ tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 481 | int | 483 | int |
| 482 | tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs) | 484 | tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs) |
| 483 | { | 485 | { |
| 486 | CBS cert_request_context; | ||
| 487 | int alert_desc; | ||
| 488 | |||
| 484 | /* | 489 | /* |
| 485 | * Thanks to poor state design in the RFC, this function can be called | 490 | * Thanks to poor state design in the RFC, this function can be called |
| 486 | * when we actually have a certificate message instead of a certificate | 491 | * when we actually have a certificate message instead of a certificate |
| @@ -492,8 +497,21 @@ tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 492 | return tls13_server_certificate_recv(ctx, cbs); | 497 | return tls13_server_certificate_recv(ctx, cbs); |
| 493 | } | 498 | } |
| 494 | 499 | ||
| 495 | /* XXX - unimplemented. */ | 500 | if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context)) |
| 501 | goto err; | ||
| 502 | if (CBS_len(&cert_request_context) != 0) | ||
| 503 | goto err; | ||
| 504 | |||
| 505 | if (!tlsext_client_parse(ctx->ssl, cbs, &alert_desc, SSL_TLSEXT_MSG_CR)) { | ||
| 506 | ctx->alert = alert_desc; | ||
| 507 | goto err; | ||
| 508 | } | ||
| 509 | |||
| 510 | return 1; | ||
| 496 | 511 | ||
| 512 | err: | ||
| 513 | if (ctx->alert == 0) | ||
| 514 | ctx->alert = TLS1_AD_DECODE_ERROR; | ||
| 497 | return 0; | 515 | return 0; |
| 498 | } | 516 | } |
| 499 | 517 | ||
| @@ -872,3 +890,131 @@ tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 872 | err: | 890 | err: |
| 873 | return ret; | 891 | return ret; |
| 874 | } | 892 | } |
| 893 | |||
| 894 | int | ||
| 895 | tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | ||
| 896 | { | ||
| 897 | SSL *s = ctx->ssl; | ||
| 898 | CBB cert_request_context, cert_list; | ||
| 899 | STACK_OF(X509) *chain; | ||
| 900 | CERT_PKEY *cpk; | ||
| 901 | X509 *cert; | ||
| 902 | int i, ret = 0; | ||
| 903 | |||
| 904 | /* XXX - Need to revisit certificate selection. */ | ||
| 905 | cpk = &s->cert->pkeys[SSL_PKEY_RSA_ENC]; | ||
| 906 | |||
| 907 | if ((chain = cpk->chain) == NULL) | ||
| 908 | chain = s->ctx->extra_certs; | ||
| 909 | |||
| 910 | if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context)) | ||
| 911 | goto err; | ||
| 912 | if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) | ||
| 913 | goto err; | ||
| 914 | |||
| 915 | if (cpk->x509 == NULL) | ||
| 916 | goto done; | ||
| 917 | |||
| 918 | if (!tls13_cert_add(&cert_list, cpk->x509)) | ||
| 919 | goto err; | ||
| 920 | |||
| 921 | for (i = 0; i < sk_X509_num(chain); i++) { | ||
| 922 | cert = sk_X509_value(chain, i); | ||
| 923 | if (!tls13_cert_add(&cert_list, cert)) | ||
| 924 | goto err; | ||
| 925 | } | ||
| 926 | |||
| 927 | ctx->handshake_stage.hs_type |= WITH_CCV; | ||
| 928 | done: | ||
| 929 | if (!CBB_flush(cbb)) | ||
| 930 | goto err; | ||
| 931 | |||
| 932 | ret = 1; | ||
| 933 | |||
| 934 | err: | ||
| 935 | return ret; | ||
| 936 | } | ||
| 937 | |||
| 938 | int | ||
| 939 | tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) | ||
| 940 | { | ||
| 941 | SSL *s = ctx->ssl; | ||
| 942 | const struct ssl_sigalg *sigalg = NULL; | ||
| 943 | uint8_t *sig = NULL, *sig_content = NULL; | ||
| 944 | size_t sig_len, sig_content_len; | ||
| 945 | EVP_MD_CTX *mdctx = NULL; | ||
| 946 | EVP_PKEY_CTX *pctx; | ||
| 947 | EVP_PKEY *pkey; | ||
| 948 | CERT_PKEY *cpk; | ||
| 949 | CBB sig_cbb; | ||
| 950 | int ret = 0; | ||
| 951 | |||
| 952 | memset(&sig_cbb, 0, sizeof(sig_cbb)); | ||
| 953 | |||
| 954 | /* XXX - Need to revisit certificate selection. */ | ||
| 955 | cpk = &s->cert->pkeys[SSL_PKEY_RSA_ENC]; | ||
| 956 | pkey = cpk->privatekey; | ||
| 957 | |||
| 958 | if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) { | ||
| 959 | /* XXX - SSL_R_SIGNATURE_ALGORITHMS_ERROR */ | ||
| 960 | goto err; | ||
| 961 | } | ||
| 962 | |||
| 963 | if (!CBB_init(&sig_cbb, 0)) | ||
| 964 | goto err; | ||
| 965 | if (!CBB_add_bytes(&sig_cbb, tls13_cert_verify_pad, | ||
| 966 | sizeof(tls13_cert_verify_pad))) | ||
| 967 | goto err; | ||
| 968 | if (!CBB_add_bytes(&sig_cbb, tls13_cert_client_verify_context, | ||
| 969 | strlen(tls13_cert_client_verify_context))) | ||
| 970 | goto err; | ||
| 971 | if (!CBB_add_u8(&sig_cbb, 0)) | ||
| 972 | goto err; | ||
| 973 | if (!CBB_add_bytes(&sig_cbb, ctx->hs->transcript_hash, | ||
| 974 | ctx->hs->transcript_hash_len)) | ||
| 975 | goto err; | ||
| 976 | if (!CBB_finish(&sig_cbb, &sig_content, &sig_content_len)) | ||
| 977 | goto err; | ||
| 978 | |||
| 979 | if ((mdctx = EVP_MD_CTX_new()) == NULL) | ||
| 980 | goto err; | ||
| 981 | if (!EVP_DigestSignInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) | ||
| 982 | goto err; | ||
| 983 | if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { | ||
| 984 | if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) | ||
| 985 | goto err; | ||
| 986 | if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) | ||
| 987 | goto err; | ||
| 988 | } | ||
| 989 | if (!EVP_DigestSignUpdate(mdctx, sig_content, sig_content_len)) | ||
| 990 | goto err; | ||
| 991 | if (EVP_DigestSignFinal(mdctx, NULL, &sig_len) <= 0) | ||
| 992 | goto err; | ||
| 993 | if ((sig = calloc(1, sig_len)) == NULL) | ||
| 994 | goto err; | ||
| 995 | if (EVP_DigestSignFinal(mdctx, sig, &sig_len) <= 0) | ||
| 996 | goto err; | ||
| 997 | |||
| 998 | if (!CBB_add_u16(cbb, sigalg->value)) | ||
| 999 | goto err; | ||
| 1000 | if (!CBB_add_u16_length_prefixed(cbb, &sig_cbb)) | ||
| 1001 | goto err; | ||
| 1002 | if (!CBB_add_bytes(&sig_cbb, sig, sig_len)) | ||
| 1003 | goto err; | ||
| 1004 | |||
| 1005 | if (!CBB_flush(cbb)) | ||
| 1006 | goto err; | ||
| 1007 | |||
| 1008 | ret = 1; | ||
| 1009 | |||
| 1010 | err: | ||
| 1011 | if (!ret && ctx->alert == 0) | ||
| 1012 | ctx->alert = TLS1_AD_INTERNAL_ERROR; | ||
| 1013 | |||
| 1014 | CBB_cleanup(&sig_cbb); | ||
| 1015 | EVP_MD_CTX_free(mdctx); | ||
| 1016 | free(sig_content); | ||
| 1017 | free(sig); | ||
| 1018 | |||
| 1019 | return ret; | ||
| 1020 | } | ||
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index 8ed2a6ea11..64c9741d7d 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.17 2020/01/26 02:45:27 beck Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.18 2020/01/26 03:38:24 beck 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> |
| @@ -312,24 +312,12 @@ tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | int | 314 | int |
| 315 | tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | ||
| 316 | { | ||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 320 | int | ||
| 321 | tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) | 315 | tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) |
| 322 | { | 316 | { |
| 323 | return 0; | 317 | return 0; |
| 324 | } | 318 | } |
| 325 | 319 | ||
| 326 | int | 320 | int |
| 327 | tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) | ||
| 328 | { | ||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | int | ||
| 333 | tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs) | 321 | tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs) |
| 334 | { | 322 | { |
| 335 | return 0; | 323 | return 0; |
