Search code examples
javasslcertificatex509certificatebouncycastle

How to get a certificate type from its file?


I have a X509Certificate and I want to programmatically determine its type (Extended Validation (EV SSL), Organization Validated (OV SSL) or Domain Validated (DV SSL)).

I read my certificate using BouncyCastle cryptoAPI. For example, this is how I read it from file and get issuer and subject common name (CN):

...
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream input = new FileInputStream(certfile);                                  
X509Certificate cert = (X509Certificate)cf.generateCertificate(input);
X500Name x500name = new JcaX509CertificateHolder(cert).getSubject();
X500Name issuer = new JcaX509CertificateHolder(cert).getIssuer();
...

How could I get the type of a given certificate in my program?


Solution

  • I'm using BouncyCastle 1.57. If you're using a version < 1.47, the code might be different because in 1.47 they made significant changes in the API (although the idea is the same).

    To check if the certificate is DV or OV, you can check the Certificate Policies extension, as explained in this answer and in GlobalSign's website:

    Type                     Policy Identifier
    
    Domain Validated         2.23.140.1.2.1
    Organization Validated   2.23.140.1.2.2
    

    Having these identifiers takes us a long way towards our goal of deterministic evaluation of certificate issuance policy — that said, not all CAs have yet adopted them.

    Note that this method is not 100% guaranteed, because it's not fully adopted by all Certificate Authorities. That being said, you can check this extension with BouncyCastle using this:

    import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    import org.bouncycastle.asn1.DLSequence;
    import org.bouncycastle.x509.extension.X509ExtensionUtil;
    
    X509Certificate cert = // get certificate
    
    byte[] value = cert.getExtensionValue("2.5.29.32");
    if (value != null) { // extension is present
        // CertificatePolicies is a sequence
        DLSequence seq = (DLSequence) X509ExtensionUtil.fromExtensionValue(value);
        for (int i = 0; i < seq.size(); i++) {
            // each element is also a sequence
            DLSequence s = (DLSequence) seq.getObjectAt(i);
            // first element is an OID
            String oid = ((ASN1ObjectIdentifier) s.getObjectAt(0)).getId();
            if ("2.23.140.1.2.1".equals(oid)) {
                // DV
            } else if ("2.23.140.1.2.2".equals(oid)) {
                // OV
            }
        }
    }