summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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}