Skip to content

Crl Processing Changes: Allow for multiple CRLs per issuer and allow more paths to revoke certs - #12116

Open
aidankeefe2022 wants to merge 4 commits into
wolfSSL:masterfrom
aidankeefe2022:zendesk-crl
Open

aidankeefe2022 wants to merge 4 commits into
wolfSSL:masterfrom
aidankeefe2022:zendesk-crl

Conversation

@aidankeefe2022

@aidankeefe2022 aidankeefe2022 commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Description

Zendesk #: https://wolfssl.zendesk.com/agent/tickets/22769

wolfSSL found a cert's CRL by issuer name alone. When a CA rolls its key, or signs CRLs with a separate key, it publishes one CRL series per key under the same name. That broke CRL checking in three ways:

  • Missed revocations: a CRL from one key was treated as a duplicate of, or was replaced by, a CRL from another key of the same CA. Revocations in the dropped CRL were lost.
  • Wrong CRL used: the check could stop at the first CRL with a matching name, even when it came from a different key than the one that signed the cert.
  • Wrong chain walk: the WOLFSSL_CRL_CHECKALL walk moved to the first CA with the issuer's name, not the CA whose key actually signed the intermediate.

Changes

Storing CRLs (AddCRL, src/crl.c)

  • Each signing key of a same-name CA now keeps its own CRL series, identified by AKID. A new CRL replaces a stored one only when both were signed by the same key. The usual CRL number and date checks then apply.
  • A new CRL with an AKID can replace a stored one without an AKID, but not the other way around.
  • An unverified CRL can't replace a verified one from the same issuer.

Checking certs (CheckCertCRLList / CheckCertCRL_ex, src/crl.c)

  • CheckCertCRL_ex takes a new akid argument: the cert's Authority Key Identifier.
  • All CRLs with the issuer's name are checked and split into two groups:
    • own-key: the CRL's AKID matches the cert's AKID, or one side has no AKID
    • other-key: the AKIDs differ
  • Own-key CRLs are preferred. If there is none, other-key CRLs are used as a fallback.
  • Any fresh, verified CRL for the issuer name can revoke the cert, since issuer name plus serial uniquely identifies it.
  • An other-key CRL can only show the cert is not revoked if its key chains to the same trust anchor as the cert's issuer (RFC 5280 §6.3.3(f)). If it doesn't, it still counts toward revocation, but otherwise the result is CRL_MISSING. This is due to key rollover protection: where the anchor has shifted, we want to be on the safe side and still honor CRLs that are valid.bbbb
  • A stored CRL that fails signature verification is now skipped instead of failing the whole check, because another CRL for the issuer may still apply.

