Skip to content

certs: re-sign orphaned rsapss/mldsa leaves and add chain guard#10835

Merged
Frauschi merged 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/cert
Jul 2, 2026
Merged

certs: re-sign orphaned rsapss/mldsa leaves and add chain guard#10835
Frauschi merged 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/cert

Conversation

@yosuke-wolfssl

Copy link
Copy Markdown
Contributor

certs: re-sign orphaned rsapss/mldsa leaves and add a leaf-to-CA chain guard

Problem

The tinytls13-cert-rsaverify CI config (and any PR that had picked up current
master) fails during the TLS 1.3 smoke test:

tls13_memio handshake FAILED (client err -188, server err -313)
  • client -188 = ASN_NO_SIGNER_E — no signer found for the presented cert
  • server -313 = FATAL_ERROR — received the fatal alert the client sent

Root cause

Two committed leaf certificates were signed by CAs that were later re-issued,
so each leaf's issuer no longer matches its CA's subject:

Leaf Leaf issuer Current CA subject
certs/rsapss/ecc-leaf-rsapss.pem emailAddress=info@wolfssl.com certs/rsapss/ca-rsapss.pememailAddress=facts@wolfssl.com
certs/mldsa/ecc-leaf-mldsa44.pem CN=Test mldsa44 certs/mldsa/mldsa44-cert.pemCN=ML-DSA-44

The CAs were re-issued (the facts@wolfssl.com email change, and the ML-DSA CA
CN change) without regenerating the leaves they had signed. This is a
cert/data sync issue, not a code defect, which is why it reproduced on every
open PR regardless of its content.

Fix

Regenerate both leaves against the current committed CAs (same keys, no other
cert in the tree touched):

  • certs/rsapss/ecc-leaf-rsapss.pem — re-signed by ca-rsapss.pem (RSA-PSS),
    matching certs/rsapss/renew-rsapss-certs.sh.
  • certs/mldsa/ecc-leaf-mldsa44.pem — re-signed by mldsa44-cert.pem,
    matching the ML-DSA leaf section of certs/renewcerts.sh.

Prevent recurrence

Add a guard so a future CA re-issue that skips the leaf fails loudly at PR time
instead of as a runtime handshake error buried in one config:

  • certs/check_cert_chains.sh (new) — a data-driven checker for the pinned
    leaf/CA pairs. Per pair it runs:
    1. a signature-independent identity check (leaf issuer DN == CA subject DN,
      and leaf AKID == CA SKID) that works on any OpenSSL and catches the exact
      DN-drift class that broke here;
    2. a cryptographic openssl verify when the local OpenSSL supports the CA's
      algorithm. ML-DSA verification needs OpenSSL 3.5+, so on older toolchains
      the crypto step is skipped with an explicit notice while the identity
      check still runs.
  • .github/workflows/check-cert-chains.yml (new) — a ~30s OpenSSL-only job
    (modeled on gencertbuf.yml) that runs the script on every non-draft PR.
  • certs/renewcerts.sh — calls the guard at the end of a full regen so
    drift is caught before the refreshed certs are committed.

Adding a new pinned leaf later is one line in the pairs list in
check_cert_chains.sh.

Testing

  • Positive: cd certs && ./check_cert_chains.sh → both pairs report OK,
    exit 0 (crypto-verified locally on OpenSSL 3.6.1).
  • Negative control: restoring the old orphaned ecc-leaf-rsapss.pem makes the
    guard print the info@ vs facts@ mismatch and exit 1.
  • openssl verify -partial_chain -CAfile ca-rsapss.pem ecc-leaf-rsapss.pem → OK;
    full chain via root-rsapss.pem (untrusted ca-rsapss.pem) → OK.
  • sh -n / bash -n clean on both scripts; workflow YAML parses.

Notes

  • The CI guard cryptographically verifies the RSA-PSS pair; the ML-DSA pair
    gets the identity check on stock runners (OpenSSL 3.0.x). The ML-DSA leaf is
    still fully exercised at handshake time by the existing tinytls13 / pq-all
    tests, so a capable-OpenSSL build was intentionally left out to keep the job
    lightweight.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jul 2, 2026
Copilot AI review requested due to automatic review settings July 2, 2026 01:25

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.

Pull request overview

This PR fixes TLS 1.3 handshake failures caused by committed leaf certificates no longer matching their re-issued CAs, and adds a lightweight CI guard to prevent future leaf/CA drift from landing unnoticed.

Changes:

  • Re-sign the RSA-PSS and ML-DSA leaf certificates so their issuer/AKID chain correctly matches the currently committed CA subject/SKID.
  • Add certs/check_cert_chains.sh to validate pinned leaf→CA pairs via issuer/subject + AKID/SKID identity checks, and crypto verification where OpenSSL supports the algorithm.
  • Add a GitHub Actions workflow to run the guard on non-draft PRs; run the guard at the end of certs/renewcerts.sh.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
certs/rsapss/ecc-leaf-rsapss.pem Re-signed RSA-PSS leaf to match the current RSA-PSS CA identity.
certs/mldsa/ecc-leaf-mldsa44.pem Re-signed ML-DSA leaf to match the current ML-DSA CA identity.
certs/check_cert_chains.sh New script to check pinned leaf/CA identity and (when supported) cryptographic verification.
.github/workflows/check-cert-chains.yml New CI workflow running the guard with stock OpenSSL on non-draft PRs.
certs/renewcerts.sh Runs the new guard after certificate regeneration/cleanup to catch drift before commit.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread certs/check_cert_chains.sh Outdated

@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 #10835

No scan targets match the changed files in this PR. Review skipped.

@Frauschi Frauschi merged commit 4de8190 into wolfSSL:master Jul 2, 2026
294 of 295 checks passed
@yosuke-wolfssl yosuke-wolfssl deleted the fix/cert branch July 2, 2026 23:26
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.

5 participants