diff options
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 78 |
1 files changed, 33 insertions, 45 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index 8fe416b74a..224aa1032f 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.150 2022/07/02 16:00:12 tb Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.151 2022/07/03 14:52:39 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 | * |
@@ -1086,10 +1086,10 @@ ssl3_get_server_hello(SSL *s) | |||
1086 | int | 1086 | int |
1087 | ssl3_get_server_certificate(SSL *s) | 1087 | ssl3_get_server_certificate(SSL *s) |
1088 | { | 1088 | { |
1089 | CBS cbs, cert_list; | 1089 | CBS cbs, cert_list, cert_data; |
1090 | X509 *x = NULL; | 1090 | STACK_OF(X509) *certs = NULL; |
1091 | const unsigned char *q; | 1091 | X509 *cert = NULL; |
1092 | STACK_OF(X509) *sk = NULL; | 1092 | const uint8_t *p; |
1093 | EVP_PKEY *pkey; | 1093 | EVP_PKEY *pkey; |
1094 | int cert_type; | 1094 | int cert_type; |
1095 | int al, ret; | 1095 | int al, ret; |
@@ -1111,7 +1111,7 @@ ssl3_get_server_certificate(SSL *s) | |||
1111 | goto fatal_err; | 1111 | goto fatal_err; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | if ((sk = sk_X509_new_null()) == NULL) { | 1114 | if ((certs = sk_X509_new_null()) == NULL) { |
1115 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 1115 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
1116 | goto err; | 1116 | goto err; |
1117 | } | 1117 | } |
@@ -1120,47 +1120,37 @@ ssl3_get_server_certificate(SSL *s) | |||
1120 | goto decode_err; | 1120 | goto decode_err; |
1121 | 1121 | ||
1122 | CBS_init(&cbs, s->internal->init_msg, s->internal->init_num); | 1122 | CBS_init(&cbs, s->internal->init_msg, s->internal->init_num); |
1123 | if (CBS_len(&cbs) < 3) | ||
1124 | goto decode_err; | ||
1125 | 1123 | ||
1126 | if (!CBS_get_u24_length_prefixed(&cbs, &cert_list) || | 1124 | if (!CBS_get_u24_length_prefixed(&cbs, &cert_list)) |
1127 | CBS_len(&cbs) != 0) { | 1125 | goto decode_err; |
1128 | al = SSL_AD_DECODE_ERROR; | 1126 | if (CBS_len(&cbs) != 0) |
1129 | SSLerror(s, SSL_R_LENGTH_MISMATCH); | 1127 | goto decode_err; |
1130 | goto fatal_err; | ||
1131 | } | ||
1132 | 1128 | ||
1133 | while (CBS_len(&cert_list) > 0) { | 1129 | while (CBS_len(&cert_list) > 0) { |
1134 | CBS cert; | 1130 | if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) |
1135 | |||
1136 | if (CBS_len(&cert_list) < 3) | ||
1137 | goto decode_err; | 1131 | goto decode_err; |
1138 | if (!CBS_get_u24_length_prefixed(&cert_list, &cert)) { | 1132 | p = CBS_data(&cert_data); |
1139 | al = SSL_AD_DECODE_ERROR; | 1133 | if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) { |
1140 | SSLerror(s, SSL_R_CERT_LENGTH_MISMATCH); | ||
1141 | goto fatal_err; | ||
1142 | } | ||
1143 | |||
1144 | q = CBS_data(&cert); | ||
1145 | x = d2i_X509(NULL, &q, CBS_len(&cert)); | ||
1146 | if (x == NULL) { | ||
1147 | al = SSL_AD_BAD_CERTIFICATE; | 1134 | al = SSL_AD_BAD_CERTIFICATE; |
1148 | SSLerror(s, ERR_R_ASN1_LIB); | 1135 | SSLerror(s, ERR_R_ASN1_LIB); |
1149 | goto fatal_err; | 1136 | goto fatal_err; |
1150 | } | 1137 | } |
1151 | if (q != CBS_data(&cert) + CBS_len(&cert)) { | 1138 | if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) |
1152 | al = SSL_AD_DECODE_ERROR; | 1139 | goto decode_err; |
1153 | SSLerror(s, SSL_R_CERT_LENGTH_MISMATCH); | 1140 | if (!sk_X509_push(certs, cert)) { |
1154 | goto fatal_err; | ||
1155 | } | ||
1156 | if (!sk_X509_push(sk, x)) { | ||
1157 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 1141 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
1158 | goto err; | 1142 | goto err; |
1159 | } | 1143 | } |
1160 | x = NULL; | 1144 | cert = NULL; |
1145 | } | ||
1146 | |||
1147 | /* A server must always provide a non-empty certificate list. */ | ||
1148 | if (sk_X509_num(certs) < 1) { | ||
1149 | SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); | ||
1150 | goto decode_err; | ||
1161 | } | 1151 | } |
1162 | 1152 | ||
1163 | if (ssl_verify_cert_chain(s, sk) <= 0 && | 1153 | if (ssl_verify_cert_chain(s, certs) <= 0 && |
1164 | s->verify_mode != SSL_VERIFY_NONE) { | 1154 | s->verify_mode != SSL_VERIFY_NONE) { |
1165 | al = ssl_verify_alarm_type(s->verify_result); | 1155 | al = ssl_verify_alarm_type(s->verify_result); |
1166 | SSLerror(s, SSL_R_CERTIFICATE_VERIFY_FAILED); | 1156 | SSLerror(s, SSL_R_CERTIFICATE_VERIFY_FAILED); |
@@ -1172,34 +1162,32 @@ ssl3_get_server_certificate(SSL *s) | |||
1172 | * Inconsistency alert: cert_chain does include the peer's | 1162 | * Inconsistency alert: cert_chain does include the peer's |
1173 | * certificate, which we don't include in s3_srvr.c | 1163 | * certificate, which we don't include in s3_srvr.c |
1174 | */ | 1164 | */ |
1175 | x = sk_X509_value(sk, 0); | 1165 | cert = sk_X509_value(certs, 0); |
1166 | X509_up_ref(cert); | ||
1176 | 1167 | ||
1177 | if ((pkey = X509_get0_pubkey(x)) == NULL || | 1168 | if ((pkey = X509_get0_pubkey(cert)) == NULL || |
1178 | EVP_PKEY_missing_parameters(pkey)) { | 1169 | EVP_PKEY_missing_parameters(pkey)) { |
1179 | x = NULL; | ||
1180 | al = SSL3_AL_FATAL; | 1170 | al = SSL3_AL_FATAL; |
1181 | SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); | 1171 | SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); |
1182 | goto fatal_err; | 1172 | goto fatal_err; |
1183 | } | 1173 | } |
1184 | if ((cert_type = ssl_cert_type(pkey)) < 0) { | 1174 | if ((cert_type = ssl_cert_type(pkey)) < 0) { |
1185 | x = NULL; | ||
1186 | al = SSL3_AL_FATAL; | 1175 | al = SSL3_AL_FATAL; |
1187 | SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE); | 1176 | SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE); |
1188 | goto fatal_err; | 1177 | goto fatal_err; |
1189 | } | 1178 | } |
1190 | 1179 | ||
1191 | X509_up_ref(x); | ||
1192 | X509_free(s->session->peer_cert); | 1180 | X509_free(s->session->peer_cert); |
1193 | s->session->peer_cert = x; | 1181 | X509_up_ref(cert); |
1182 | s->session->peer_cert = cert; | ||
1194 | s->session->peer_cert_type = cert_type; | 1183 | s->session->peer_cert_type = cert_type; |
1195 | 1184 | ||
1196 | s->session->verify_result = s->verify_result; | 1185 | s->session->verify_result = s->verify_result; |
1197 | 1186 | ||
1198 | sk_X509_pop_free(s->session->cert_chain, X509_free); | 1187 | sk_X509_pop_free(s->session->cert_chain, X509_free); |
1199 | s->session->cert_chain = sk; | 1188 | s->session->cert_chain = certs; |
1200 | sk = NULL; | 1189 | certs = NULL; |
1201 | 1190 | ||
1202 | x = NULL; | ||
1203 | ret = 1; | 1191 | ret = 1; |
1204 | 1192 | ||
1205 | if (0) { | 1193 | if (0) { |
@@ -1211,8 +1199,8 @@ ssl3_get_server_certificate(SSL *s) | |||
1211 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 1199 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
1212 | } | 1200 | } |
1213 | err: | 1201 | err: |
1214 | X509_free(x); | 1202 | sk_X509_pop_free(certs, X509_free); |
1215 | sk_X509_pop_free(sk, X509_free); | 1203 | X509_free(cert); |
1216 | 1204 | ||
1217 | return (ret); | 1205 | return (ret); |
1218 | } | 1206 | } |