Jack
Jack

Reputation: 335

BouncyCastle - signature algorithm in TBS cert not same as outer cert

I'm trying validate the certificate path and signature using bouncy castle APIs.

And i'm getting the following exception. I have verified that the signature algorithm 'SHA256WithRSAEncryption' is same in my certificates and the issuer certificate.

Any help would be much appreciated.

Exception in thread "main" org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature.
    at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertA(Unknown Source)
    at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown Source)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:250)


Caused by: java.security.cert.CertificateException: signature algorithm in TBS cert not same as outer cert
    at org.bouncycastle.jce.provider.X509CertificateObject.checkSignature(Unknown Source)
    at org.bouncycastle.jce.provider.X509CertificateObject.verify(Unknown Source)
    at org.bouncycastle.jce.provider.CertPathValidatorUtilities.verifyX509Certificate(Unknown Source)
    ... 6 more

signing:

public byte[] sign(byte[] data) throws GeneralSecurityException, CMSException, IOException {

          CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
          generator.addSigner(pk, (X509Certificate) cert,
              CMSSignedDataGenerator.DIGEST_SHA1); //Also tried DIGEST_SHA256
          generator.addCertificatesAndCRLs(getCertStore());
          CMSProcessable content = new CMSProcessableByteArray(data);

          CMSSignedData signedData = generator.generate(content, true, "BC");
          return signedData.getEncoded();
        }

Verification :

CollectionCertStoreParameters params = new CollectionCertStoreParameters(list);
        CertStore store = CertStore.getInstance("Collection", params, "BC");
        //create certificate path
        CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC");
        List<X509Certificate> certChain = new ArrayList<X509Certificate>();
        //Create the certificate chain
        for( int i = 0; i < list.size(); i++)
            certChain.add(list.get(i));
        //Create the chain of certificates
        CertPath certPath = fact.generateCertPath(certChain);

        Set<TrustAnchor>      trust = Collections.singleton(new TrustAnchor(rootX509cert, null));
        //Get the certificate path validator
        CertPathValidator validator = CertPathValidator.getInstance("PKIX", "BC");
        PKIXParameters param = new PKIXParameters(trust);
        param.setRevocationEnabled(false);
        param.addCertStore(store);
        param.setDate(new Date());
        param.addCertPathChecker(new PathChecker());

        //Validate the certificate path
        validator.validate(certPath, param);

Upvotes: 0

Views: 1135

Answers (1)

MatK
MatK

Reputation: 96

I am not sure this is a problem of your CMS structure or your cert path validation. I think one of your certificates is erroneous.

The exception states that in a X509Certificate (my guess is your signer certificate or in its chain) the value of Certificate signatureAlgorithm is not the same as TBSCertificate signature.

See https://www.rfc-editor.org/rfc/rfc5280#section-4.1:

Certificate  ::=  SEQUENCE  {
    tbsCertificate       TBSCertificate,
    signatureAlgorithm   AlgorithmIdentifier, <--
    signatureValue       BIT STRING  }



TBSCertificate  ::=  SEQUENCE  {
    version         [0]  EXPLICIT Version DEFAULT v1,
    serialNumber         CertificateSerialNumber,
    signature            AlgorithmIdentifier, <--
    issuer               Name,
    ...
   

Upvotes: 1

Related Questions