diff options
author | tb <> | 2020-06-04 18:41:42 +0000 |
---|---|---|
committer | tb <> | 2020-06-04 18:41:42 +0000 |
commit | f72963c511984aa80063f765f212f8d17b14e3ce (patch) | |
tree | 003de66accc82ad2651bfab148c0c527e609d655 /src | |
parent | 045f7a6a412c8db9e615d93850130c5eee7f9d73 (diff) | |
download | openbsd-f72963c511984aa80063f765f212f8d17b14e3ce.tar.gz openbsd-f72963c511984aa80063f765f212f8d17b14e3ce.tar.bz2 openbsd-f72963c511984aa80063f765f212f8d17b14e3ce.zip |
Improve client certificate selection for TLSv1.3
This allows clients to use EC certificates.
ok inoguchi, jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_client.c | 96 |
1 files changed, 80 insertions, 16 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index d7a912a7e1..e2f61f6c08 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.64 2020/05/23 11:58:46 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.65 2020/06/04 18:41:42 tb 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 | * |
@@ -826,30 +826,98 @@ tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
826 | return ret; | 826 | return ret; |
827 | } | 827 | } |
828 | 828 | ||
829 | static int | ||
830 | tls13_client_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk, | ||
831 | int *ok, const struct ssl_sigalg **out_sigalg) | ||
832 | { | ||
833 | const struct ssl_sigalg *sigalg; | ||
834 | SSL *s = ctx->ssl; | ||
835 | |||
836 | *ok = 0; | ||
837 | *out_sigalg = NULL; | ||
838 | |||
839 | if (cpk->x509 == NULL || cpk->privatekey == NULL) | ||
840 | goto done; | ||
841 | |||
842 | if ((sigalg = ssl_sigalg_select(s, cpk->privatekey)) == NULL) | ||
843 | goto done; | ||
844 | |||
845 | *ok = 1; | ||
846 | *out_sigalg = sigalg; | ||
847 | |||
848 | done: | ||
849 | return 1; | ||
850 | } | ||
851 | |||
852 | static int | ||
853 | tls13_client_select_certificate(struct tls13_ctx *ctx, CERT_PKEY **out_cpk, | ||
854 | const struct ssl_sigalg **out_sigalg) | ||
855 | { | ||
856 | SSL *s = ctx->ssl; | ||
857 | const struct ssl_sigalg *sigalg; | ||
858 | CERT_PKEY *cpk; | ||
859 | int cert_ok; | ||
860 | |||
861 | *out_cpk = NULL; | ||
862 | *out_sigalg = NULL; | ||
863 | |||
864 | /* | ||
865 | * XXX - RFC 8446, 4.4.2.3: the server can communicate preferences | ||
866 | * with the certificate_authorities (4.2.4) and oid_filters (4.2.5) | ||
867 | * extensions. We should honor the former and must apply the latter. | ||
868 | */ | ||
869 | |||
870 | cpk = &s->cert->pkeys[SSL_PKEY_ECC]; | ||
871 | if (!tls13_client_check_certificate(ctx, cpk, &cert_ok, &sigalg)) | ||
872 | return 0; | ||
873 | if (cert_ok) | ||
874 | goto done; | ||
875 | |||
876 | cpk = &s->cert->pkeys[SSL_PKEY_RSA]; | ||
877 | if (!tls13_client_check_certificate(ctx, cpk, &cert_ok, &sigalg)) | ||
878 | return 0; | ||
879 | if (cert_ok) | ||
880 | goto done; | ||
881 | |||
882 | cpk = NULL; | ||
883 | sigalg = NULL; | ||
884 | |||
885 | done: | ||
886 | *out_cpk = cpk; | ||
887 | *out_sigalg = sigalg; | ||
888 | |||
889 | return 1; | ||
890 | } | ||
891 | |||
829 | int | 892 | int |
830 | tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | 893 | tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb) |
831 | { | 894 | { |
832 | SSL *s = ctx->ssl; | 895 | SSL *s = ctx->ssl; |
833 | CBB cert_request_context, cert_list; | 896 | CBB cert_request_context, cert_list; |
897 | const struct ssl_sigalg *sigalg; | ||
834 | STACK_OF(X509) *chain; | 898 | STACK_OF(X509) *chain; |
835 | CERT_PKEY *cpk; | 899 | CERT_PKEY *cpk; |
836 | X509 *cert; | 900 | X509 *cert; |
837 | int i, ret = 0; | 901 | int i, ret = 0; |
838 | 902 | ||
839 | /* XXX - Need to revisit certificate selection. */ | 903 | if (!tls13_client_select_certificate(ctx, &cpk, &sigalg)) |
840 | cpk = &s->cert->pkeys[SSL_PKEY_RSA]; | 904 | goto err; |
841 | 905 | ||
842 | if ((chain = cpk->chain) == NULL) | 906 | ctx->hs->cpk = cpk; |
843 | chain = s->ctx->extra_certs; | 907 | ctx->hs->sigalg = sigalg; |
844 | 908 | ||
845 | if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context)) | 909 | if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context)) |
846 | goto err; | 910 | goto err; |
847 | if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) | 911 | if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) |
848 | goto err; | 912 | goto err; |
849 | 913 | ||
850 | if (cpk->x509 == NULL) | 914 | /* No certificate selected. */ |
915 | if (cpk == NULL) | ||
851 | goto done; | 916 | goto done; |
852 | 917 | ||
918 | if ((chain = cpk->chain) == NULL) | ||
919 | chain = s->ctx->extra_certs; | ||
920 | |||
853 | if (!tls13_cert_add(ctx, &cert_list, cpk->x509, tlsext_client_build)) | 921 | if (!tls13_cert_add(ctx, &cert_list, cpk->x509, tlsext_client_build)) |
854 | goto err; | 922 | goto err; |
855 | 923 | ||
@@ -873,27 +941,23 @@ tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb) | |||
873 | int | 941 | int |
874 | tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) | 942 | tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) |
875 | { | 943 | { |
876 | SSL *s = ctx->ssl; | 944 | const struct ssl_sigalg *sigalg; |
877 | const struct ssl_sigalg *sigalg = NULL; | ||
878 | uint8_t *sig = NULL, *sig_content = NULL; | 945 | uint8_t *sig = NULL, *sig_content = NULL; |
879 | size_t sig_len, sig_content_len; | 946 | size_t sig_len, sig_content_len; |
880 | EVP_MD_CTX *mdctx = NULL; | 947 | EVP_MD_CTX *mdctx = NULL; |
881 | EVP_PKEY_CTX *pctx; | 948 | EVP_PKEY_CTX *pctx; |
882 | EVP_PKEY *pkey; | 949 | EVP_PKEY *pkey; |
883 | CERT_PKEY *cpk; | 950 | const CERT_PKEY *cpk; |
884 | CBB sig_cbb; | 951 | CBB sig_cbb; |
885 | int ret = 0; | 952 | int ret = 0; |
886 | 953 | ||
887 | memset(&sig_cbb, 0, sizeof(sig_cbb)); | 954 | memset(&sig_cbb, 0, sizeof(sig_cbb)); |
888 | 955 | ||
889 | /* XXX - Need to revisit certificate selection. */ | 956 | if ((cpk = ctx->hs->cpk) == NULL) |
890 | cpk = &s->cert->pkeys[SSL_PKEY_RSA]; | ||
891 | pkey = cpk->privatekey; | ||
892 | |||
893 | if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) { | ||
894 | /* XXX - SSL_R_SIGNATURE_ALGORITHMS_ERROR */ | ||
895 | goto err; | 957 | goto err; |
896 | } | 958 | if ((sigalg = ctx->hs->sigalg) == NULL) |
959 | goto err; | ||
960 | pkey = cpk->privatekey; | ||
897 | 961 | ||
898 | if (!CBB_init(&sig_cbb, 0)) | 962 | if (!CBB_init(&sig_cbb, 0)) |
899 | goto err; | 963 | goto err; |