1

I'm trying to extract the signer's X509CertificateObject from a CMSSignedData object using java Bouncy Castle 1.47. So far I have only been able to extract an org.bouncycastle.asn1.x509.Certificate object. How do I get a X509CertificateObject from this? Thanks a lot!

public static X509CertificateObject extractSignersCert(CMSSignedData cmsSignedData)
    throws Exception
{
    SignerInformationStore signerInfoStore;
    SignerInformation signerInfo;
    Store certStore;
    Collection certCollection;
    X509CertificateHolder x509CertHolder;
    X509Certificate cert;
    X509CertificateObject certObj;
    JcaX509CertificateConverter certConverter;

    signerInfoStore = cmsSignedData.getSignerInfos();
    signerInfo = (SignerInformation) signerInfoStore.getSigners().iterator().next();

    certStore = cmsSignedData.getCertificates();
    certCollection = certStore.getMatches(signerInfo.getSID());
    x509CertHolder = (X509CertificateHolder) certCollection.iterator().next();

    certConverter = new JcaX509CertificateConverter();
    certConverter.setProvider("BC");

    cert = certConverter.getCertificate(x509CertHolder);
    certObj = (X509CertificateObject) cert;

    return certObj;
}
Thomas Lieven
  • 371
  • 4
  • 14
  • Try the [`X509CertificateObject` class's constructor](http://www.bouncycastle.org/docs/docs1.4/org/bouncycastle/jce/provider/X509CertificateObject.html#constructor_detail) it should take an `X509CertificateStructure` object (which, given your code sample) your `cert` variable holds. – Kohányi Róbert Nov 28 '12 at 13:35
  • Thats what I initially had in mind, too. Unfortunately this practically appears to be not viable c.f. changed demo code. Having a look at the class relations you will see that cert is not, or at least no longer, a subclass of X509CertificateStructure. – Thomas Lieven Nov 29 '12 at 08:47
  • I've checked the `sources.jar` and `javadoc.jar` attached to the [this Bouncy Castle Maven artifact](http://search.maven.org/#artifactdetails|org.bouncycastle|bcprov-jdk15on|1.46|jar). To me it seems the constructor is defined. I didn't run your code as of yet, but could check and post the *exact* Bouncy Castle version you use? – Kohányi Róbert Nov 29 '12 at 10:56
  • I'm using the latest BC Jars from http://www.bouncycastle.org/latest_releases.html, i.e. bcprov-jdk15on-147.jar, my JDK is 1.7 – Thomas Lieven Nov 29 '12 at 13:40
  • Class X509CertificateObject defines a constructor X509CertificateObject(X509CertificateStructure c) in BC 1.47. (Unfortunately) org.bouncycastle.asn1.x509.Certificate only has org.bouncycastle.asn1.ASN1Object as a common ancestor with X509CertificateStructure – Thomas Lieven Nov 29 '12 at 13:44
  • In general I'm not fixed to any class in between at all. I just start with a CMSSignedData object and want to retrieve the signer's certififcate as X509Certificate or X509CertificateObject. – Thomas Lieven Nov 29 '12 at 13:48
  • Your example has an invalid syntax. You didn't declare `certStruct` in your code you just use it. [Please read this](http://sscce.org/) and improve your answer. If you update your example code then please include your import declarations too. Thanks. – Kohányi Róbert Nov 29 '12 at 16:06
  • Of course what I've wanted to write was improve your *question*, not your answer. – Kohányi Róbert Nov 29 '12 at 16:33

2 Answers2

0

Finally found a solution based on this post. The trick is to use a JcaX509CertificateConverter() and feed it with the X509CertificateHolder you can easily get from the CMSSignedData. Works just fine.

Community
  • 1
  • 1
Thomas Lieven
  • 371
  • 4
  • 14
0

You can use this method.

/**
 * Get all x509 certificates from p7s File(.p7s or .p7b) Base64 format
 * @param p7sFileName
 * @return list of x509 certificates
 */
public static ArrayList<X509Certificate> getCertificates(final String p7sFileName){

    final ArrayList<X509Certificate> certListResult = new ArrayList<X509Certificate>();

    try {

        BufferedReader br = new BufferedReader(new FileReader(p7sFileName));
        StringBuilder str = new StringBuilder();
        br.readLine();
        while(br.ready()){

            String s = br.readLine();
            if(s.startsWith("-----END PKCS7-----"))
                break;
            else str.append(s);

        }

        byte[] data = Base64.decode(str.toString().getBytes());

        CMSSignedData s = new CMSSignedData(data);
        Store   certStore = s.getCertificates();

        JcaX509CertificateConverter converter = new JcaX509CertificateConverter();

        @SuppressWarnings("unchecked")
        ArrayList<X509CertificateHolder> certificateHolders = (ArrayList<X509CertificateHolder>)certStore.getMatches(null); 

        for(X509CertificateHolder holder: certificateHolders){

                X509Certificate cert = converter.getCertificate(holder);
                certListResult.add(cert);

            }

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CMSException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CertificateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return certListResult;

}
partlov
  • 13,789
  • 6
  • 63
  • 82
Hung
  • 1
  • 1