How to get Policy Identifier and Subject Type of Basic Constraints in X509 Certificate in Java


Hussein Akajani

I have an X509Certificate in Java and I want to get the value of the X509Certificate present in the field as shown in the image below:Policy IdentifierCertificate Policies

enter image description here

Also, I want to get the value of the in field as shown in the image below:Subject TypeBasic Constraints

enter image description here

my code:

public static void main(String[] args) throws Exception {
    CertificateFactory cf = CertificateFactory.getInstance("X509");
    InputStream in = new FileInputStream(new File("E:\\myCert.crt"));
    X509Certificate cert = (X509Certificate) cf.generateCertificate(in);
    int length = cert.getCertificateExtensionOIDs().size();
    String oid;
    for(int i = 0; i < length; i++){
        oid = cert.getCertificateExtensionOIDs().iterator().next();
        byte[] UID = cert.getExtensionValue(oid);
        DERObject derObject = toDERObject(UID);
        if(derObject instanceof DEROctetString){
            DEROctetString derOctetString = (DEROctetString) derObject;
            derObject = toDERObject(derOctetString.getOctets());
        }
// here I think, I should use derObject to retrieve cert info but I don't know how!?
}
public static DERObject toDERObject(byte[] data) throws IOException {
        ByteArrayInputStream inStream = new ByteArrayInputStream(data);
        ASN1InputStream DIS = new ASN1InputStream(inStream);
        return DIS.readObject();
    }
Kerziek

Look at that code. More data validation code may be required, and you must double-check the underlying constraints, as the following conditions may not be sufficient in some cases.

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.CertificatePolicies;
import org.bouncycastle.asn1.x509.PolicyInformation;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

/**
 * 2016 krzysiek
 */
public class App {
    private static final String CERTIFICATE_POLICY_OID = "2.5.29.32";

    private static final String FILENAME = "/test.cer";

    public static void main(String[] args) {
        try {
            X509Certificate cert = loadCertificate();
            String policyIdentifier = getCertificatePolicyId(cert, 0, 0);

            System.out.println("Policy Identifier: " + policyIdentifier);

            String subjectType = getSubjectType(cert);
            System.out.println("Subject Type: " + subjectType);
        } catch (Exception e) {
            System.out.println("Problem with certificate: " + e.getMessage());
        }
    }

    private static String getSubjectType(X509Certificate cert) {
        int pathLen = cert.getBasicConstraints();
        if (pathLen == -1) {
            if (cert.getKeyUsage()[5] || cert.getKeyUsage()[6]) { //simple check, there my be needed more key usage and extended key usage verification
                return "Service";
            } else {
                return "EndEntity";
            }

        } else {
            try {
                cert.verify(cert.getPublicKey());
                return "RootCA";
            } catch (SignatureException | InvalidKeyException e) {
                return "SubCA";
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    private static X509Certificate loadCertificate() {
        try (InputStream in = new FileInputStream(App.class.getResource(FILENAME).getFile())) {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Certificate certificate = cf.generateCertificate(in);
            X509Certificate cert = (X509Certificate) certificate;

            return cert;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String getCertificatePolicyId(X509Certificate cert, int certificatePolicyPos, int policyIdentifierPos)
            throws IOException {
        byte[] extPolicyBytes = cert.getExtensionValue(CERTIFICATE_POLICY_OID);
        if (extPolicyBytes == null) {
            return null;
        }

        DEROctetString oct = (DEROctetString) (new ASN1InputStream(new ByteArrayInputStream(extPolicyBytes)).readObject());
        ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject();

        if (seq.size() <= (certificatePolicyPos)) {
            return null;
        }

        CertificatePolicies certificatePolicies = new CertificatePolicies(PolicyInformation.getInstance(seq.getObjectAt(certificatePolicyPos)));
        if (certificatePolicies.getPolicyInformation().length <= policyIdentifierPos) {
            return null;
        }

        PolicyInformation[] policyInformation = certificatePolicies.getPolicyInformation();
        return policyInformation[policyIdentifierPos].getPolicyIdentifier().getId();
    }
}

pom.xml :

<properties>
    <bouncycastle.version>1.54</bouncycastle.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>${bouncycastle.version}</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcmail-jdk15on</artifactId>
        <version>${bouncycastle.version}</version>
    </dependency>
</dependencies>

Related


How to get BasicConstraints extension from Java X509 certificate

michalk: I want to read the extension BasicConstraints for Java X509Certificate (the certificate implementation comes from the default JCE, so yes sun.security.x509.X509CertImpl). I want to get the BasicConstraint extension value to check if it's a CA: X509Cer

How to get BasicConstraints extension from Java X509 certificate

michalk: I want to read the extension BasicConstraints for Java X509Certificate (the certificate implementation comes from the default JCE, so yes sun.security.x509.X509CertImpl). I want to get the BasicConstraint extension value to check if it is a CA: X509Ce

How to get BasicConstraints extension from Java X509 certificate

michalk: I want to read the extension BasicConstraints for Java X509Certificate (the certificate implementation comes from the default JCE, so yes sun.security.x509.X509CertImpl). I want to get the BasicConstraint extension value to check if it is a CA: X509Ce

How to open X509 certificate in Java?

Jackson I am trying to open the crt certificate in Java, thereby getting some parameters from the crt. I use the following code: inStream = new FileInputStream("sbi.crt"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert =

Get trusted X509 certificate for Java SSLSocket

Jesse Wilson I can establish a TLS connection to https://google.com/ . The remote service returns a chain of 3 certificates: CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US CN=Google Internet Authority G2, O=Google Inc, C=US CN=GeoTrust G

How to get x509 certificate from http client in Go

mjb2kmn: I've gone through the documentation at https://golang.org/pkg/ but I can't make this connection. I am creating a client and requesting like this (error handling removed): client := http.Client{ CheckRedirect: func(req *http.Request, via []*http.Re

How to get x509 certificate from http client in Go

mjb2kmn: I've gone through the documentation at https://golang.org/pkg/ but I can't make this connection. I am creating a client and requesting like this (error handling removed): client := http.Client{ CheckRedirect: func(req *http.Request, via []*http.Re

How to get x509 certificate from http client in Go

mjb2kmn: I've gone through the documentation at https://golang.org/pkg/ but I can't make this connection. I am creating a client and requesting like this (error handling removed): client := http.Client{ CheckRedirect: func(req *http.Request, via []*http.Re

How to check if X509 certificate has been revoked in Java?

Mickey I googled all over the place, and asked in other communities, and I went all the way to the Oracle documentation that discusses the spec. However, the documentation covers more about the naming of the methods and the overall architecture, and doesn't ac

How to check if X509 certificate has been revoked in Java?

Mickey I googled all over the place, and asked in other communities, and I went all the way to the Oracle documentation that discusses the spec. However, the documentation covers more about the naming of the methods and the overall architecture, and doesn't ac

How to check if X509 certificate has been revoked in Java?

Mickey I googled all over the place, and asked in other communities, and I went all the way to the Oracle documentation that discusses the spec. However, the documentation covers more about the naming of the methods and the overall architecture, and doesn't ac

How to extract X509 certificate fields in Java

Facing FTW I'm currently working on an application that will handle some fields of an X509 certificate, but can't seem to figure out how to extract some parts of the certificate for debugging purposes. So far I have only been able to figure out how to read the