* exception that |x| is self-issued and |ctx->chain| has just one element.
* Prefer the first match with suitable validity period or latest expiration.
*/
-static X509 *get0_best_issuer_sk(X509_STORE_CTX *ctx, int trusted,
+/*
+ * Note: so far, we do not check during chain building
+ * whether any key usage extension stands against a candidate issuer cert.
+ * Likely it would be good if build_chain() sets |check_signing_allowed|.
+ * Yet if |sk| is a list of trusted certs, as with X509_STORE_CTX_set0_trusted_stack(),
+ * better not set |check_signing_allowed|.
+ * Maybe not touch X509_STORE_CTX_get1_issuer(), for API backward compatiblity.
+ */
+static X509 *get0_best_issuer_sk(X509_STORE_CTX *ctx, int check_signing_allowed,
int no_dup, STACK_OF(X509) *sk, X509 *x)
{
int i;
candidate = sk_X509_value(sk, i);
if (no_dup
&& !((x->ex_flags & EXFLAG_SI) != 0 && sk_X509_num(ctx->chain) == 1)
- && sk_X509_contains(ctx->chain, candidate))
+ && sk_X509_contains(ctx->chain, candidate))
continue;
if (ctx->check_issued(ctx, x, candidate)) {
- if (!trusted) { /* do not check key usage for trust anchors */
- if (ossl_x509_signing_allowed(candidate, x) != X509_V_OK)
- continue;
- }
+ if (check_signing_allowed
+ /* yet better not check key usage for trust anchors */
+ && ossl_x509_signing_allowed(candidate, x) != X509_V_OK)
+ continue;
if (ossl_x509_check_cert_time(ctx, candidate, -1))
return candidate;
/*
if (certs == NULL)
return -1;
- *issuer = get0_best_issuer_sk(ctx, 1 /* trusted */, 0, certs, x);
+ *issuer = get0_best_issuer_sk(ctx, 0, 0 /* allow duplicates */, certs, x);
if (*issuer != NULL)
ret = X509_up_ref(*issuer) ? 1 : -1;
OSSL_STACK_OF_X509_free(certs);
*/
static int get1_best_issuer_other_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
- *issuer = get0_best_issuer_sk(ctx, 1 /* trusted */, 1 /* no_dup */,
- ctx->other_ctx, x);
+ *issuer = get0_best_issuer_sk(ctx, 0, 1 /* no_dup */, ctx->other_ctx, x);
if (*issuer == NULL)
return 0;
return X509_up_ref(*issuer) ? 1 : -1;
goto int_err;
curr = sk_X509_value(ctx->chain, num - 1);
issuer = (X509_self_signed(curr, 0) > 0 || num > max_depth) ?
- NULL : get0_best_issuer_sk(ctx, 0, 1, sk_untrusted, curr);
+ NULL : get0_best_issuer_sk(ctx, 0, 1 /* no_dup */, sk_untrusted, curr);
if (issuer == NULL) {
/*
* Once we have reached a self-signed cert or num > max_depth