Skip to content

Commit 85e34e2

Browse files
committed
Add the missing SQIsign and AIMer cases to PqcMalformedInputTest so that an empty or one-byte signature is covered for all five of the fixed-length PQC signature schemes rather than only MAYO, SNOVA and QR-UOV, and correct the CONTRIBUTORS.html entry that still described the AIMer length guard as bounding the signed-message envelope since removed, relates to github #2401.
1 parent d670265 commit 85e34e2

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

‎CONTRIBUTORS.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@
594594
<li>subbudvk &lt;https://github.com/subbudvk&gt; - initial author on S2K parser hardening work for OpenPGP API.</li>
595595
<li>mkarasik &lt;https://github.com/mkarasik&gt; - initial work on EST server-side key generation (RFC 7030 4.4).</li>
596596
<li>Bernd Pr&uuml;nster (A-SIT Plus) &lt;bernd.pruenster&#064;a-sit.at&gt; - reported lenient ASN.1 UTCTime/GeneralizedTime parsing accepting structurally malformed content, with fuzzing-derived test cases.</li>
597-
<li>Naveed Khan &lt;https://github.com/rootvector2&gt; - constant time comparison of membership and confirmation tags in the MLS API. Reported unbounded array allocation in the BKS/UBER keystore load path (OutOfMemoryError DoS from a crafted keystore) and introduction of a capped decompression limit in PGPCompressedData.getDataStream(), both with POC. Original submission creating S/MIME backing temp files with owner-only permissions (PR #2326). Rejecting empty sequences in the X.509 extension parsers whose RFC 5280 syntax is SEQUENCE SIZE (1..MAX) - CRLDistPoint, CertificatePolicies, ExtendedKeyUsage, PolicyMappings, and SubjectDirectoryAttributes (PR #2331). Hardening asn1.cms.SignerInfo decode to reject a non-INTEGER version or non-tagged unsignedAttrs via getInstance rather than leaking a ClassCastException (PR #2342). Fixing an off-by-4 header-length guard in the OpenPGP NotationData signature subpacket parser (PR #2346). Rejecting CR/LF in the S/MIME streaming writer header names and values (SMIMEEnvelopedWriter/SMIMESignedWriter withHeader) to prevent MIME header injection (PR #2348). Adding minimum-length guards to the SM2 decrypt and GOST28147/DSTU7624/DESede/RC2 key-wrap unwrap paths (PR #2359). Guarding the ECDH session-key length in the JCE OpenPGP decryptor (PR #2383). Fixing the identity fast-path type guards in the OER getInstance factories and the transposed isInstance arguments in OEROptional.getObject (PR #2373). Requiring the signed-message envelope handed to AIMerSigner.verifySignature to be exactly the message plus the parameter set's signature size (PR #2401).</li>
597+
<li>Naveed Khan &lt;https://github.com/rootvector2&gt; - constant time comparison of membership and confirmation tags in the MLS API. Reported unbounded array allocation in the BKS/UBER keystore load path (OutOfMemoryError DoS from a crafted keystore) and introduction of a capped decompression limit in PGPCompressedData.getDataStream(), both with POC. Original submission creating S/MIME backing temp files with owner-only permissions (PR #2326). Rejecting empty sequences in the X.509 extension parsers whose RFC 5280 syntax is SEQUENCE SIZE (1..MAX) - CRLDistPoint, CertificatePolicies, ExtendedKeyUsage, PolicyMappings, and SubjectDirectoryAttributes (PR #2331). Hardening asn1.cms.SignerInfo decode to reject a non-INTEGER version or non-tagged unsignedAttrs via getInstance rather than leaking a ClassCastException (PR #2342). Fixing an off-by-4 header-length guard in the OpenPGP NotationData signature subpacket parser (PR #2346). Rejecting CR/LF in the S/MIME streaming writer header names and values (SMIMEEnvelopedWriter/SMIMESignedWriter withHeader) to prevent MIME header injection (PR #2348). Adding minimum-length guards to the SM2 decrypt and GOST28147/DSTU7624/DESede/RC2 key-wrap unwrap paths (PR #2359). Guarding the ECDH session-key length in the JCE OpenPGP decryptor (PR #2383). Fixing the identity fast-path type guards in the OER getInstance factories and the transposed isInstance arguments in OEROptional.getObject (PR #2373). Requiring the signature handed to AIMerSigner.verifySignature to be exactly the parameter set's signature size (PR #2401).</li>
598598
<li>suraj0208 &lt;https://github.com/suraj0208&gt; - initial work on auto-detecting private key reader (JcaPrivateKeyReader).</li>
599599
<li>liamgilligan &lt;https://github.com/liamgilligan&gt; - noticing the BIP-340 step numbering in the BIP340Signer signing comments was incorrect (PR #2340).</li>
600600
<li>digi-scrypt &lt;https://github.com/digi-scrypt&gt; - disabling DTD and external-entity resolution in KMIPInputStream to close an XXE (local file disclosure / SSRF) exposure in KMIP XML parsing (PR #2315).</li>

