summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_verify.c
diff options
context:
space:
mode:
authorbeck <>2021-09-03 08:58:53 +0000
committerbeck <>2021-09-03 08:58:53 +0000
commiteabb493f0d6e4fe79346324ce6f5ac67a874928a (patch)
tree9c46aa8dc9877d0ff22a6819eece4485287e26be /src/lib/libcrypto/x509/x509_verify.c
parentbc45016d90bc7c94c8c5358acacd475d210bd576 (diff)
downloadopenbsd-eabb493f0d6e4fe79346324ce6f5ac67a874928a.tar.gz
openbsd-eabb493f0d6e4fe79346324ce6f5ac67a874928a.tar.bz2
openbsd-eabb493f0d6e4fe79346324ce6f5ac67a874928a.zip
Call the callback on success in new verifier in a compatible way
when we succeed with a chain, and ensure we do not call the callback twice when the caller doesn't expect it. A refactor of the end of the legacy verify code in x509_vfy is probably overdue, but this should be done based on a piece that works. the important bit here is this allows the perl regression tests in tree to pass. Changes the previously committed regress tests to test the success case callbacks to be known to pass. ok bluhm@ tb@
Diffstat (limited to 'src/lib/libcrypto/x509/x509_verify.c')
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
index 39371ef038..2ec53f6fc8 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.47 2021/08/30 08:59:33 beck Exp $ */ 1/* $OpenBSD: x509_verify.c,v 1.48 2021/09/03 08:58:53 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 *
@@ -383,6 +383,7 @@ x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx,
383 return 0; 383 return 0;
384 chain->cert_errors[ctx->xsc->error_depth] = 384 chain->cert_errors[ctx->xsc->error_depth] =
385 ctx->xsc->error; 385 ctx->xsc->error;
386 ctx->error_depth = ctx->xsc->error_depth;
386 } 387 }
387 388
388 return ret; 389 return ret;
@@ -537,10 +538,11 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
537 x509_verify_chain_free(new_chain); 538 x509_verify_chain_free(new_chain);
538 return 0; 539 return 0;
539 } 540 }
540 if (x509_verify_cert_error(ctx, candidate, depth, X509_V_OK, 1)) { 541 if (!x509_verify_ctx_add_chain(ctx, new_chain)) {
541 (void) x509_verify_ctx_add_chain(ctx, new_chain); 542 x509_verify_chain_free(new_chain);
542 goto done; 543 return 0;
543 } 544 }
545 goto done;
544 } 546 }
545 547
546 x509_verify_build_chains(ctx, candidate, new_chain, full_chain); 548 x509_verify_build_chains(ctx, candidate, new_chain, full_chain);
@@ -596,8 +598,15 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
596 return; 598 return;
597 599
598 count = ctx->chains_count; 600 count = ctx->chains_count;
601
599 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; 602 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
600 ctx->error_depth = depth; 603 ctx->error_depth = depth;
604
605 if (ctx->saved_error != 0)
606 ctx->error = ctx->saved_error;
607 if (ctx->saved_error_depth != 0)
608 ctx->error_depth = ctx->saved_error_depth;
609
601 if (ctx->xsc != NULL) { 610 if (ctx->xsc != NULL) {
602 /* 611 /*
603 * Long ago experiments at Muppet labs resulted in a 612 * Long ago experiments at Muppet labs resulted in a
@@ -663,8 +672,6 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
663 } else if (ctx->error_depth == depth) { 672 } else if (ctx->error_depth == depth) {
664 if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0)) 673 if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0))
665 return; 674 return;
666 (void) x509_verify_cert_error(ctx, cert, depth,
667 ctx->error, 0);
668 } 675 }
669} 676}
670 677
@@ -1131,9 +1138,12 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1131 } 1138 }
1132 do { 1139 do {
1133 retry_chain_build = 0; 1140 retry_chain_build = 0;
1134 if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) 1141 if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) {
1135 x509_verify_ctx_add_chain(ctx, current_chain); 1142 if (!x509_verify_ctx_add_chain(ctx, current_chain)) {
1136 else { 1143 x509_verify_chain_free(current_chain);
1144 goto err;
1145 }
1146 } else {
1137 x509_verify_build_chains(ctx, leaf, current_chain, 1147 x509_verify_build_chains(ctx, leaf, current_chain,
1138 full_chain); 1148 full_chain);
1139 if (full_chain && ctx->chains_count == 0) { 1149 if (full_chain && ctx->chains_count == 0) {
@@ -1189,8 +1199,24 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1189 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1199 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0],
1190 1, 1)) 1200 1, 1))
1191 goto err; 1201 goto err;
1202 ctx->xsc->error = X509_V_OK;
1203 /*
1204 * Call the callback indicating success up our already
1205 * verified chain. The callback could still tell us to
1206 * fail.
1207 */
1208 if(!x509_vfy_callback_indicate_success(ctx->xsc))
1209 goto err;
1210 } else {
1211 /*
1212 * We had a failure, indicate the failure, but
1213 * allow the callback to override at depth 0
1214 */
1215 if (ctx->xsc->verify_cb(0, ctx->xsc)) {
1216 ctx->xsc->error = X509_V_OK;
1217 return 1;
1218 }
1192 } 1219 }
1193 return ctx->xsc->verify_cb(ctx->chains_count > 0, ctx->xsc);
1194 } 1220 }
1195 return (ctx->chains_count); 1221 return (ctx->chains_count);
1196 1222