diff options
| author | jsing <> | 2022-08-17 07:39:19 +0000 |
|---|---|---|
| committer | jsing <> | 2022-08-17 07:39:19 +0000 |
| commit | b0c5f651476e9397892adf645bba468df03d0ea9 (patch) | |
| tree | d4b208572f46a7c773aecb3e2d410aeaae5e817a /src | |
| parent | 7e9e21e27683a4be2c58fedde7fc9303f63a83f9 (diff) | |
| download | openbsd-b0c5f651476e9397892adf645bba468df03d0ea9.tar.gz openbsd-b0c5f651476e9397892adf645bba468df03d0ea9.tar.bz2 openbsd-b0c5f651476e9397892adf645bba468df03d0ea9.zip | |
Deduplicate peer certificate chain processing code.
Rather than reimplement this in each TLS client and server, deduplicate it
into a single function. Furthermore, rather than dealing with the API
hazard that is SSL_get_peer_cert_chain() in this code, simply produce two
chains - one that has the leaf and one that does not.
SSL_get_peer_cert_chain() can then return the appropriate one.
This also moves the peer cert chain from the SSL_SESSION to the
SSL_HANDSHAKE, which makes more sense since it is not available on
resumption.
ok tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/Makefile | 5 | ||||
| -rw-r--r-- | src/lib/libssl/s3_lib.c | 15 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_clnt.c | 36 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_lib.c | 13 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_locl.h | 10 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_sess.c | 6 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_srvr.c | 23 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_client.c | 26 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_server.c | 28 | ||||
| -rw-r--r-- | src/lib/libssl/tls_lib.c | 68 |
10 files changed, 121 insertions, 109 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index d0d7bc4e02..1788cd75a3 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.76 2022/07/24 14:28:16 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.77 2022/08/17 07:39:19 jsing Exp $ |
| 2 | 2 | ||
| 3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
| 4 | .ifndef NOMAN | 4 | .ifndef NOMAN |
| @@ -85,7 +85,8 @@ SRCS= \ | |||
| 85 | tls13_server.c \ | 85 | tls13_server.c \ |
| 86 | tls_buffer.c \ | 86 | tls_buffer.c \ |
| 87 | tls_content.c \ | 87 | tls_content.c \ |
| 88 | tls_key_share.c | 88 | tls_key_share.c \ |
| 89 | tls_lib.c | ||
| 89 | 90 | ||
| 90 | HDRS= dtls1.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h tls1.h | 91 | HDRS= dtls1.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h tls1.h |
| 91 | 92 | ||
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index b6a2c26938..2726744357 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: s3_lib.c,v 1.235 2022/07/02 16:31:04 tb Exp $ */ | 1 | /* $OpenBSD: s3_lib.c,v 1.236 2022/08/17 07:39:19 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 | * |
| @@ -1559,8 +1559,10 @@ ssl3_free(SSL *s) | |||
| 1559 | tls1_cleanup_key_block(s); | 1559 | tls1_cleanup_key_block(s); |
| 1560 | ssl3_release_read_buffer(s); | 1560 | ssl3_release_read_buffer(s); |
| 1561 | ssl3_release_write_buffer(s); | 1561 | ssl3_release_write_buffer(s); |
| 1562 | freezero(s->s3->hs.sigalgs, s->s3->hs.sigalgs_len); | ||
| 1563 | 1562 | ||
| 1563 | freezero(s->s3->hs.sigalgs, s->s3->hs.sigalgs_len); | ||
| 1564 | sk_X509_pop_free(s->s3->hs.peer_certs, X509_free); | ||
| 1565 | sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); | ||
| 1564 | tls_key_share_free(s->s3->hs.key_share); | 1566 | tls_key_share_free(s->s3->hs.key_share); |
| 1565 | 1567 | ||
| 1566 | tls13_secrets_destroy(s->s3->hs.tls13.secrets); | 1568 | tls13_secrets_destroy(s->s3->hs.tls13.secrets); |
| @@ -1586,8 +1588,8 @@ ssl3_free(SSL *s) | |||
| 1586 | void | 1588 | void |
| 1587 | ssl3_clear(SSL *s) | 1589 | ssl3_clear(SSL *s) |
| 1588 | { | 1590 | { |
| 1589 | unsigned char *rp, *wp; | 1591 | unsigned char *rp, *wp; |
| 1590 | size_t rlen, wlen; | 1592 | size_t rlen, wlen; |
| 1591 | 1593 | ||
| 1592 | tls1_cleanup_key_block(s); | 1594 | tls1_cleanup_key_block(s); |
| 1593 | sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free); | 1595 | sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free); |
| @@ -1598,6 +1600,11 @@ ssl3_clear(SSL *s) | |||
| 1598 | s->s3->hs.sigalgs = NULL; | 1600 | s->s3->hs.sigalgs = NULL; |
| 1599 | s->s3->hs.sigalgs_len = 0; | 1601 | s->s3->hs.sigalgs_len = 0; |
| 1600 | 1602 | ||
| 1603 | sk_X509_pop_free(s->s3->hs.peer_certs, X509_free); | ||
| 1604 | s->s3->hs.peer_certs = NULL; | ||
| 1605 | sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); | ||
| 1606 | s->s3->hs.peer_certs_no_leaf = NULL; | ||
| 1607 | |||
| 1601 | tls_key_share_free(s->s3->hs.key_share); | 1608 | tls_key_share_free(s->s3->hs.key_share); |
| 1602 | s->s3->hs.key_share = NULL; | 1609 | s->s3->hs.key_share = NULL; |
| 1603 | 1610 | ||
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index 1319684868..0e50285898 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_clnt.c,v 1.152 2022/08/15 10:45:25 tb Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.153 2022/08/17 07:39:19 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 | * |
| @@ -1090,8 +1090,6 @@ ssl3_get_server_certificate(SSL *s) | |||
| 1090 | STACK_OF(X509) *certs = NULL; | 1090 | STACK_OF(X509) *certs = NULL; |
| 1091 | X509 *cert = NULL; | 1091 | X509 *cert = NULL; |
| 1092 | const uint8_t *p; | 1092 | const uint8_t *p; |
| 1093 | EVP_PKEY *pkey; | ||
| 1094 | int cert_type; | ||
| 1095 | int al, ret; | 1093 | int al, ret; |
| 1096 | 1094 | ||
| 1097 | if ((ret = ssl3_get_message(s, SSL3_ST_CR_CERT_A, | 1095 | if ((ret = ssl3_get_message(s, SSL3_ST_CR_CERT_A, |
| @@ -1156,37 +1154,11 @@ ssl3_get_server_certificate(SSL *s) | |||
| 1156 | SSLerror(s, SSL_R_CERTIFICATE_VERIFY_FAILED); | 1154 | SSLerror(s, SSL_R_CERTIFICATE_VERIFY_FAILED); |
| 1157 | goto fatal_err; | 1155 | goto fatal_err; |
| 1158 | } | 1156 | } |
| 1159 | ERR_clear_error(); /* but we keep s->verify_result */ | ||
| 1160 | |||
| 1161 | /* | ||
| 1162 | * Inconsistency alert: cert_chain does include the peer's | ||
| 1163 | * certificate, which we don't include in s3_srvr.c | ||
| 1164 | */ | ||
| 1165 | cert = sk_X509_value(certs, 0); | ||
| 1166 | X509_up_ref(cert); | ||
| 1167 | |||
| 1168 | if ((pkey = X509_get0_pubkey(cert)) == NULL || | ||
| 1169 | EVP_PKEY_missing_parameters(pkey)) { | ||
| 1170 | al = SSL3_AL_FATAL; | ||
| 1171 | SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); | ||
| 1172 | goto fatal_err; | ||
| 1173 | } | ||
| 1174 | if ((cert_type = ssl_cert_type(pkey)) < 0) { | ||
| 1175 | al = SSL3_AL_FATAL; | ||
| 1176 | SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE); | ||
| 1177 | goto fatal_err; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | X509_free(s->session->peer_cert); | ||
| 1181 | X509_up_ref(cert); | ||
| 1182 | s->session->peer_cert = cert; | ||
| 1183 | s->session->peer_cert_type = cert_type; | ||
| 1184 | |||
| 1185 | s->session->verify_result = s->verify_result; | 1157 | s->session->verify_result = s->verify_result; |
| 1158 | ERR_clear_error(); | ||
| 1186 | 1159 | ||
| 1187 | sk_X509_pop_free(s->session->cert_chain, X509_free); | 1160 | if (!tls_process_peer_certs(s, certs)) |
| 1188 | s->session->cert_chain = certs; | 1161 | goto err; |
| 1189 | certs = NULL; | ||
| 1190 | 1162 | ||
| 1191 | ret = 1; | 1163 | ret = 1; |
| 1192 | 1164 | ||
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index e346e3cf7f..9af1934dd6 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_lib.c,v 1.300 2022/07/24 15:05:16 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.301 2022/08/17 07:39:19 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 | * |
| @@ -880,14 +880,17 @@ SSL_get_peer_certificate(const SSL *s) | |||
| 880 | STACK_OF(X509) * | 880 | STACK_OF(X509) * |
| 881 | SSL_get_peer_cert_chain(const SSL *s) | 881 | SSL_get_peer_cert_chain(const SSL *s) |
| 882 | { | 882 | { |
| 883 | if (s == NULL || s->session == NULL) | 883 | if (s == NULL) |
| 884 | return NULL; | 884 | return NULL; |
| 885 | 885 | ||
| 886 | /* | 886 | /* |
| 887 | * If we are a client, cert_chain includes the peer's own | 887 | * Achtung! Due to API inconsistency, a client includes the peer's leaf |
| 888 | * certificate; if we are a server, it does not. | 888 | * certificate in the peer certificate chain, while a server does not. |
| 889 | */ | 889 | */ |
| 890 | return s->session->cert_chain; | 890 | if (!s->server) |
| 891 | return s->s3->hs.peer_certs; | ||
| 892 | |||
| 893 | return s->s3->hs.peer_certs_no_leaf; | ||
| 891 | } | 894 | } |
| 892 | 895 | ||
| 893 | STACK_OF(X509) * | 896 | STACK_OF(X509) * |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 18daf791f0..1bfeeb9740 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.417 2022/07/24 14:28:16 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.418 2022/08/17 07:39:19 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 | * |
| @@ -518,8 +518,6 @@ struct ssl_session_st { | |||
| 518 | * not_resumable_session_cb to disable session caching and tickets. */ | 518 | * not_resumable_session_cb to disable session caching and tickets. */ |
| 519 | int not_resumable; | 519 | int not_resumable; |
| 520 | 520 | ||
| 521 | STACK_OF(X509) *cert_chain; /* as received from peer */ | ||
| 522 | |||
| 523 | size_t tlsext_ecpointformatlist_length; | 521 | size_t tlsext_ecpointformatlist_length; |
| 524 | uint8_t *tlsext_ecpointformatlist; /* peer's list */ | 522 | uint8_t *tlsext_ecpointformatlist; /* peer's list */ |
| 525 | size_t tlsext_supportedgroups_length; | 523 | size_t tlsext_supportedgroups_length; |
| @@ -645,6 +643,10 @@ typedef struct ssl_handshake_st { | |||
| 645 | uint8_t peer_finished[EVP_MAX_MD_SIZE]; | 643 | uint8_t peer_finished[EVP_MAX_MD_SIZE]; |
| 646 | size_t peer_finished_len; | 644 | size_t peer_finished_len; |
| 647 | 645 | ||
| 646 | /* List of certificates received from our peer. */ | ||
| 647 | STACK_OF(X509) *peer_certs; | ||
| 648 | STACK_OF(X509) *peer_certs_no_leaf; | ||
| 649 | |||
| 648 | SSL_HANDSHAKE_TLS12 tls12; | 650 | SSL_HANDSHAKE_TLS12 tls12; |
| 649 | SSL_HANDSHAKE_TLS13 tls13; | 651 | SSL_HANDSHAKE_TLS13 tls13; |
| 650 | } SSL_HANDSHAKE; | 652 | } SSL_HANDSHAKE; |
| @@ -1566,6 +1568,8 @@ int srtp_find_profile_by_num(unsigned int profile_num, | |||
| 1566 | 1568 | ||
| 1567 | #endif /* OPENSSL_NO_SRTP */ | 1569 | #endif /* OPENSSL_NO_SRTP */ |
| 1568 | 1570 | ||
| 1571 | int tls_process_peer_certs(SSL *s, STACK_OF(X509) *peer_certs); | ||
| 1572 | |||
| 1569 | __END_HIDDEN_DECLS | 1573 | __END_HIDDEN_DECLS |
| 1570 | 1574 | ||
| 1571 | #endif | 1575 | #endif |
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c index fcb259f6a2..7cf36f8984 100644 --- a/src/lib/libssl/ssl_sess.c +++ b/src/lib/libssl/ssl_sess.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_sess.c,v 1.116 2022/06/07 17:49:22 tb Exp $ */ | 1 | /* $OpenBSD: ssl_sess.c,v 1.117 2022/08/17 07:39:19 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 | * |
| @@ -230,6 +230,8 @@ SSL_SESSION_new(void) | |||
| 230 | ss->next = NULL; | 230 | ss->next = NULL; |
| 231 | ss->tlsext_hostname = NULL; | 231 | ss->tlsext_hostname = NULL; |
| 232 | 232 | ||
| 233 | ss->peer_cert_type = -1; | ||
| 234 | |||
| 233 | ss->tlsext_ecpointformatlist_length = 0; | 235 | ss->tlsext_ecpointformatlist_length = 0; |
| 234 | ss->tlsext_ecpointformatlist = NULL; | 236 | ss->tlsext_ecpointformatlist = NULL; |
| 235 | ss->tlsext_supportedgroups_length = 0; | 237 | ss->tlsext_supportedgroups_length = 0; |
| @@ -761,8 +763,6 @@ SSL_SESSION_free(SSL_SESSION *ss) | |||
| 761 | explicit_bzero(ss->master_key, sizeof ss->master_key); | 763 | explicit_bzero(ss->master_key, sizeof ss->master_key); |
| 762 | explicit_bzero(ss->session_id, sizeof ss->session_id); | 764 | explicit_bzero(ss->session_id, sizeof ss->session_id); |
| 763 | 765 | ||
| 764 | sk_X509_pop_free(ss->cert_chain, X509_free); | ||
| 765 | |||
| 766 | X509_free(ss->peer_cert); | 766 | X509_free(ss->peer_cert); |
| 767 | 767 | ||
| 768 | sk_SSL_CIPHER_free(ss->ciphers); | 768 | sk_SSL_CIPHER_free(ss->ciphers); |
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index d665a568d1..acdcb15398 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_srvr.c,v 1.148 2022/07/03 14:58:00 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.149 2022/08/17 07:39:19 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 | * |
| @@ -2175,6 +2175,11 @@ ssl3_get_client_certificate(SSL *s) | |||
| 2175 | al = SSL_AD_HANDSHAKE_FAILURE; | 2175 | al = SSL_AD_HANDSHAKE_FAILURE; |
| 2176 | goto fatal_err; | 2176 | goto fatal_err; |
| 2177 | } | 2177 | } |
| 2178 | |||
| 2179 | /* | ||
| 2180 | * If we asked for a client certificate and the client has none, | ||
| 2181 | * it must respond with a certificate list of length zero. | ||
| 2182 | */ | ||
| 2178 | if (s->s3->hs.tls12.cert_request != 0) { | 2183 | if (s->s3->hs.tls12.cert_request != 0) { |
| 2179 | SSLerror(s, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); | 2184 | SSLerror(s, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); |
| 2180 | al = SSL_AD_UNEXPECTED_MESSAGE; | 2185 | al = SSL_AD_UNEXPECTED_MESSAGE; |
| @@ -2244,19 +2249,11 @@ ssl3_get_client_certificate(SSL *s) | |||
| 2244 | SSLerror(s, SSL_R_NO_CERTIFICATE_RETURNED); | 2249 | SSLerror(s, SSL_R_NO_CERTIFICATE_RETURNED); |
| 2245 | goto fatal_err; | 2250 | goto fatal_err; |
| 2246 | } | 2251 | } |
| 2247 | |||
| 2248 | X509_free(s->session->peer_cert); | ||
| 2249 | s->session->peer_cert = sk_X509_shift(certs); | ||
| 2250 | |||
| 2251 | /* | ||
| 2252 | * Inconsistency alert: cert_chain does *not* include the | ||
| 2253 | * peer's own certificate, while we do include it in s3_clnt.c | ||
| 2254 | */ | ||
| 2255 | sk_X509_pop_free(s->session->cert_chain, X509_free); | ||
| 2256 | s->session->cert_chain = certs; | ||
| 2257 | certs = NULL; | ||
| 2258 | |||
| 2259 | s->session->verify_result = s->verify_result; | 2252 | s->session->verify_result = s->verify_result; |
| 2253 | ERR_clear_error(); | ||
| 2254 | |||
| 2255 | if (!tls_process_peer_certs(s, certs)) | ||
| 2256 | goto err; | ||
| 2260 | 2257 | ||
| 2261 | done: | 2258 | done: |
| 2262 | ret = 1; | 2259 | ret = 1; |
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index b1efafdfdd..87759632f9 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.97 2022/07/24 14:16:29 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.98 2022/08/17 07:39:19 jsing 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 | * |
| @@ -553,9 +553,8 @@ tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 553 | struct stack_st_X509 *certs = NULL; | 553 | struct stack_st_X509 *certs = NULL; |
| 554 | SSL *s = ctx->ssl; | 554 | SSL *s = ctx->ssl; |
| 555 | X509 *cert = NULL; | 555 | X509 *cert = NULL; |
| 556 | EVP_PKEY *pkey; | ||
| 557 | const uint8_t *p; | 556 | const uint8_t *p; |
| 558 | int alert_desc, cert_type; | 557 | int alert_desc; |
| 559 | int ret = 0; | 558 | int ret = 0; |
| 560 | 559 | ||
| 561 | if ((certs = sk_X509_new_null()) == NULL) | 560 | if ((certs = sk_X509_new_null()) == NULL) |
| @@ -610,28 +609,11 @@ tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 610 | "failed to verify peer certificate", NULL); | 609 | "failed to verify peer certificate", NULL); |
| 611 | goto err; | 610 | goto err; |
| 612 | } | 611 | } |
| 612 | s->session->verify_result = s->verify_result; | ||
| 613 | ERR_clear_error(); | 613 | ERR_clear_error(); |
| 614 | 614 | ||
| 615 | cert = sk_X509_value(certs, 0); | 615 | if (!tls_process_peer_certs(s, certs)) |
| 616 | X509_up_ref(cert); | ||
| 617 | |||
| 618 | if ((pkey = X509_get0_pubkey(cert)) == NULL) | ||
| 619 | goto err; | ||
| 620 | if (EVP_PKEY_missing_parameters(pkey)) | ||
| 621 | goto err; | 616 | goto err; |
| 622 | if ((cert_type = ssl_cert_type(pkey)) < 0) | ||
| 623 | goto err; | ||
| 624 | |||
| 625 | X509_up_ref(cert); | ||
| 626 | X509_free(s->session->peer_cert); | ||
| 627 | s->session->peer_cert = cert; | ||
| 628 | s->session->peer_cert_type = cert_type; | ||
| 629 | |||
| 630 | s->session->verify_result = s->verify_result; | ||
| 631 | |||
| 632 | sk_X509_pop_free(s->session->cert_chain, X509_free); | ||
| 633 | s->session->cert_chain = certs; | ||
| 634 | certs = NULL; | ||
| 635 | 617 | ||
| 636 | if (ctx->ocsp_status_recv_cb != NULL && | 618 | if (ctx->ocsp_status_recv_cb != NULL && |
| 637 | !ctx->ocsp_status_recv_cb(ctx)) | 619 | !ctx->ocsp_status_recv_cb(ctx)) |
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index 5aee5f1a93..8f225433f0 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.100 2022/07/24 14:16:29 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.101 2022/08/17 07:39:19 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> |
| @@ -860,9 +860,7 @@ tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 860 | struct stack_st_X509 *certs = NULL; | 860 | struct stack_st_X509 *certs = NULL; |
| 861 | SSL *s = ctx->ssl; | 861 | SSL *s = ctx->ssl; |
| 862 | X509 *cert = NULL; | 862 | X509 *cert = NULL; |
| 863 | EVP_PKEY *pkey; | ||
| 864 | const uint8_t *p; | 863 | const uint8_t *p; |
| 865 | int cert_type; | ||
| 866 | int ret = 0; | 864 | int ret = 0; |
| 867 | 865 | ||
| 868 | if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context)) | 866 | if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context)) |
| @@ -911,31 +909,11 @@ tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) | |||
| 911 | "failed to verify peer certificate", NULL); | 909 | "failed to verify peer certificate", NULL); |
| 912 | goto err; | 910 | goto err; |
| 913 | } | 911 | } |
| 912 | s->session->verify_result = s->verify_result; | ||
| 914 | ERR_clear_error(); | 913 | ERR_clear_error(); |
| 915 | 914 | ||
| 916 | /* | 915 | if (!tls_process_peer_certs(s, certs)) |
| 917 | * Achtung! Due to API inconsistency, a client includes the peer's leaf | ||
| 918 | * certificate in the stored certificate chain, while a server does not. | ||
| 919 | */ | ||
| 920 | cert = sk_X509_shift(certs); | ||
| 921 | |||
| 922 | if ((pkey = X509_get0_pubkey(cert)) == NULL) | ||
| 923 | goto err; | 916 | goto err; |
| 924 | if (EVP_PKEY_missing_parameters(pkey)) | ||
| 925 | goto err; | ||
| 926 | if ((cert_type = ssl_cert_type(pkey)) < 0) | ||
| 927 | goto err; | ||
| 928 | |||
| 929 | X509_up_ref(cert); | ||
| 930 | X509_free(s->session->peer_cert); | ||
| 931 | s->session->peer_cert = cert; | ||
| 932 | s->session->peer_cert_type = cert_type; | ||
| 933 | |||
| 934 | s->session->verify_result = s->verify_result; | ||
| 935 | |||
| 936 | sk_X509_pop_free(s->session->cert_chain, X509_free); | ||
| 937 | s->session->cert_chain = certs; | ||
| 938 | certs = NULL; | ||
| 939 | 917 | ||
| 940 | ctx->handshake_stage.hs_type |= WITH_CCV; | 918 | ctx->handshake_stage.hs_type |= WITH_CCV; |
| 941 | ret = 1; | 919 | ret = 1; |
diff --git a/src/lib/libssl/tls_lib.c b/src/lib/libssl/tls_lib.c new file mode 100644 index 0000000000..48db071803 --- /dev/null +++ b/src/lib/libssl/tls_lib.c | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | /* $OpenBSD: tls_lib.c,v 1.1 2022/08/17 07:39:19 jsing Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2019, 2021 Joel Sing <jsing@openbsd.org> | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "ssl_locl.h" | ||
| 19 | |||
| 20 | int | ||
| 21 | tls_process_peer_certs(SSL *s, STACK_OF(X509) *peer_certs) | ||
| 22 | { | ||
| 23 | STACK_OF(X509) *peer_certs_no_leaf; | ||
| 24 | X509 *peer_cert = NULL; | ||
| 25 | EVP_PKEY *pkey; | ||
| 26 | int cert_type; | ||
| 27 | int ret = 0; | ||
| 28 | |||
| 29 | if (sk_X509_num(peer_certs) < 1) | ||
| 30 | goto err; | ||
| 31 | peer_cert = sk_X509_value(peer_certs, 0); | ||
| 32 | X509_up_ref(peer_cert); | ||
| 33 | |||
| 34 | if ((pkey = X509_get0_pubkey(peer_cert)) == NULL) { | ||
| 35 | SSLerror(s, SSL_R_NO_PUBLICKEY); | ||
| 36 | goto err; | ||
| 37 | } | ||
| 38 | if (EVP_PKEY_missing_parameters(pkey)) { | ||
| 39 | SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); | ||
| 40 | goto err; | ||
| 41 | } | ||
| 42 | if ((cert_type = ssl_cert_type(pkey)) < 0) { | ||
| 43 | SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE); | ||
| 44 | goto err; | ||
| 45 | } | ||
| 46 | |||
| 47 | s->session->peer_cert_type = cert_type; | ||
| 48 | |||
| 49 | X509_free(s->session->peer_cert); | ||
| 50 | s->session->peer_cert = peer_cert; | ||
| 51 | peer_cert = NULL; | ||
| 52 | |||
| 53 | sk_X509_pop_free(s->s3->hs.peer_certs, X509_free); | ||
| 54 | if ((s->s3->hs.peer_certs = X509_chain_up_ref(peer_certs)) == NULL) | ||
| 55 | goto err; | ||
| 56 | |||
| 57 | if ((peer_certs_no_leaf = X509_chain_up_ref(peer_certs)) == NULL) | ||
| 58 | goto err; | ||
| 59 | X509_free(sk_X509_shift(peer_certs_no_leaf)); | ||
| 60 | sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); | ||
| 61 | s->s3->hs.peer_certs_no_leaf = peer_certs_no_leaf; | ||
| 62 | |||
| 63 | ret = 1; | ||
| 64 | err: | ||
| 65 | X509_free(peer_cert); | ||
| 66 | |||
| 67 | return ret; | ||
| 68 | } | ||
