Public key parameter digestParamSet should be optional for GOST 34.10 R 2012
Environment
- Bouncy Castle build on commit
9279d29588e52d8f0260c2ce5e730c773c247569 - Modules used:
- bcpkix;
- bcprov;
- bcutils.
- OpenJDK Runtime Environment (build 17+35-2724)
Description
-
When generating a certificate using the GOST 34.10 R 2012 algorithm with a key length of 256 and parameters
id-tc26-gost-3410-2012-256-paramSetBvia Bouncy Castle we have two parameters in theparametersfield of theSubjectPublicKeyInfostructure:-
publicKeyParamSet: 1.2.643.7.1.2.1.1.2 equal toid-tc26-gost-3410-12-256-paramSetB; -
digestParamSet: 1.2.643.7.1.1.2.2 equal toid-tc26-gost3411-12-256.
-
-
On verifying a CMS GOST 34.10 R 2012 signature with only one parameter
publicKeyParamSetequal toid-tc26-gost-3410-12-256-paramSetBin theparametersfield of the certificate'sSubjectPublicKeyInfoArrayIndexOutOfBoundsException exception is thrown as Bouncy Castle ALWAYS expects at least two parameters to be present:publicKeyParamSetanddigestParamSet.Stacktrace:
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1 at org.bouncycastle.asn1.ASN1Sequence.getObjectAt(ASN1Sequence.java:269) at org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters.<init>(GOST3410PublicKeyAlgParameters.java:64) at org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters.getInstance(GOST3410PublicKeyAlgParameters.java:35) at org.bouncycastle.jcajce.provider.asymmetric.ecgost12.BCECGOST3410_2012PublicKey.populateFromPubKeyInfo(BCECGOST3410_2012PublicKey.java:220) at org.bouncycastle.jcajce.provider.asymmetric.ecgost12.BCECGOST3410_2012PublicKey.<init>(BCECGOST3410_2012PublicKey.java:183) at org.bouncycastle.jcajce.provider.asymmetric.ecgost12.KeyFactorySpi.generatePublic(KeyFactorySpi.java:159) at org.bouncycastle.jce.provider.BouncyCastleProvider.getPublicKey(BouncyCastleProvider.java:530) at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateImpl.getPublicKey(X509CertificateImpl.java:450) at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject.getPublicKey(X509CertificateObject.java:96) at org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder$1.get(JcaContentVerifierProviderBuilder.java:101) at org.bouncycastle.cms.SignerInformationVerifier.getContentVerifier(SignerInformationVerifier.java:43) at org.bouncycastle.cms.SignerInformation.doVerify(SignerInformation.java:364) at org.bouncycastle.cms.SignerInformation.verify(SignerInformation.java:659) at org.example.CmsSignVerifyDetachedGOSTR3410_2012_256.verifyDetached(CmsSignVerifyDetachedGOSTR3410_2012_256.java:98) at org.example.CmsSignVerifyDetachedGOSTR3410_2012_256.main(CmsSignVerifyDetachedGOSTR3410_2012_256.java:60) java.lang.RuntimeException: Detached CMS signature is invalid at org.example.CmsSignVerifyDetachedGOSTR3410_2012_256.main(CmsSignVerifyDetachedGOSTR3410_2012_256.java:63)
Class GOST3410PublicKeyAlgParameters.java requires digestParamSet parameter in it's constructors or expects that ASN1Sequence parameter must always have an object at the index 1 indicating digestParamSet.
The library's current behavior doesn't comply with RFC 9215. According to section 4.2:
The digestParamSet field:
SHOULD be omitted if the GOST R 34.10-2012 signature algorithm is used with a 512-bit key length
MUST be present and must be equal to id-tc26-digest- gost3411-12-256 if one of the following values is used as publicKeyParamSet:
id-GostR3410-2001-TestParamSet
id-GostR3410-2001-CryptoPro-A-ParamSet
id-GostR3410-2001-CryptoPro-B-ParamSet
id-GostR3410-2001-CryptoPro-C-ParamSet
id-GostR3410-2001-CryptoPro-XchA-ParamSet
id-GostR3410-2001-CryptoPro-XchB-ParamSet
SHOULD be omitted if publicKeyParamSet is equal to:
- id-tc26-gost-3410-2012-256-paramSetA
MUST be omitted if one of the following values is used as publicKeyParamSet:
id-tc26-gost-3410-2012-256-paramSetB
id-tc26-gost-3410-2012-256-paramSetC
id-tc26-gost-3410-2012-256-paramSetD
Expected behavior
The expected behavior in this case is that Bouncy Castle supports the conditions described in section 4.2 of RFC 9215:
-
Verification of CMS GOST 34.10 R 2012 signature without
digestParamSetparameter in certificate'sSubjectPublicKeyInfoshould not throw exception. -
Objects generated via Bouncy Castle using the GOST 34.10 R 2012 algorithm with a key length of 256 bits and a value
publicKeyParamSetequal to:- id-tc26-gost-3410-2012-256-paramSetB
- id-tc26-gost-3410-2012-256-paramSetC
- id-tc26-gost-3410-2012-256-paramSetD
must have only one parameter publicKeyParamSet in parameters. The digestParamSet parameter should be omitted.
Link to samples
https://drive.google.com/file/d/1Zyo8qcPF-LCBGMNEXRANgr22KGKH4NwX/view?usp=share_link
-
CmsSignVerifyDetachedGOSTR3410_2012_256sample tries to verify detached CMS signature with signer certificate created by rtpkcs11ecp library and fails with exception mentioned above -
GenerateCertificateGOSTR3410_2012_256sample generates certificate (GOST 34.10 R 2012 algorithm with a key length of 256 bits and id-tc26-gost-3410-2012-256-paramSetB) and shows SubjectPublicKeyInfo parameters including unnecessarydigestParamSet