diff options
author | jsing <> | 2022-07-03 14:52:39 +0000 |
---|---|---|
committer | jsing <> | 2022-07-03 14:52:39 +0000 |
commit | 1ffc21a41f265a4910719c37b047e1583145350d (patch) | |
tree | 231014d5c8a73baa0d89d717c78bb14252955b70 /src | |
parent | 5f45601ea6aa0b2b60618271d2c77b278d5f4cfc (diff) | |
download | openbsd-1ffc21a41f265a4910719c37b047e1583145350d.tar.gz openbsd-1ffc21a41f265a4910719c37b047e1583145350d.tar.bz2 openbsd-1ffc21a41f265a4910719c37b047e1583145350d.zip |
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 'src')
-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 | } |