CVE-2026-59639 Overview
CVE-2026-59639 is a signature verification flaw in Bouncy Castle for Java. The CMS.verifySignatures method returns true for Cryptographic Message Syntax (CMS) SignedData structures containing zero signers. Applications relying on this method as an authenticity check will accept unsigned, attacker-supplied content as valid. The issue is classified as improper verification of a cryptographic signature [CWE-347].
The flaw affects Bouncy Castle for Java before 1.85, Bouncy Castle for Java LTS before 2.73.12, and Bouncy Castle for Java FIPS (BC-FJA) bcpkix-fips versions before 1.0.12, 2.0.12, and 2.1.12.
Critical Impact
Attackers can forge CMS messages with an empty signerInfos set and have them treated as authentically signed, breaking the integrity guarantees applications depend on.
Affected Products
- Bouncy Castle for Java before 1.85
- Bouncy Castle for Java LTS before 2.73.12
- Bouncy Castle for Java FIPS (bcpkix-fips) before 1.0.12, 2.0.12, and 2.1.12
Discovery Timeline
- 2026-08-03 - CVE-2026-59639 published to NVD
- 2026-08-04 - Last updated in NVD database
Technical Details for CVE-2026-59639
Vulnerability Analysis
The vulnerability resides in the CMSSignedData.verifySignatures method within pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java. RFC 5652 permits a SignedData structure to contain an empty signerInfos SET, for example in a certificates-only distribution. The pre-patch implementation iterated over the signer collection and returned true when the loop completed without failure. An empty collection skipped the loop entirely and produced a vacuous success result.
Callers using verifySignatures as their authenticity check would accept the content as validly signed. This turns a signature verification API into a no-op for maliciously constructed degenerate messages.
Root Cause
The method conflated "no verification failure occurred" with "the message was successfully verified." There was no explicit check for the presence of at least one SignerInformation entry before returning success. This is a fail-open logic pattern in a security-critical cryptographic primitive.
Attack Vector
An attacker crafts a CMS SignedData structure containing valid encapsulated content but with an empty signerInfos SET. The message is delivered over any channel where the receiving application invokes verifySignatures to establish authenticity, such as a document signing workflow, code signing pipeline, or secure messaging endpoint. The call returns true, and the application processes the unsigned content as trusted.
{
Collection signers = this.getSignerInfos().getSigners();
+ // Fail closed on a degenerate SignedData with no SignerInfos (RFC 5652 permits an empty
+ // signerInfos SET, e.g. a certs-only structure). Falling through the loop to "return true"
+ // would report vacuous success, so a caller using this as its authenticity check would accept
+ // unsigned, attacker-supplied content. Callers expecting a certs-only structure should use
+ // getCertificates() instead.
+ if (signers.isEmpty())
+ {
+ throw new CMSException("no signers present in SignedData");
+ }
+
for (Iterator it = signers.iterator(); it.hasNext(); )
{
SignerInformation signer = (SignerInformation)it.next();
Source: Bouncy Castle patch commit 99ddc6d
The patch throws a CMSException when the signer collection is empty, forcing a fail-closed behavior consistent with the method's security contract.
Detection Methods for CVE-2026-59639
Indicators of Compromise
- CMS SignedData messages arriving at application endpoints with an empty signerInfos SET yet carrying encapsulated content intended for trusted processing.
- Application logs showing successful signature verification with no associated signer certificate or subject identity recorded.
- Java stack traces referencing pre-patch versions of org.bouncycastle.cms.CMSSignedData in signature-processing workflows.
Detection Strategies
- Inventory Java applications and dependencies for Bouncy Castle artifacts bcprov, bcpkix, and bcpkix-fips using Software Composition Analysis (SCA) or Software Bill of Materials (SBOM) tooling.
- Instrument code paths that call verifySignatures to log the count of SignerInformation entries and alert on any zero-signer message accepted as valid.
- Perform ASN.1 parsing at ingress gateways to reject CMS structures where the signerInfos field is empty before they reach application logic.
Monitoring Recommendations
- Track invocation of CMSSignedData.verifySignatures across signing and validation services and correlate results with signer identity metadata.
- Monitor build systems and dependency-management tooling for pinned Bouncy Castle versions below the fixed releases.
- Review outbound and inbound signed message flows for anomalies in signer distribution, such as sudden appearance of certs-only structures where full signatures were previously observed.
How to Mitigate CVE-2026-59639
Immediate Actions Required
- Upgrade Bouncy Castle for Java to 1.85 or later, Bouncy Castle for Java LTS to 2.73.12 or later, or bcpkix-fips to 1.0.12, 2.0.12, or 2.1.12 as appropriate for the deployed series.
- Audit all code paths that invoke CMSSignedData.verifySignatures and confirm they treat a zero-signer condition as failure.
- Rebuild and redeploy affected applications, including transitive dependencies pulled in through frameworks.
Patch Information
The fix is committed in 99ddc6dcc6782e6a76b0dd587c77e62eb7096ad0 and adds an explicit signers.isEmpty() check that throws CMSException("no signers present in SignedData"). Refer to the Bouncy Castle CVE-2026-59639 wiki entry for the full advisory and to the upstream commit for the patch source.
Workarounds
- Wrap calls to verifySignatures with application-level logic that first checks getSignerInfos().getSigners().isEmpty() and rejects such messages.
- For workflows that legitimately handle certificate-only CMS structures, switch to getCertificates() and stop using verifySignatures as the authenticity check.
- Where upgrade is delayed, filter CMS payloads at the network or message-broker boundary to drop structures lacking at least one SignerInfo entry.
# Example Maven dependency update to a fixed version
mvn versions:use-dep-version -Dincludes=org.bouncycastle:bcpkix-jdk18on -DdepVersion=1.85 -DforceVersion=true
mvn versions:use-dep-version -Dincludes=org.bouncycastle:bcprov-jdk18on -DdepVersion=1.85 -DforceVersion=true
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

