summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2021-11-24 09:28:56 +0000
committertb <>2021-11-24 09:28:56 +0000
commit2c0e7f8ac54f86297f1f41b51254e4b672dc9a6c (patch)
tree43f0280ff3795786784edb02273862918922c8ba
parenta091f55fdff9699931b85df586c79f5ffe01d616 (diff)
downloadopenbsd-2c0e7f8ac54f86297f1f41b51254e4b672dc9a6c.tar.gz
openbsd-2c0e7f8ac54f86297f1f41b51254e4b672dc9a6c.tar.bz2
openbsd-2c0e7f8ac54f86297f1f41b51254e4b672dc9a6c.zip
In some situations, the verifier would discard the error on an unvalidatedlibressl-v3.4.3libressl-v3.4.2
certificate chain. This would happen when the verification callback was in use, instructing the verifier to continue unconditionally. This could lead to incorrect decisions being made in software. This is patches/common/006_x509.patch.sig
-rw-r--r--src/lib/libcrypto/x509/x509_internal.h4
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c129
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c8
3 files changed, 91 insertions, 50 deletions
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h
index 8891aecb13..9878b6febd 100644
--- a/src/lib/libcrypto/x509/x509_internal.h
+++ b/src/lib/libcrypto/x509/x509_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_internal.h,v 1.12 2021/09/03 08:58:53 beck Exp $ */ 1/* $OpenBSD: x509_internal.h,v 1.12.2.1 2021/11/24 09:28:55 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -90,7 +90,7 @@ int x509_vfy_check_revocation(X509_STORE_CTX *ctx);
90int x509_vfy_check_policy(X509_STORE_CTX *ctx); 90int x509_vfy_check_policy(X509_STORE_CTX *ctx);
91int x509_vfy_check_trust(X509_STORE_CTX *ctx); 91int x509_vfy_check_trust(X509_STORE_CTX *ctx);
92int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx); 92int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
93int x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx); 93int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx);
94void x509v3_cache_extensions(X509 *x); 94void x509v3_cache_extensions(X509 *x);
95X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); 95X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
96 96
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
index e49fbdee48..5ff7c50653 100644
--- a/src/lib/libcrypto/x509/x509_verify.c
+++ b/src/lib/libcrypto/x509/x509_verify.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_verify.c,v 1.49 2021/09/09 15:09:43 beck Exp $ */ 1/* $OpenBSD: x509_verify.c,v 1.49.2.1 2021/11/24 09:28:56 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -1171,62 +1171,99 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1171 x509_verify_chain_free(current_chain); 1171 x509_verify_chain_free(current_chain);
1172 1172
1173 /* 1173 /*
1174 * Bring back the failure case we wanted to the xsc if 1174 * Do the new verifier style return, where we don't have an xsc
1175 * we saved one. 1175 * that allows a crazy callback to turn invalid things into valid.
1176 */ 1176 */
1177 if (!x509_verify_ctx_restore_xsc_error(ctx)) 1177 if (ctx->xsc == NULL) {
1178 goto err; 1178 /*
1179 * Safety net:
1180 * We could not find a validated chain, and for some reason do not
1181 * have an error set.
1182 */
1183 if (ctx->chains_count == 0 && ctx->error == X509_V_OK)
1184 ctx->error = X509_V_ERR_UNSPECIFIED;
1185
1186 /*
1187 * If we are not using an xsc, and have no possibility for the
1188 * crazy OpenSSL callback API changing the results of
1189 * validation steps (because the callback can make validation
1190 * proceed in the presence of invalid certs), any chains we
1191 * have here are correctly built and verified.
1192 */
1193 if (ctx->chains_count > 0)
1194 ctx->error = X509_V_OK;
1195
1196 return ctx->chains_count;
1197 }
1179 1198
1180 /* 1199 /*
1181 * Safety net: 1200 * Otherwise we are doing compatibility with an xsc, which means that we
1182 * We could not find a validated chain, and for some reason do not 1201 * will have one chain, which might actually be a bogus chain because
1183 * have an error set. 1202 * the callback told us to ignore errors and proceed to build an invalid
1203 * chain. Possible return values from this include returning 1 with an
1204 * invalid chain and a value of xsc->error != X509_V_OK (It's tradition
1205 * that makes it ok).
1184 */ 1206 */
1185 if (ctx->chains_count == 0 && ctx->error == X509_V_OK) {
1186 ctx->error = X509_V_ERR_UNSPECIFIED;
1187 if (ctx->xsc != NULL && ctx->xsc->error != X509_V_OK)
1188 ctx->error = ctx->xsc->error;
1189 }
1190 1207
1191 /* Clear whatever errors happened if we have any validated chain */ 1208 if (ctx->chains_count > 0) {
1192 if (ctx->chains_count > 0) 1209 /*
1193 ctx->error = X509_V_OK; 1210 * The chain we have using an xsc might not be a verified chain
1211 * if the callback perverted things while we built it to ignore
1212 * failures and proceed with chain building. We put this chain
1213 * and the error associated with it on the xsc.
1214 */
1215 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1, 1))
1216 goto err;
1194 1217
1195 if (ctx->xsc != NULL) { 1218 /*
1196 ctx->xsc->error = ctx->error; 1219 * Call the callback for completion up our built
1197 if (ctx->chains_count > 0) { 1220 * chain. The callback could still tell us to
1198 /* Take the first chain we found. */ 1221 * fail. Since this chain might exist as the result of
1199 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1222 * callback doing perversions, we could still return
1200 1, 1)) 1223 * "success" with something other than X509_V_OK set
1201 goto err; 1224 * as the error.
1202 ctx->xsc->error = X509_V_OK; 1225 */
1203 /* 1226 if (!x509_vfy_callback_indicate_completion(ctx->xsc))
1204 * Call the callback indicating success up our already 1227 goto err;
1205 * verified chain. The callback could still tell us to 1228 } else {
1206 * fail. 1229 /*
1207 */ 1230 * We did not find a chain. Bring back the failure
1208 if(!x509_vfy_callback_indicate_success(ctx->xsc)) { 1231 * case we wanted to the xsc if we saved one. If we
1209 /* The callback can change the error code */ 1232 * did not we should have just the leaf on the xsc.
1210 ctx->error = ctx->xsc->error; 1233 */
1211 goto err; 1234 if (!x509_verify_ctx_restore_xsc_error(ctx))
1212 } 1235 goto err;
1213 } else { 1236
1214 /* 1237 /*
1215 * We had a failure, indicate the failure, but 1238 * Safety net, ensure we have an error set in the
1216 * allow the callback to override at depth 0 1239 * failing case.
1217 */ 1240 */
1218 if (ctx->xsc->verify_cb(0, ctx->xsc)) { 1241 if (ctx->xsc->error == X509_V_OK) {
1219 ctx->xsc->error = X509_V_OK; 1242 if (ctx->error == X509_V_OK)
1220 return 1; 1243 ctx->error = X509_V_ERR_UNSPECIFIED;
1221 } 1244 ctx->xsc->error = ctx->error;
1222 } 1245 }
1246
1247 /*
1248 * Let the callback override the return value
1249 * at depth 0 if it chooses to
1250 */
1251 return ctx->xsc->verify_cb(0, ctx->xsc);
1223 } 1252 }
1224 return (ctx->chains_count); 1253
1254 /* We only ever find one chain in compat mode with an xsc. */
1255 return 1;
1225 1256
1226 err: 1257 err:
1227 if (ctx->error == X509_V_OK) 1258 if (ctx->error == X509_V_OK)
1228 ctx->error = X509_V_ERR_UNSPECIFIED; 1259 ctx->error = X509_V_ERR_UNSPECIFIED;
1229 if (ctx->xsc != NULL) 1260
1230 ctx->xsc->error = ctx->error; 1261 if (ctx->xsc != NULL) {
1262 if (ctx->xsc->error == X509_V_OK)
1263 ctx->xsc->error = X509_V_ERR_UNSPECIFIED;
1264 ctx->error = ctx->xsc->error;
1265 }
1266
1231 return 0; 1267 return 0;
1232} 1268}
1269
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index 2f69017e96..1f52779911 100644
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ b/src/lib/libcrypto/x509/x509_vfy.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_vfy.c,v 1.89 2021/09/03 08:58:53 beck Exp $ */ 1/* $OpenBSD: x509_vfy.c,v 1.89.2.1 2021/11/24 09:28:56 tb 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 *
@@ -1960,8 +1960,12 @@ internal_verify(X509_STORE_CTX *ctx)
1960 return x509_vfy_internal_verify(ctx, 0); 1960 return x509_vfy_internal_verify(ctx, 0);
1961} 1961}
1962 1962
1963/*
1964 * Internal verify, but with a chain where the verification
1965 * math has already been performed.
1966 */
1963int 1967int
1964x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx) 1968x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx)
1965{ 1969{
1966 return x509_vfy_internal_verify(ctx, 1); 1970 return x509_vfy_internal_verify(ctx, 1);
1967} 1971}