Chain walk (ProcessPeerCertsChainCRLCheck, src/internal.c)

  • The walk now uses the new GetCAIssuer(). It finds the issuer by the CA's AKID and confirms the subject name matches, falling back to the name when there is no AKID. Each CA's AKID is passed to `CheckC
  • Loop protection:
    • a two-CA cross-certificate
    • longer loops stop at WOLFSSL_MAX_CHAIN_DEPTH with ASN_PATHLEN_SIZE_E

Trade-off

When no own-key CRL exists, falling back to other-key CRLs from the same issuer name can occasionally reject a cert that should pass. We chose this over the opposite risk of accepting a revoked cert. This is due to key rollover protection: where the anchor has shifted, we want to be on the safe side and still honor CRLs that are valid by rejecting based on issuer as a last resort.

Other Changes:

  • Api test was putting CRLs in a non-tmp dir, causing a later test to pick it up; with the CRL fixes, this triggered a test failure. The fix was not to write crl to the real directory.

Testing

Added 8 tests to make sure CRLs are handled properly. These tests include a large set of certs and CRLs: tests/api/test_certman_crl_fixtures.h

  1. test_wolfSSL_CRL_skip_unverifiable
  2. test_wolfSSL_CRL_same_name_key_rollover
  3. test_wolfSSL_CRL_crl_only_signing_key
  4. test_wolfSSL_CRL_other_key_fallback
  5. test_wolfSSL_CRL_other_key_trust_anchor
  6. test_wolfSSL_CRL_chain_same_name_key_rollover
  7. test_wolfSSL_CRL_chain_walk_follows_akid
  8. test_wolfSSL_CRL_chain_walk_cycle

I also updated the white box tests to match the new behavior.

Checklist

  • added tests

Major change for adding CRLs

They are now only reported as duplicates if the issuer name and AKID do
not match if AKDI is avaible. We then go into out normal checks for CLR
number and date. This means that multiple CRLs from one issuer are added
and we do not miss any revocations.

When checking certs with issuer we match with name and AKID.
If that does not work we then fall back to matching to any
CRL with same issuer name. This can lead to rejecting when we should not
but it is better than accpeting when we should not trade-off.
@aidankeefe2022 aidankeefe2022 self-assigned this Nov 12, 2026
Copilot AI balanced review requested due to automatic review settings November 12, 2026 23:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

An AKID-less CRL update can discard another signing key’s revocations, allowing revoked certificates to pass, and the cycle test does not exercise the new CRL-walk guard.

2 open issues
What changed in this PR

This PR updates wolfSSL’s certificate revocation checks to distinguish CRLs by issuer name and authority key identifier (AKID), supporting issuers with multiple signing keys.

Changes:

  • Keeps separate CRL series for different keys and adds same-name fallback handling.
  • Passes AKIDs through certificate and chain checks, with bounded chain traversal.
  • Adds fixtures and regression tests for key rollover, CRL-only keys, unverifiable CRLs, and cycles.
File Description
wolfssl/​wolfcrypt/​asn.h Makes signer AKID fields available for CRL checks.
wolfssl/​crl.h Adds AKID to the internal CRL-check interface.
wolfcrypt/​src/​asn.c Copies signer AKIDs in CRL-enabled builds.
tests/​unit-mcdc/​test_internal_revocation_whitebox.c Updates CRL mocks for the new argument.
tests/​unit-mcdc/​test_crl_whitebox.c Adds AKID matching and CRL-series test vectors.
tests/​api/​test_certman.h Registers new CRL regression tests.
tests/​api/​test_certman.c Tests rollover, fallback, verification failures, and chain traversal.
tests/​api/​test_certman_crl_fixtures.h Adds certificate, key, and CRL fixtures.
tests/​api/​include.am Includes the fixture header in source distributions.
src/​internal.c Follows issuer AKIDs and bounds CRL chain traversal.
src/​crl.c Updates CRL storage, matching, and fallback behavior.

Review effort: Balanced

Comment thread src/crl.c Resolved
Comment thread src/internal.c Resolved

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #12116

Scan targets checked: wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): tests/api/include.am, tests/api/test_certman.h, tests/api/test_certman_crl_fixtures.h
Coverage: 8 of 8 in-scope changed file(s) opened by the reviewer

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Review tier: Max

Comment thread src/crl.c Resolved
Comment thread src/crl.c Resolved
…that AKIDN mismatch leads to same trust anchor

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #12116

Scan targets checked: wolfssl-src, wolfssl-bugs
Unchanged since last review (not re-run): wolfcrypt-src, wolfcrypt-bugs
Not reviewed (no scan target covers them): tests/api/include.am, tests/api/test_certman.h, tests/api/test_certman_crl_fixtures.h
Coverage: 4 of 7 in-scope changed file(s) opened by the reviewer; not opened: src/ssl_certman.c, tests/api.c, tests/api/test_certman.c

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

@wolfSSL-Fenrir-bot
wolfSSL-Fenrir-bot dismissed their stale review November 13, 2026 18:57

Fenrir's latest completed scan found no issues; clearing the prior automated change request.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The comment in src/crl.c incorrectly implies that a fresh CRL-only-key CRL can cover an expired own-key CRL despite an AKID mismatch, and needs to describe the verified-CRL and shared-trust-anchor requirements.

1 open issue
2 resolved since last review

Review effort: Balanced

Comment thread src/crl.c Resolved
@aidankeefe2022
aidankeefe2022 requested review from wolfSSL-Fenrir-bot and a balanced review from Copilot November 13, 2026 21:47
@aidankeefe2022
aidankeefe2022 marked this pull request as ready for review November 13, 2026 21:47
@github-actions

Copy link
Copy Markdown

retest this please

@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .text +320 B (+0.0%, 804,676 B / 1,048,576 B, total: 77% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .text +320 B (+0.1%, 344,744 B / 1,048,576 B, total: 33% used)

zephyr-frdm_rw612

  • FLASH: datas +16 B, log_const_area -8 B, rodata +28 B, text +11,728 B (+4.2%, 294,228 B / 67,108,864 B, total: 0% used)
  • RAM: bss +49 B, datas +16 B (+0.1%, 58,423 B / 983,040 B, total: 6% used)

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The HAVE_CRL and NO_SKID configuration fails to compile or link because it calls the unavailable GetCAByName function instead of GetCA.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread src/ssl_certman.c Resolved

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #12116

Scan targets checked: wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): tests/api/include.am, tests/api/test_certman.h, tests/api/test_certman_crl_fixtures.h
Coverage: 5 of 6 in-scope changed file(s) opened by the reviewer; not opened: tests/api/test_certman.c

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

CRL replacement can retain superseded revocations, while certificate-cache round-trips omit metadata needed to recognize same-anchor CRLs, causing erroneous CRL_MISSING failures.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment thread src/crl.c Resolved
Comment thread src/crl.c
Comment on lines +1063 to +1066
/* Remove the current entry which was replaced */
CRL_Entry_free(curr, crl->heap);

break;
@aidankeefe2022 aidankeefe2022 changed the title Match certs with appropriate CRL Crl Processing Changes: Allow for multiple CRLs per issuer and allow more paths to revoke certs Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants