October 22, 2019

How to Read MSUPN in X509Certificate

Maven dependency


        <!-- The prov module provides all the JCA/JCE provider functionality. -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>${bouncycastle.version}</version>
        </dependency>
        <!-- The pkix module is the home for code for X.509 certificate generation 
            and the APIs for standards that rely on ASN.1 such as CMS, TSP, PKCS#12, OCSP, CRMF, 
            and CMP. -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>${bouncycastle.version}</version>
        </dependency>

The source code for The Bouncy Castle Crypto Package For Java.

The Java code


package se.magnuskkarlsson.example.bouncycastle;

import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.asn1.x509.GeneralName;

public class X509CertificateUtils {

    public static final String MSUPN_OID = "1.3.6.1.4.1.311.20.2.3";
    private final Logger log = Logger.getLogger(X509CertificateUtils.class.getName());

    public String getMSUPNFromX509Certificate(X509Certificate cert) throws CertificateParsingException {
        Collection<List<?>> sans = JcaX509ExtensionUtils.getSubjectAlternativeNames(cert);
        for (List<?> san : sans) {

            log.info("Read X509 SAN " + sans);
            int sanType = (int) san.get(0);
            if (sanType == GeneralName.otherName) {

                ASN1Sequence sanASN1Sequence = (ASN1Sequence) san.get(1);
                String msupn = getSANFromASN1Sequence(sanASN1Sequence);
                if (msupn != null) {
                    return msupn;
                }
            }
        }
        return null;
    }

    private String getSANFromASN1Sequence(ASN1Sequence sanASN1Sequence) {
        ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) sanASN1Sequence.getObjectAt(0);
        if (!MSUPN_OID.equals(oid.getId())) {
            log.warning("Invalid MSUPN OID, expected '" + MSUPN_OID + "' got '" + oid.getId() + "'.");
            return null;
        }

        ASN1TaggedObject sanASN1TaggedObject = (ASN1TaggedObject) sanASN1Sequence.getObjectAt(1);
        ASN1Primitive sanASN1Primitive = sanASN1TaggedObject.getObject();

        if (sanASN1Primitive instanceof ASN1String) {
            return ((ASN1String) sanASN1Primitive).getString();
        }
        log.warning("Invalid ASN.1 Primitive class, expected ASN1String, got " + sanASN1Primitive.getClass());
        return null;
    }

}

No comments: