summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2022-07-03 14:58:00 +0000
committerjsing <>2022-07-03 14:58:00 +0000
commit75b104defc9fec997245749fc919fd66a679c40d (patch)
tree6210ecab1ffd76ddf1fb9ee395feb4d7bad0129d /src
parent1ffc21a41f265a4910719c37b047e1583145350d (diff)
downloadopenbsd-75b104defc9fec997245749fc919fd66a679c40d.tar.gz
openbsd-75b104defc9fec997245749fc919fd66a679c40d.tar.bz2
openbsd-75b104defc9fec997245749fc919fd66a679c40d.zip
Simplify certificate list handling code in legacy server.
A client is required to send an empty list if it does not have a suitable certificate - handle this case up front, rather than going through the normal code path and ending up with an empty certificate list. This matches what we do in the TLSv1.3 stack and will allow for ruther clean up (in addition to making the code more readable). Also tidy up the CBS code and remove some unnecessary length checks. Use 'cert' and 'certs' for certificates, rather than 'x' and 'sk'. ok tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/ssl_srvr.c112
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)
2156int 2156int
2157ssl3_get_client_certificate(SSL *s) 2157ssl3_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}