summaryrefslogtreecommitdiff
path: root/lib/libssl
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2022-07-03 14:52:40 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2022-07-03 14:52:40 +0000
commit1f584ecb075766d8b207145ae57e250c1fae3f81 (patch)
tree42d136d0879dd87742dbd37b7adc73ff5eb0f047 /lib/libssl
parent6be12ed7b8d988e66e11b1b2d93747c01ed85ad5 (diff)
Simplify certificate list handling code in legacy client.
Tidy up CBS code and remove some unnecessary length checks. Use 'cert' and 'certs' for certificates, rather than 'x' and 'sk'. ok tb@
Diffstat (limited to 'lib/libssl')
-rw-r--r--lib/libssl/ssl_clnt.c78
1 files changed, 33 insertions, 45 deletions
diff --git a/lib/libssl/ssl_clnt.c b/lib/libssl/ssl_clnt.c
index 8fe416b74a5..224aa1032fb 100644
--- a/lib/libssl/ssl_clnt.c
+++ b/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.150 2022/07/02 16:00:12 tb Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.151 2022/07/03 14:52:39 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1086,10 +1086,10 @@ ssl3_get_server_hello(SSL *s)
int
ssl3_get_server_certificate(SSL *s)
{
- CBS cbs, cert_list;
- X509 *x = NULL;
- const unsigned char *q;
- STACK_OF(X509) *sk = NULL;
+ CBS cbs, cert_list, cert_data;
+ STACK_OF(X509) *certs = NULL;
+ X509 *cert = NULL;
+ const uint8_t *p;
EVP_PKEY *pkey;
int cert_type;
int al, ret;
@@ -1111,7 +1111,7 @@ ssl3_get_server_certificate(SSL *s)
goto fatal_err;
}
- if ((sk = sk_X509_new_null()) == NULL) {
+ if ((certs = sk_X509_new_null()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1120,47 +1120,37 @@ ssl3_get_server_certificate(SSL *s)
goto decode_err;
CBS_init(&cbs, s->internal->init_msg, s->internal->init_num);
- if (CBS_len(&cbs) < 3)
- goto decode_err;
- if (!CBS_get_u24_length_prefixed(&cbs, &cert_list) ||
- CBS_len(&cbs) != 0) {
- al = SSL_AD_DECODE_ERROR;
- SSLerror(s, SSL_R_LENGTH_MISMATCH);
- goto fatal_err;
- }
+ if (!CBS_get_u24_length_prefixed(&cbs, &cert_list))
+ goto decode_err;
+ if (CBS_len(&cbs) != 0)
+ goto decode_err;
while (CBS_len(&cert_list) > 0) {
- CBS cert;
-
- if (CBS_len(&cert_list) < 3)
+ if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data))
goto decode_err;
- if (!CBS_get_u24_length_prefixed(&cert_list, &cert)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerror(s, SSL_R_CERT_LENGTH_MISMATCH);
- goto fatal_err;
- }
-
- q = CBS_data(&cert);
- x = d2i_X509(NULL, &q, CBS_len(&cert));
- if (x == NULL) {
+ p = CBS_data(&cert_data);
+ if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) {
al = SSL_AD_BAD_CERTIFICATE;
SSLerror(s, ERR_R_ASN1_LIB);
goto fatal_err;
}
- if (q != CBS_data(&cert) + CBS_len(&cert)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerror(s, SSL_R_CERT_LENGTH_MISMATCH);
- goto fatal_err;
- }
- if (!sk_X509_push(sk, x)) {
+ if (p != CBS_data(&cert_data) + CBS_len(&cert_data))
+ goto decode_err;
+ if (!sk_X509_push(certs, cert)) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
- x = NULL;
+ cert = NULL;
+ }
+
+ /* A server must always provide a non-empty certificate list. */
+ if (sk_X509_num(certs) < 1) {
+ SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+ goto decode_err;
}
- if (ssl_verify_cert_chain(s, sk) <= 0 &&
+ if (ssl_verify_cert_chain(s, certs) <= 0 &&
s->verify_mode != SSL_VERIFY_NONE) {
al = ssl_verify_alarm_type(s->verify_result);
SSLerror(s, SSL_R_CERTIFICATE_VERIFY_FAILED);
@@ -1172,34 +1162,32 @@ ssl3_get_server_certificate(SSL *s)
* Inconsistency alert: cert_chain does include the peer's
* certificate, which we don't include in s3_srvr.c
*/
- x = sk_X509_value(sk, 0);
+ cert = sk_X509_value(certs, 0);
+ X509_up_ref(cert);
- if ((pkey = X509_get0_pubkey(x)) == NULL ||
+ if ((pkey = X509_get0_pubkey(cert)) == NULL ||
EVP_PKEY_missing_parameters(pkey)) {
- x = NULL;
al = SSL3_AL_FATAL;
SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
goto fatal_err;
}
if ((cert_type = ssl_cert_type(pkey)) < 0) {
- x = NULL;
al = SSL3_AL_FATAL;
SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
goto fatal_err;
}
- X509_up_ref(x);
X509_free(s->session->peer_cert);
- s->session->peer_cert = x;
+ X509_up_ref(cert);
+ s->session->peer_cert = cert;
s->session->peer_cert_type = cert_type;
s->session->verify_result = s->verify_result;
sk_X509_pop_free(s->session->cert_chain, X509_free);
- s->session->cert_chain = sk;
- sk = NULL;
+ s->session->cert_chain = certs;
+ certs = NULL;
- x = NULL;
ret = 1;
if (0) {
@@ -1211,8 +1199,8 @@ ssl3_get_server_certificate(SSL *s)
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}
err:
- X509_free(x);
- sk_X509_pop_free(sk, X509_free);
+ sk_X509_pop_free(certs, X509_free);
+ X509_free(cert);
return (ret);
}