CVE-2026-59641 Overview
CVE-2026-59641 affects Bouncy Castle for Java, a widely deployed cryptographic library. The SignedMailValidator class in the S/MIME module trusts the signer-asserted signingTime attribute when performing certificate path validation. Because the CMS signingTime attribute is chosen by the signer and is not authenticated absent a trusted timestamp, attackers can back-date a signature to a moment before key expiry or revocation. The validator would then evaluate certificate expiry and revocation at that attacker-chosen instant, accepting a signature that should have been rejected. This flaw is classified as insufficient verification of data authenticity [CWE-345].
Critical Impact
Attackers can produce S/MIME signatures that validate successfully using expired or revoked certificates by asserting a favorable signingTime, undermining the integrity guarantees of signed email.
Affected Products
- Bouncy Castle for Java before 1.85
- Bouncy Castle for Java LTS before 2.73.12
- Bouncy Castle for Java FIPS (BC-FJA): bcmail-fips and bcjmail-fips before 1.0.7 (1.0.X), 2.0.7 (2.0.X), and 2.1.7 (2.1.X)
Discovery Timeline
- 2026-08-03 - CVE-2026-59641 published to NVD
- 2026-08-04 - Last updated in NVD database
Technical Details for CVE-2026-59641
Vulnerability Analysis
The defect lives in mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidator.java. When callers invoke the validator with PKIXParameters, the class copies those parameters and overrides the validation date with the signer-supplied CMS signingTime attribute. Certificate path validation, including expiry checks and Certificate Revocation List (CRL) evaluation, is then performed at that signer-chosen instant.
Because signingTime is an unauthenticated attribute unless a trusted timestamp authority countersigns it, an attacker in possession of a compromised or expired private key can forge a signature and assert an earlier date. The validator accepts the signature as if the certificate were still valid, defeating revocation as a control.
The impact is on integrity of signed messages rather than confidentiality or availability, which is consistent with the vector components indicating integrity impact only.
Root Cause
The root cause is misplaced trust in unauthenticated signer-controlled metadata. SignedMailValidator treated the CMS signingTime attribute as authoritative for path validation without requiring a trusted timestamp token or allowing callers to override it. Any caller who did not explicitly set a validation date via PKIXParameters.setDate() was subject to the signer-chosen instant.
Attack Vector
An attacker who obtains a private key after certificate expiry, revocation, or key compromise crafts a CMS/SMIME signed message and sets the signingTime attribute to a date preceding the revocation or expiry. The message is delivered to a recipient whose application relies on Bouncy Castle's SignedMailValidator. Validation succeeds, giving the recipient false assurance of authenticity and non-repudiation.
* <code>param</code> are used for the certificate path validation. The actual
* {@link PKIXParameters} used for the certificate path validation are a copy of <code>param</code>
* with the following changes:<br>
- * - The validation date is changed to the signature time.<br>
+ * - If <code>param</code> has no validation date set, the validation date is changed to the
+ * signature time (the CMS signingTime attribute, or the current time if none is present).<br>
* - A CertStore with certificates and CRLs from the mail message is added to the CertStores.<br>
* <br>
* In <code>param</code> it's also possible to add additional CertStores with intermediate
* certificates and/or CRLs which then are also used for the validation.
+ * <br>
+ * <b>Security note:</b> the CMS signingTime attribute is asserted by the signer and, absent a
+ * trusted timestamp, is not authenticated. Using it as the validation date means certificate
+ * expiry and revocation are evaluated at a signer-chosen instant, so a signature back-dated to
+ * before a key's revocation or expiry would otherwise be accepted. A caller that requires a
+ * trusted validation instant should set it explicitly via {@link PKIXParameters#setDate}; a
+ * date set on <code>param</code> takes precedence over the signing time.
Source: Bouncy Castle patch commit 2f81b22. The patch documents the risk and makes a caller-supplied validation date take precedence over the signer-asserted signingTime.
Detection Methods for CVE-2026-59641
Indicators of Compromise
- S/MIME messages whose CMS signingTime attribute precedes the revocation or notAfter date of the signing certificate.
- Signed messages that validate under Bouncy Castle but fail validation under a strict verifier that uses current time.
- Repeated inbound signed mail from a sender whose certificate is listed in a current CRL or Online Certificate Status Protocol (OCSP) response as revoked.
Detection Strategies
- Inventory Java applications and mail gateways that ship Bouncy Castle and identify versions below 1.85, LTS below 2.73.12, or FIPS releases below the fixed 1.0.7, 2.0.7, and 2.1.7 builds.
- Re-verify archived signed messages using current time as the validation instant and flag any signature that was previously accepted but now fails on certificate status.
- Compare CMS signingTime against server-side receipt timestamps and alert on large negative skew.
Monitoring Recommendations
- Log the validation date, certificate serial, and CRL status for every S/MIME verification and forward events to a central log platform for retrospective analysis.
- Alert on validations that succeed against certificates present in current CRL or OCSP revocation feeds.
- Track dependency manifests (Maven, Gradle) in continuous integration for bcmail, bcjmail, bcmail-fips, and bcjmail-fips versions.
How to Mitigate CVE-2026-59641
Immediate Actions Required
- Upgrade to Bouncy Castle for Java 1.85, LTS 2.73.12, or the corresponding FIPS releases 1.0.7, 2.0.7, or 2.1.7.
- Until upgrades are deployed, set an explicit validation date on PKIXParameters via PKIXParameters.setDate() before calling SignedMailValidator.
- Re-validate any recently accepted S/MIME messages against current revocation data and current time.
Patch Information
The fix is delivered in commits 2f81b22 and fd89fe9 to the bc-java repository. After the patch, a caller-supplied date on PKIXParameters takes precedence over the CMS signingTime attribute. Additional detail is available in the Bouncy Castle CVE-2026-59641 wiki entry.
Workarounds
- Wrap calls to SignedMailValidator so that PKIXParameters.setDate(new Date()) is always invoked with the current time before validation.
- Require a trusted timestamp token (RFC 3161) alongside the CMS signingTime attribute and reject messages that lack one.
- Enforce CRL and OCSP checking with fresh revocation data at verification time, independent of the signer-asserted date.
# Maven dependency pin example - update to fixed versions
mvn versions:use-dep-version -Dincludes=org.bouncycastle:bcmail-jdk18on -DdepVersion=1.85 -DforceVersion=true
mvn versions:use-dep-version -Dincludes=org.bouncycastle:bcjmail-jdk18on -DdepVersion=1.85 -DforceVersion=true
# Verify no vulnerable versions remain on the classpath
mvn dependency:tree | grep -E 'bcmail|bcjmail'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

