diff options
| author | jsing <> | 2020-11-03 17:22:45 +0000 |
|---|---|---|
| committer | jsing <> | 2020-11-03 17:22:45 +0000 |
| commit | b7e071d468fd49ea9bbc98532eb8d0fff0bf974a (patch) | |
| tree | 543eb1214dc6b8aed4c5ba8c0c29e05da3bdaa29 | |
| parent | 8e671ab9449a693adfcba3a3763b6d321af32b52 (diff) | |
| download | openbsd-b7e071d468fd49ea9bbc98532eb8d0fff0bf974a.tar.gz openbsd-b7e071d468fd49ea9bbc98532eb8d0fff0bf974a.tar.bz2 openbsd-b7e071d468fd49ea9bbc98532eb8d0fff0bf974a.zip | |
Hook X509_STORE_CTX get_issuer() callback from new X509 verifier.
If we fail to find a parent certificate from either the supplied roots or
intermediates and we have a X509_STORE_CTX, call its get_issuer() callback
to see if it can supply a suitable certificate. This makes things like
certificates by directory (aka by_dir) work correctly.
Issue noted by Uwe Werler <uwe@werler.is>
ok beck@ tb@
| -rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index 124d4ba34e..6ab1cad2ad 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.16 2020/10/26 12:01:01 tb Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.17 2020/11/03 17:22:45 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -401,7 +401,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 401 | { | 401 | { |
| 402 | unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 }; | 402 | unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 }; |
| 403 | X509 *candidate; | 403 | X509 *candidate; |
| 404 | int i, depth, count; | 404 | int i, depth, count, ret; |
| 405 | 405 | ||
| 406 | depth = sk_X509_num(current_chain->certs); | 406 | depth = sk_X509_num(current_chain->certs); |
| 407 | if (depth > 0) | 407 | if (depth > 0) |
| @@ -428,7 +428,6 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 428 | cert_md, 1, candidate, current_chain); | 428 | cert_md, 1, candidate, current_chain); |
| 429 | } | 429 | } |
| 430 | } | 430 | } |
| 431 | |||
| 432 | if (ctx->intermediates != NULL) { | 431 | if (ctx->intermediates != NULL) { |
| 433 | for (i = 0; i < sk_X509_num(ctx->intermediates); i++) { | 432 | for (i = 0; i < sk_X509_num(ctx->intermediates); i++) { |
| 434 | candidate = sk_X509_value(ctx->intermediates, i); | 433 | candidate = sk_X509_value(ctx->intermediates, i); |
| @@ -438,6 +437,21 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 438 | } | 437 | } |
| 439 | } | 438 | } |
| 440 | } | 439 | } |
| 440 | if (ctx->xsc != NULL) { | ||
| 441 | if ((ret = ctx->xsc->get_issuer(&candidate, ctx->xsc, cert)) < 0) { | ||
| 442 | x509_verify_cert_error(ctx, cert, depth, | ||
| 443 | X509_V_ERR_STORE_LOOKUP, 0); | ||
| 444 | return; | ||
| 445 | } | ||
| 446 | if (ret > 0) { | ||
| 447 | if (x509_verify_potential_parent(ctx, candidate, cert)) { | ||
| 448 | x509_verify_consider_candidate(ctx, cert, | ||
| 449 | cert_md, 1, candidate, current_chain); | ||
| 450 | } | ||
| 451 | X509_free(candidate); | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 441 | if (ctx->chains_count > count) { | 455 | if (ctx->chains_count > count) { |
| 442 | if (ctx->xsc != NULL) { | 456 | if (ctx->xsc != NULL) { |
| 443 | ctx->xsc->error = X509_V_OK; | 457 | ctx->xsc->error = X509_V_OK; |
