diff options
| author | tb <> | 2020-06-04 18:41:42 +0000 |
|---|---|---|
| committer | tb <> | 2020-06-04 18:41:42 +0000 |
| commit | 73803d4f9471a320c132894319e7be48ead70aa3 (patch) | |
| tree | 003de66accc82ad2651bfab148c0c527e609d655 /src | |
| parent | 232bfe77671b78bbdac14d245b89f0c9a35b75d0 (diff) | |
| download | openbsd-73803d4f9471a320c132894319e7be48ead70aa3.tar.gz openbsd-73803d4f9471a320c132894319e7be48ead70aa3.tar.bz2 openbsd-73803d4f9471a320c132894319e7be48ead70aa3.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; |
