diff options
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 112 |
1 files changed, 50 insertions, 62 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 526d9e678b..d665a568d1 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.147 2022/07/02 16:00:12 tb Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.148 2022/07/03 14:58:00 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 | * |
@@ -525,7 +525,7 @@ ssl3_accept(SSL *s) | |||
525 | 525 | ||
526 | case SSL3_ST_SR_CERT_A: | 526 | case SSL3_ST_SR_CERT_A: |
527 | case SSL3_ST_SR_CERT_B: | 527 | case SSL3_ST_SR_CERT_B: |
528 | if (s->s3->hs.tls12.cert_request) { | 528 | if (s->s3->hs.tls12.cert_request != 0) { |
529 | ret = ssl3_get_client_certificate(s); | 529 | ret = ssl3_get_client_certificate(s); |
530 | if (ret <= 0) | 530 | if (ret <= 0) |
531 | goto end; | 531 | goto end; |
@@ -2156,11 +2156,11 @@ ssl3_get_cert_verify(SSL *s) | |||
2156 | int | 2156 | int |
2157 | ssl3_get_client_certificate(SSL *s) | 2157 | ssl3_get_client_certificate(SSL *s) |
2158 | { | 2158 | { |
2159 | CBS cbs, client_certs; | 2159 | CBS cbs, cert_list, cert_data; |
2160 | X509 *x = NULL; | 2160 | STACK_OF(X509) *certs = NULL; |
2161 | const unsigned char *q; | 2161 | X509 *cert = NULL; |
2162 | STACK_OF(X509) *sk = NULL; | 2162 | const uint8_t *p; |
2163 | int i, al, ret; | 2163 | int al, ret; |
2164 | 2164 | ||
2165 | if ((ret = ssl3_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, | 2165 | if ((ret = ssl3_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, |
2166 | -1, s->internal->max_cert_list)) <= 0) | 2166 | -1, s->internal->max_cert_list)) <= 0) |
@@ -2175,13 +2175,8 @@ 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 | /* | 2178 | if (s->s3->hs.tls12.cert_request != 0) { |
2179 | * If tls asked for a client cert, | 2179 | SSLerror(s, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); |
2180 | * the client must return a 0 list. | ||
2181 | */ | ||
2182 | if (s->s3->hs.tls12.cert_request) { | ||
2183 | SSLerror(s, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST | ||
2184 | ); | ||
2185 | al = SSL_AD_UNEXPECTED_MESSAGE; | 2180 | al = SSL_AD_UNEXPECTED_MESSAGE; |
2186 | goto fatal_err; | 2181 | goto fatal_err; |
2187 | } | 2182 | } |
@@ -2200,77 +2195,70 @@ ssl3_get_client_certificate(SSL *s) | |||
2200 | 2195 | ||
2201 | CBS_init(&cbs, s->internal->init_msg, s->internal->init_num); | 2196 | CBS_init(&cbs, s->internal->init_msg, s->internal->init_num); |
2202 | 2197 | ||
2203 | if ((sk = sk_X509_new_null()) == NULL) { | 2198 | if (!CBS_get_u24_length_prefixed(&cbs, &cert_list)) |
2204 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 2199 | goto decode_err; |
2205 | goto err; | 2200 | if (CBS_len(&cbs) != 0) |
2206 | } | ||
2207 | |||
2208 | if (!CBS_get_u24_length_prefixed(&cbs, &client_certs) || | ||
2209 | CBS_len(&cbs) != 0) | ||
2210 | goto decode_err; | 2201 | goto decode_err; |
2211 | 2202 | ||
2212 | while (CBS_len(&client_certs) > 0) { | 2203 | /* |
2213 | CBS cert; | 2204 | * A TLS client must send an empty certificate list, if no suitable |
2214 | 2205 | * certificate is available (rather than omitting the Certificate | |
2215 | if (!CBS_get_u24_length_prefixed(&client_certs, &cert)) { | 2206 | * handshake message) - see RFC 5246 section 7.4.6. |
2216 | al = SSL_AD_DECODE_ERROR; | 2207 | */ |
2217 | SSLerror(s, SSL_R_CERT_LENGTH_MISMATCH); | 2208 | if (CBS_len(&cert_list) == 0) { |
2209 | if ((s->verify_mode & SSL_VERIFY_PEER) && | ||
2210 | (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { | ||
2211 | SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); | ||
2212 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
2218 | goto fatal_err; | 2213 | goto fatal_err; |
2219 | } | 2214 | } |
2215 | /* No client certificate so free transcript. */ | ||
2216 | tls1_transcript_free(s); | ||
2217 | goto done; | ||
2218 | } | ||
2220 | 2219 | ||
2221 | q = CBS_data(&cert); | 2220 | if ((certs = sk_X509_new_null()) == NULL) { |
2222 | x = d2i_X509(NULL, &q, CBS_len(&cert)); | 2221 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
2223 | if (x == NULL) { | 2222 | goto err; |
2223 | } | ||
2224 | |||
2225 | while (CBS_len(&cert_list) > 0) { | ||
2226 | if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) | ||
2227 | goto decode_err; | ||
2228 | p = CBS_data(&cert_data); | ||
2229 | if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) { | ||
2224 | SSLerror(s, ERR_R_ASN1_LIB); | 2230 | SSLerror(s, ERR_R_ASN1_LIB); |
2225 | goto err; | 2231 | goto err; |
2226 | } | 2232 | } |
2227 | if (q != CBS_data(&cert) + CBS_len(&cert)) { | 2233 | if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) |
2228 | al = SSL_AD_DECODE_ERROR; | 2234 | goto decode_err; |
2229 | SSLerror(s, SSL_R_CERT_LENGTH_MISMATCH); | 2235 | if (!sk_X509_push(certs, cert)) { |
2230 | goto fatal_err; | ||
2231 | } | ||
2232 | if (!sk_X509_push(sk, x)) { | ||
2233 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 2236 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
2234 | goto err; | 2237 | goto err; |
2235 | } | 2238 | } |
2236 | x = NULL; | 2239 | cert = NULL; |
2237 | } | 2240 | } |
2238 | 2241 | ||
2239 | if (sk_X509_num(sk) <= 0) { | 2242 | if (ssl_verify_cert_chain(s, certs) <= 0) { |
2240 | /* | 2243 | al = ssl_verify_alarm_type(s->verify_result); |
2241 | * TLS does not mind 0 certs returned. | 2244 | SSLerror(s, SSL_R_NO_CERTIFICATE_RETURNED); |
2242 | * Fail for TLS only if we required a certificate. | 2245 | goto fatal_err; |
2243 | */ | ||
2244 | if ((s->verify_mode & SSL_VERIFY_PEER) && | ||
2245 | (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { | ||
2246 | SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); | ||
2247 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
2248 | goto fatal_err; | ||
2249 | } | ||
2250 | /* No client certificate so free transcript. */ | ||
2251 | tls1_transcript_free(s); | ||
2252 | } else { | ||
2253 | i = ssl_verify_cert_chain(s, sk); | ||
2254 | if (i <= 0) { | ||
2255 | al = ssl_verify_alarm_type(s->verify_result); | ||
2256 | SSLerror(s, SSL_R_NO_CERTIFICATE_RETURNED); | ||
2257 | goto fatal_err; | ||
2258 | } | ||
2259 | } | 2246 | } |
2260 | 2247 | ||
2261 | X509_free(s->session->peer_cert); | 2248 | X509_free(s->session->peer_cert); |
2262 | s->session->peer_cert = sk_X509_shift(sk); | 2249 | s->session->peer_cert = sk_X509_shift(certs); |
2263 | 2250 | ||
2264 | /* | 2251 | /* |
2265 | * Inconsistency alert: cert_chain does *not* include the | 2252 | * Inconsistency alert: cert_chain does *not* include the |
2266 | * peer's own certificate, while we do include it in s3_clnt.c | 2253 | * peer's own certificate, while we do include it in s3_clnt.c |
2267 | */ | 2254 | */ |
2268 | sk_X509_pop_free(s->session->cert_chain, X509_free); | 2255 | sk_X509_pop_free(s->session->cert_chain, X509_free); |
2269 | s->session->cert_chain = sk; | 2256 | s->session->cert_chain = certs; |
2270 | sk = NULL; | 2257 | certs = NULL; |
2271 | 2258 | ||
2272 | s->session->verify_result = s->verify_result; | 2259 | s->session->verify_result = s->verify_result; |
2273 | 2260 | ||
2261 | done: | ||
2274 | ret = 1; | 2262 | ret = 1; |
2275 | if (0) { | 2263 | if (0) { |
2276 | decode_err: | 2264 | decode_err: |
@@ -2280,8 +2268,8 @@ ssl3_get_client_certificate(SSL *s) | |||
2280 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 2268 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
2281 | } | 2269 | } |
2282 | err: | 2270 | err: |
2283 | X509_free(x); | 2271 | sk_X509_pop_free(certs, X509_free); |
2284 | sk_X509_pop_free(sk, X509_free); | 2272 | X509_free(cert); |
2285 | 2273 | ||
2286 | return (ret); | 2274 | return (ret); |
2287 | } | 2275 | } |