Search code examples
javacryptographycertificatebouncycastlepki

Generate p7b certificate chain with bouncycastle in Java


I need to generate p7b certificate chain using bouncy castle 1.58.

In the older version we used(1.46), this code worked:

        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        Certificate [] chain = certificate.getCertificateChain();
        CertStore certStore;
        try {
            certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Arrays.asList(chain)));
            gen.addCertificatesAndCRLs(certStore);

            CMSSignedData signedData = gen.generate(null,(Provider)null);
            return signedData.getEncoded();
        } catch (Exception ex) {
            logger.error("Failed to construct P7B response",ex);
            throw new RuntimeException(ex);
        }

However, there are some changes of the CMSSignedDataGenerator with the new version of Bouncy Castle, so I modified my code like this:

        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        Certificate [] chain = certificate.getCertificateChain();
        try {
            JcaCertStore store = new JcaCertStore(Arrays.asList(chain));
            gen.addCertificates(store);

            CMSSignedData signedData = gen.generate(null);
            return signedData.getEncoded();
        } catch (Exception ex) {
            logger.error("Failed to construct P7B response",ex);
            throw new RuntimeException(ex);
        } 

However, I get a null pointer exception on this line inside the generate:

CMSSignedData signedData = gen.generate(null);

I tried to debug and I checked that the certificates are loaded to JcaCertStore, so that part is ok.

However, when I try to debug bouncy castle library the debugger can't seem to find line numbers of the CMSSignedDataGenerator class.

I'm using Wildfly to deploy my project and I've attached the jar with sources to the debugger, however I see the code but right next to class name I get line not available, so I'm not able to see where the null pointer exception occurs.

enter image description here

What's also interesting is that I see a hollow Java icon on that class: enter image description here


Solution

  • I solved the issue using the following code:

            CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
            Certificate [] chain = certificate.getCertificateChain();
            try {
                CMSProcessableByteArray msg = new CMSProcessableByteArray("".getBytes());
                JcaCertStore store = new JcaCertStore(Arrays.asList(chain));
                gen.addCertificates(store);
                CMSSignedData signedData = gen.generate(msg);
                return signedData.getEncoded();
            } catch (Exception ex) {
                logger.error("Failed to construct P7B response",ex);
                throw new RuntimeException(ex);
            } 
    

    However, I see this as a kind of a hack as you use CMSSignedDataGenerator which is meant for signing to generate the p7b certificate chain.

    In the older version you could use null as data that is signed, but now you must input some data, even if it is just an empty byte array.