‎core/src/test/java/org/bouncycastle/pqc/crypto/test/PqcMalformedInputTest.java‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import junit.framework.TestCase;
66
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
77
import org.bouncycastle.crypto.digests.SHA256Digest;
8+
import org.bouncycastle.pqc.crypto.aimer.AIMerParameters;
9+
import org.bouncycastle.pqc.crypto.aimer.AIMerPublicKeyParameters;
10+
import org.bouncycastle.pqc.crypto.aimer.AIMerSigner;
811
import org.bouncycastle.pqc.crypto.falcon.FalconParameters;
912
import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters;
1013
import org.bouncycastle.pqc.crypto.falcon.FalconSigner;
@@ -47,6 +50,7 @@
4750
import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPublicKeyParameters;
4851
import org.bouncycastle.pqc.crypto.sqisign.SQIsignParameters;
4952
import org.bouncycastle.pqc.crypto.sqisign.SQIsignPublicKeyParameters;
53+
import org.bouncycastle.pqc.crypto.sqisign.SQIsignSigner;
5054
import org.bouncycastle.pqc.crypto.xmss.XMSSKeyGenerationParameters;
5155
import org.bouncycastle.pqc.crypto.xmss.XMSSKeyPairGenerator;
5256
import org.bouncycastle.pqc.crypto.xmss.XMSSMTKeyGenerationParameters;
@@ -69,7 +73,10 @@ public class PqcMalformedInputTest
6973
{
7074
private static final byte[] MESSAGE = new byte[]{ 0x01, 0x02, 0x03, 0x04 };
7175

72-
// #15: verifySignature must return false (not throw) on an empty or one-byte signature.
76+
// #15: verifySignature must return false (not throw) on an empty or one-byte
77+
// signature. The trailing-bytes half of the same rule - a valid signature with
78+
// data appended must not verify either - needs a genuine signature to bite and
79+
// so lives in PqcSignatureEncodingTest, not here.
7380
public void testMalformedSignatureReturnsFalse()
7481
throws Exception
7582
{
@@ -102,6 +109,21 @@ public void testMalformedSignatureReturnsFalse()
102109
assertFalse(qruov.verifySignature(MESSAGE, new byte[0]));
103110
assertFalse(qruov.verifySignature(MESSAGE, new byte[1]));
104111

112+
// SQIsign (fixed-size signature).
113+
SQIsignParameters sqisignParams = SQIsignParameters.sqisign_lvl1;
114+
SQIsignSigner sqisign = new SQIsignSigner();
115+
sqisign.init(false, new SQIsignPublicKeyParameters(sqisignParams, new byte[sqisignParams.getPublicKeyLength()]));
116+
assertFalse(sqisign.verifySignature(MESSAGE, new byte[0]));
117+
assertFalse(sqisign.verifySignature(MESSAGE, new byte[1]));
118+
119+
// AIMer (fixed-size signature, read at a fixed offset - a short buffer used
120+
// to be indexed past its end rather than reported, github #2401).
121+
AIMerParameters aimerParams = AIMerParameters.aimer128f;
122+
AIMerSigner aimer = new AIMerSigner();
123+
aimer.init(false, new AIMerPublicKeyParameters(aimerParams, new byte[aimerParams.getPublicKeyBytes()]));
124+
assertFalse(aimer.verifySignature(MESSAGE, new byte[0]));
125+
assertFalse(aimer.verifySignature(MESSAGE, new byte[1]));
126+
105127
// XMSS (stateful, parse must not throw out of verify).
106128
XMSSKeyPairGenerator xmssGen = new XMSSKeyPairGenerator();
107129
xmssGen.init(new XMSSKeyGenerationParameters(new XMSSParameters(4, new SHA256Digest()), new SecureRandom()));

0 commit comments

Comments
 (0)