-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Hi, the BC lightweight TLS path (BcTlsRawKeyCertificate) correctly validates that the CertificateVerify signatureScheme matches the certificate's key algorithm OID, but the JCA TLS path (JcaTlsCertificate) skips this check for ML-DSA and SLH-DSA.
JCA path (JcaTlsCertificate.java:277-280) — no validation:
case SignatureScheme.mldsa44:
case SignatureScheme.mldsa65:
case SignatureScheme.mldsa87:
return crypto.createTls13Verifier("ML-DSA", null, getPubKeyMLDSA());BC lightweight path (BcTlsRawKeyCertificate.java:256-262) — validates:
case SignatureScheme.mldsa44:
case SignatureScheme.mldsa65:
case SignatureScheme.mldsa87:
{
ASN1ObjectIdentifier mlDsaAlgOid = PQCUtil.getMLDSAObjectidentifier(signatureScheme);
validateMLDSA(mlDsaAlgOid); // checks key OID matches scheme
// ...
}The same asymmetry exists for all 12 SLH-DSA schemes (lines 281-294).
This isn't exploitable — signature length differences between SLH-DSA parameter sets (e.g. 7,856 bytes for 128s vs 49,856 for 256s) and hash binding in the key parameters prevent cross-parameter forgery. But it's a RFC 8446 §4.4.3 compliance gap, and the fix is straightforward: add validateMLDSA()/validateSLHDSA() calls to JcaTlsCertificate.createVerifier() matching BcTlsRawKeyCertificate's pattern.
Looks like the validation was implemented for the BC lightweight path but missed for the JCA path when PQC TLS support was added.