summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 a9b584b13e..9ac0c2bbde 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.15 2021/11/04 23:52:34 beck Exp $ */ 1/* $OpenBSD: x509_internal.h,v 1.16 2021/11/24 05:38:12 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -92,7 +92,7 @@ int x509_vfy_check_revocation(X509_STORE_CTX *ctx);
92int x509_vfy_check_policy(X509_STORE_CTX *ctx); 92int x509_vfy_check_policy(X509_STORE_CTX *ctx);
93int x509_vfy_check_trust(X509_STORE_CTX *ctx); 93int x509_vfy_check_trust(X509_STORE_CTX *ctx);
94int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx); 94int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
95int x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx); 95int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx);
96void x509v3_cache_extensions(X509 *x); 96void x509v3_cache_extensions(X509 *x);
97X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); 97X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
98 98
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
index e7493fdbf0..6a73cb74e2 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.53 2021/11/14 08:21:47 jsing Exp $ */ 1/* $OpenBSD: x509_verify.c,v 1.54 2021/11/24 05:38:12 beck 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 *
@@ -1164,62 +1164,99 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1164 x509_verify_chain_free(current_chain); 1164 x509_verify_chain_free(current_chain);
1165 1165
1166 /* 1166 /*
1167 * Bring back the failure case we wanted to the xsc if 1167 * Do the new verifier style return, where we don't have an xsc
1168 * we saved one. 1168 * that allows a crazy callback to turn invalid things into valid.
1169 */ 1169 */
1170 if (!x509_verify_ctx_restore_xsc_error(ctx)) 1170 if (ctx->xsc == NULL) {
1171 goto err; 1171 /*
1172 * Safety net:
1173 * We could not find a validated chain, and for some reason do not
1174 * have an error set.
1175 */
1176 if (ctx->chains_count == 0 && ctx->error == X509_V_OK)
1177 ctx->error = X509_V_ERR_UNSPECIFIED;
1178
1179 /*
1180 * If we are not using an xsc, and have no possibility for the
1181 * crazy OpenSSL callback API changing the results of
1182 * validation steps (because the callback can make validation
1183 * proceed in the presence of invalid certs), any chains we
1184 * have here are correctly built and verified.
1185 */
1186 if (ctx->chains_count > 0)
1187 ctx->error = X509_V_OK;
1188
1189 return ctx->chains_count;
1190 }
1172 1191
1173 /* 1192 /*
1174 * Safety net: 1193 * Otherwise we are doing compatibility with an xsc, which means that we
1175 * We could not find a validated chain, and for some reason do not 1194 * will have one chain, which might actually be a bogus chain because
1176 * have an error set. 1195 * the callback told us to ignore errors and proceed to build an invalid
1196 * chain. Possible return values from this include returning 1 with an
1197 * invalid chain and a value of xsc->error != X509_V_OK (It's tradition
1198 * that makes it ok).
1177 */ 1199 */
1178 if (ctx->chains_count == 0 && ctx->error == X509_V_OK) {
1179 ctx->error = X509_V_ERR_UNSPECIFIED;
1180 if (ctx->xsc != NULL && ctx->xsc->error != X509_V_OK)
1181 ctx->error = ctx->xsc->error;
1182 }
1183 1200
1184 /* Clear whatever errors happened if we have any validated chain */ 1201 if (ctx->chains_count > 0) {
1185 if (ctx->chains_count > 0) 1202 /*
1186 ctx->error = X509_V_OK; 1203 * The chain we have using an xsc might not be a verified chain
1204 * if the callback perverted things while we built it to ignore
1205 * failures and proceed with chain building. We put this chain
1206 * and the error associated with it on the xsc.
1207 */
1208 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1, 1))
1209 goto err;
1187 1210
1188 if (ctx->xsc != NULL) { 1211 /*
1189 ctx->xsc->error = ctx->error; 1212 * Call the callback for completion up our built
1190 if (ctx->chains_count > 0) { 1213 * chain. The callback could still tell us to
1191 /* Take the first chain we found. */ 1214 * fail. Since this chain might exist as the result of
1192 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1215 * callback doing perversions, we could still return
1193 1, 1)) 1216 * "success" with something other than X509_V_OK set
1194 goto err; 1217 * as the error.
1195 ctx->xsc->error = X509_V_OK; 1218 */
1196 /* 1219 if (!x509_vfy_callback_indicate_completion(ctx->xsc))
1197 * Call the callback indicating success up our already 1220 goto err;
1198 * verified chain. The callback could still tell us to 1221 } else {
1199 * fail. 1222 /*
1200 */ 1223 * We did not find a chain. Bring back the failure
1201 if(!x509_vfy_callback_indicate_success(ctx->xsc)) { 1224 * case we wanted to the xsc if we saved one. If we
1202 /* The callback can change the error code */ 1225 * did not we should have just the leaf on the xsc.
1203 ctx->error = ctx->xsc->error; 1226 */
1204 goto err; 1227 if (!x509_verify_ctx_restore_xsc_error(ctx))
1205 } 1228 goto err;
1206 } else { 1229
1207 /* 1230 /*
1208 * We had a failure, indicate the failure, but 1231 * Safety net, ensure we have an error set in the
1209 * allow the callback to override at depth 0 1232 * failing case.
1210 */ 1233 */
1211 if (ctx->xsc->verify_cb(0, ctx->xsc)) { 1234 if (ctx->xsc->error == X509_V_OK) {
1212 ctx->xsc->error = X509_V_OK; 1235 if (ctx->error == X509_V_OK)
1213 return 1; 1236 ctx->error = X509_V_ERR_UNSPECIFIED;
1214 } 1237 ctx->xsc->error = ctx->error;
1215 } 1238 }
1239
1240 /*
1241 * Let the callback override the return value
1242 * at depth 0 if it chooses to
1243 */
1244 return ctx->xsc->verify_cb(0, ctx->xsc);
1216 } 1245 }
1217 return (ctx->chains_count); 1246
1247 /* We only ever find one chain in compat mode with an xsc. */
1248 return 1;
1218 1249
1219 err: 1250 err:
1220 if (ctx->error == X509_V_OK) 1251 if (ctx->error == X509_V_OK)
1221 ctx->error = X509_V_ERR_UNSPECIFIED; 1252 ctx->error = X509_V_ERR_UNSPECIFIED;
1222 if (ctx->xsc != NULL) 1253
1223 ctx->xsc->error = ctx->error; 1254 if (ctx->xsc != NULL) {
1255 if (ctx->xsc->error == X509_V_OK)
1256 ctx->xsc->error = X509_V_ERR_UNSPECIFIED;
1257 ctx->error = ctx->xsc->error;
1258 }
1259
1224 return 0; 1260 return 0;
1225} 1261}
1262
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index b044f4931e..db2125b48d 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.97 2021/11/13 18:24:45 schwarze Exp $ */ 1/* $OpenBSD: x509_vfy.c,v 1.98 2021/11/24 05:38:12 beck 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 *
@@ -1989,8 +1989,12 @@ internal_verify(X509_STORE_CTX *ctx)
1989 return x509_vfy_internal_verify(ctx, 0); 1989 return x509_vfy_internal_verify(ctx, 0);
1990} 1990}
1991 1991
1992/*
1993 * Internal verify, but with a chain where the verification
1994 * math has already been performed.
1995 */
1992int 1996int
1993x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx) 1997x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx)
1994{ 1998{
1995 return x509_vfy_internal_verify(ctx, 1); 1999 return x509_vfy_internal_verify(ctx, 1);
1996} 2000}