-/* $OpenBSD: x509_internal.h,v 1.11 2021/08/28 15:22:42 beck Exp $ */
+/* $OpenBSD: x509_internal.h,v 1.12 2021/09/03 08:58:53 beck Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
int x509_vfy_check_policy(X509_STORE_CTX *ctx);
int x509_vfy_check_trust(X509_STORE_CTX *ctx);
int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
+int x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx);
void x509v3_cache_extensions(X509 *x);
X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
-/* $OpenBSD: x509_verify.c,v 1.47 2021/08/30 08:59:33 beck Exp $ */
+/* $OpenBSD: x509_verify.c,v 1.48 2021/09/03 08:58:53 beck Exp $ */
/*
* Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org>
*
return 0;
chain->cert_errors[ctx->xsc->error_depth] =
ctx->xsc->error;
+ ctx->error_depth = ctx->xsc->error_depth;
}
return ret;
x509_verify_chain_free(new_chain);
return 0;
}
- if (x509_verify_cert_error(ctx, candidate, depth, X509_V_OK, 1)) {
- (void) x509_verify_ctx_add_chain(ctx, new_chain);
- goto done;
+ if (!x509_verify_ctx_add_chain(ctx, new_chain)) {
+ x509_verify_chain_free(new_chain);
+ return 0;
}
+ goto done;
}
x509_verify_build_chains(ctx, candidate, new_chain, full_chain);
return;
count = ctx->chains_count;
+
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
ctx->error_depth = depth;
+
+ if (ctx->saved_error != 0)
+ ctx->error = ctx->saved_error;
+ if (ctx->saved_error_depth != 0)
+ ctx->error_depth = ctx->saved_error_depth;
+
if (ctx->xsc != NULL) {
/*
* Long ago experiments at Muppet labs resulted in a
} else if (ctx->error_depth == depth) {
if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0))
return;
- (void) x509_verify_cert_error(ctx, cert, depth,
- ctx->error, 0);
}
}
}
do {
retry_chain_build = 0;
- if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain))
- x509_verify_ctx_add_chain(ctx, current_chain);
- else {
+ if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) {
+ if (!x509_verify_ctx_add_chain(ctx, current_chain)) {
+ x509_verify_chain_free(current_chain);
+ goto err;
+ }
+ } else {
x509_verify_build_chains(ctx, leaf, current_chain,
full_chain);
if (full_chain && ctx->chains_count == 0) {
if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0],
1, 1))
goto err;
+ ctx->xsc->error = X509_V_OK;
+ /*
+ * Call the callback indicating success up our already
+ * verified chain. The callback could still tell us to
+ * fail.
+ */
+ if(!x509_vfy_callback_indicate_success(ctx->xsc))
+ goto err;
+ } else {
+ /*
+ * We had a failure, indicate the failure, but
+ * allow the callback to override at depth 0
+ */
+ if (ctx->xsc->verify_cb(0, ctx->xsc)) {
+ ctx->xsc->error = X509_V_OK;
+ return 1;
+ }
}
- return ctx->xsc->verify_cb(ctx->chains_count > 0, ctx->xsc);
}
return (ctx->chains_count);
-/* $OpenBSD: x509_vfy.c,v 1.88 2021/08/28 15:22:42 beck Exp $ */
+/* $OpenBSD: x509_vfy.c,v 1.89 2021/09/03 08:58:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
}
static int
-internal_verify(X509_STORE_CTX *ctx)
+x509_vfy_internal_verify(X509_STORE_CTX *ctx, int chain_verified)
{
int n = sk_X509_num(ctx->chain) - 1;
X509 *xi = sk_X509_value(ctx->chain, n);
* certificate and its depth (rather than the depth of
* the subject).
*/
- if (xs != xi ||
- (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
+ if (!chain_verified && ( xs != xi ||
+ (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
EVP_PKEY *pkey;
if ((pkey = X509_get_pubkey(xi)) == NULL) {
if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n,
}
check_cert:
/* Calls verify callback as needed */
- if (!x509_check_cert_time(ctx, xs, n))
+ if (!chain_verified && !x509_check_cert_time(ctx, xs, n))
return 0;
/*
return 1;
}
+static int
+internal_verify(X509_STORE_CTX *ctx)
+{
+ return x509_vfy_internal_verify(ctx, 0);
+}
+
+int
+x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx)
+{
+ return x509_vfy_internal_verify(ctx, 1);
+}
+
int
X509_cmp_current_time(const ASN1_TIME *ctm)
{
-# $OpenBSD: Makefile,v 1.7 2021/09/01 08:12:15 beck Exp $
+# $OpenBSD: Makefile,v 1.8 2021/09/03 08:58:53 beck Exp $
PROGS = constraints verify x509attribute x509name callback
LDADD= -Wl,-Bstatic -lcrypto -Wl,-Bdynamic
REGRESS_TARGETS += regress-x509name
REGRESS_TARGETS += regress-callback
-REGRESS_EXPECTED_FAILURES += regress-callback
-
CLEANFILES+= x509name.result callbackout
.if make(clean) || make(cleandir)