Example usage for org.bouncycastle.asn1.x509 GeneralName GeneralName

List of usage examples for org.bouncycastle.asn1.x509 GeneralName GeneralName

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x509 GeneralName GeneralName.

Prototype

public GeneralName(int tag, String name) 

Source Link

Document

Create a GeneralName for the given tag from the passed in String.

Usage

From source file:org.cesecore.certificates.certificate.certextensions.standard.NameConstraint.java

License:Open Source License

/**
 * Converts a list of encoded strings of Name Constraints into ASN1 GeneralSubtree objects.
 * This is needed when creating an BouncyCastle ASN1 NameConstraint object for inclusion
 * in a certificate.//from  www . j  a  v a  2 s.co m
 */
public static GeneralSubtree[] toGeneralSubtrees(List<String> list) {
    if (list == null) {
        return new GeneralSubtree[0];
    }

    GeneralSubtree[] ret = new GeneralSubtree[list.size()];
    int i = 0;
    for (String entry : list) {
        int type = getNameConstraintType(entry);
        Object data = getNameConstraintData(entry);
        GeneralName genname;
        switch (type) {
        case GeneralName.dNSName:
        case GeneralName.rfc822Name:
            genname = new GeneralName(type, (String) data);
            break;
        case GeneralName.directoryName:
            genname = new GeneralName(new X500Name(CeSecoreNameStyle.INSTANCE, (String) data));
            break;
        case GeneralName.iPAddress:
            genname = new GeneralName(type, new DEROctetString((byte[]) data));
            break;
        default:
            throw new UnsupportedOperationException(
                    "Encoding of name constraint type " + type + " is not implemented.");
        }
        ret[i++] = new GeneralSubtree(genname);
    }
    return ret;
}

From source file:org.cesecore.util.CertTools.java

License:Open Source License

/**
 * From an altName string as defined in getSubjectAlternativeName
 * /* ww  w.  jav a  2  s . co m*/
 * @param altName
 * @return ASN.1 GeneralNames
 * @see #getSubjectAlternativeName
 */
public static GeneralNames getGeneralNamesFromAltName(final String altName) {
    if (log.isTraceEnabled()) {
        log.trace(">getGeneralNamesFromAltName: " + altName);
    }
    final ASN1EncodableVector vec = new ASN1EncodableVector();

    for (final String email : CertTools.getEmailFromDN(altName)) {
        vec.add(new GeneralName(1, /*new DERIA5String(iter.next())*/email));
    }

    for (final String dns : CertTools.getPartsFromDN(altName, CertTools.DNS)) {
        vec.add(new GeneralName(2, new DERIA5String(dns)));
    }

    final String directoryName = getDirectoryStringFromAltName(altName);
    if (directoryName != null) {
        //final X500Name x500DirectoryName = new X500Name(directoryName);
        final X500Name x500DirectoryName = new X500Name(LDAPDN.unescapeRDN(directoryName));
        final GeneralName gn = new GeneralName(4, x500DirectoryName);
        vec.add(gn);
    }

    for (final String uri : CertTools.getPartsFromDN(altName, CertTools.URI)) {
        vec.add(new GeneralName(6, new DERIA5String(uri)));
    }
    for (final String uri : CertTools.getPartsFromDN(altName, CertTools.URI1)) {
        vec.add(new GeneralName(6, new DERIA5String(uri)));
    }
    for (final String uri : CertTools.getPartsFromDN(altName, CertTools.URI2)) {
        vec.add(new GeneralName(6, new DERIA5String(uri)));
    }

    for (final String addr : CertTools.getPartsFromDN(altName, CertTools.IPADDR)) {
        final byte[] ipoctets = StringTools.ipStringToOctets(addr);
        if (ipoctets.length > 0) {
            final GeneralName gn = new GeneralName(7, new DEROctetString(ipoctets));
            vec.add(gn);
        } else {
            log.error("Cannot parse/encode ip address, ignoring: " + addr);
        }
    }

    // UPN is an OtherName see method getUpn... for asn.1 definition
    for (final String upn : CertTools.getPartsFromDN(altName, CertTools.UPN)) {
        final ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(new ASN1ObjectIdentifier(CertTools.UPN_OBJECTID));
        v.add(new DERTaggedObject(true, 0, new DERUTF8String(upn)));
        vec.add(GeneralName.getInstance(new DERTaggedObject(false, 0, new DERSequence(v))));
    }

    // PermanentIdentifier is an OtherName see method getPermananentIdentifier... for asn.1 definition
    for (final String permanentIdentifier : CertTools.getPartsFromDN(altName, CertTools.PERMANENTIDENTIFIER)) {
        final String[] values = getPermanentIdentifierValues(permanentIdentifier);
        final ASN1EncodableVector v = new ASN1EncodableVector(); // this is the OtherName
        v.add(new ASN1ObjectIdentifier(CertTools.PERMANENTIDENTIFIER_OBJECTID));
        // First the PermanentIdentifier sequence
        final ASN1EncodableVector piSeq = new ASN1EncodableVector();
        if (values[0] != null) {
            piSeq.add(new DERUTF8String(values[0]));
        }
        if (values[1] != null) {
            piSeq.add(new ASN1ObjectIdentifier(values[1]));
        }
        v.add(new DERTaggedObject(true, 0, new DERSequence(piSeq)));
        // GeneralName gn = new GeneralName(new DERSequence(v), 0);
        final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v));
        vec.add(gn);
    }

    for (final String guid : CertTools.getPartsFromDN(altName, CertTools.GUID)) {
        final ASN1EncodableVector v = new ASN1EncodableVector();
        byte[] guidbytes = Hex.decode(guid);
        if (guidbytes != null) {
            v.add(new ASN1ObjectIdentifier(CertTools.GUID_OBJECTID));
            v.add(new DERTaggedObject(true, 0, new DEROctetString(guidbytes)));
            final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v));
            vec.add(gn);
        } else {
            log.error("Cannot decode hexadecimal guid, ignoring: " + guid);
        }
    }

    // Krb5PrincipalName is an OtherName, see method getKrb5Principal...for ASN.1 definition
    for (final String principalString : CertTools.getPartsFromDN(altName, CertTools.KRB5PRINCIPAL)) {
        // Start by parsing the input string to separate it in different parts
        if (log.isDebugEnabled()) {
            log.debug("principalString: " + principalString);
        }
        // The realm is the last part moving back until an @
        final int index = principalString.lastIndexOf('@');
        String realm = "";
        if (index > 0) {
            realm = principalString.substring(index + 1);
        }
        if (log.isDebugEnabled()) {
            log.debug("realm: " + realm);
        }
        // Now we can have several principals separated by /
        final ArrayList<String> principalarr = new ArrayList<String>();
        int jndex = 0;
        int bindex = 0;
        while (jndex < index) {
            // Loop and add all strings separated by /
            jndex = principalString.indexOf('/', bindex);
            if (jndex == -1) {
                jndex = index;
            }
            String s = principalString.substring(bindex, jndex);
            if (log.isDebugEnabled()) {
                log.debug("adding principal name: " + s);
            }
            principalarr.add(s);
            bindex = jndex + 1;
        }

        // Now we must construct the rather complex asn.1...
        final ASN1EncodableVector v = new ASN1EncodableVector(); // this is the OtherName
        v.add(new ASN1ObjectIdentifier(CertTools.KRB5PRINCIPAL_OBJECTID));

        // First the Krb5PrincipalName sequence
        final ASN1EncodableVector krb5p = new ASN1EncodableVector();
        // The realm is the first tagged GeneralString
        krb5p.add(new DERTaggedObject(true, 0, new DERGeneralString(realm)));
        // Second is the sequence of principal names, which is at tagged position 1 in the krb5p
        final ASN1EncodableVector principals = new ASN1EncodableVector();
        // According to rfc4210 the type NT-UNKNOWN is 0, and according to some other rfc this type should be used...
        principals.add(new DERTaggedObject(true, 0, new ASN1Integer(0)));
        // The names themselves are yet another sequence
        final Iterator<String> i = principalarr.iterator();
        final ASN1EncodableVector names = new ASN1EncodableVector();
        while (i.hasNext()) {
            String principalName = (String) i.next();
            names.add(new DERGeneralString(principalName));
        }
        principals.add(new DERTaggedObject(true, 1, new DERSequence(names)));
        krb5p.add(new DERTaggedObject(true, 1, new DERSequence(principals)));

        v.add(new DERTaggedObject(true, 0, new DERSequence(krb5p)));
        final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v));
        vec.add(gn);
    }

    // To support custom OIDs in altNames, they must be added as an OtherName of plain type UTF8String
    for (final String oid : CertTools.getCustomOids(altName)) {
        for (final String oidValue : CertTools.getPartsFromDN(altName, oid)) {
            final ASN1EncodableVector v = new ASN1EncodableVector();
            v.add(new ASN1ObjectIdentifier(oid));
            v.add(new DERTaggedObject(true, 0, new DERUTF8String(oidValue)));
            final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v));
            vec.add(gn);
        }
    }

    if (vec.size() > 0) {
        return GeneralNames.getInstance(new DERSequence(vec));
    }
    return null;
}

From source file:org.cesecore.util.CertToolsTest.java

License:Open Source License

/**
 * Tests the following methods:/*from  w w  w  .j av  a  2s. c  o  m*/
 * <ul>
 * <li>{@link CertTools.checkNameConstraints}</li>
 * <li>{@link NameConstraint.parseNameConstraintsList}</li>
 * <li>{@link NameConstraint.toGeneralSubtrees}</li>
 * </ul>
 */
@Test
public void testNameConstraints() throws Exception {
    final String permitted = "C=SE,CN=example.com\n" + "example.com\n" + "@mail.example\n" + "user@host.com\n"
            + "10.0.0.0/8\n" + "   C=SE,  CN=spacing    \n";
    final String excluded = "forbidden.example.com\n" + "postmaster@mail.example\n" + "10.1.0.0/16\n" + "::/0"; // IPv6

    final List<Extension> extensions = new ArrayList<Extension>();
    GeneralSubtree[] permittedSubtrees = NameConstraint
            .toGeneralSubtrees(NameConstraint.parseNameConstraintsList(permitted));
    GeneralSubtree[] excludedSubtrees = NameConstraint
            .toGeneralSubtrees(NameConstraint.parseNameConstraintsList(excluded));
    byte[] extdata = new NameConstraints(permittedSubtrees, excludedSubtrees).toASN1Primitive().getEncoded();
    extensions.add(new Extension(Extension.nameConstraints, false, extdata));

    final KeyPair testkeys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
    X509Certificate cacert = CertTools.genSelfCertForPurpose("C=SE,CN=Test Name Constraints CA", 365, null,
            testkeys.getPrivate(), testkeys.getPublic(), AlgorithmConstants.SIGALG_SHA1_WITH_RSA, true,
            X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign, null, null, "BC", true, extensions);

    // Allowed subject DNs
    final X500Name validDN = new X500Name("C=SE,CN=example.com"); // re-used below
    CertTools.checkNameConstraints(cacert, validDN, null);
    CertTools.checkNameConstraints(cacert, new X500Name("C=SE,CN=spacing"), null);

    // Allowed subject alternative names
    CertTools.checkNameConstraints(cacert, validDN,
            new GeneralNames(new GeneralName(GeneralName.dNSName, "example.com")));
    CertTools.checkNameConstraints(cacert, validDN,
            new GeneralNames(new GeneralName(GeneralName.dNSName, "x.sub.example.com")));
    CertTools.checkNameConstraints(cacert, validDN,
            new GeneralNames(new GeneralName(GeneralName.rfc822Name, "someuser@mail.example")));
    CertTools.checkNameConstraints(cacert, validDN,
            new GeneralNames(new GeneralName(GeneralName.rfc822Name, "user@host.com")));
    CertTools.checkNameConstraints(cacert, validDN, new GeneralNames(new GeneralName(GeneralName.iPAddress,
            new DEROctetString(InetAddress.getByName("10.0.0.1").getAddress()))));
    CertTools.checkNameConstraints(cacert, validDN, new GeneralNames(new GeneralName(GeneralName.iPAddress,
            new DEROctetString(InetAddress.getByName("10.255.255.255").getAddress()))));

    // Disallowed subject DN
    checkNCException(cacert, new X500Name("C=DK,CN=example.com"), null,
            "Disallowed DN (wrong field value) was accepted");
    checkNCException(cacert, new X500Name("C=SE,O=Company,CN=example.com"), null,
            "Disallowed DN (extra field) was accepted");

    // Disallowed SAN
    // The commented out lines are allowed by BouncyCastle but disallowed by the RFC
    checkNCException(cacert, validDN, new GeneralName(GeneralName.dNSName, "bad.com"),
            "Disallowed SAN (wrong DNS name) was accepted");
    checkNCException(cacert, validDN, new GeneralName(GeneralName.dNSName, "forbidden.example.com"),
            "Disallowed SAN (excluded DNS subdomain) was accepted");
    checkNCException(cacert, validDN, new GeneralName(GeneralName.rfc822Name, "wronguser@host.com"),
            "Disallowed SAN (wrong e-mail) was accepted");
    checkNCException(cacert, validDN,
            new GeneralName(GeneralName.iPAddress,
                    new DEROctetString(InetAddress.getByName("10.1.0.1").getAddress())),
            "Disallowed SAN (excluded IPv4 address) was accepted");
    checkNCException(cacert, validDN,
            new GeneralName(GeneralName.iPAddress,
                    new DEROctetString(InetAddress.getByName("192.0.2.1").getAddress())),
            "Disallowed SAN (wrong IPv4 address) was accepted");
    checkNCException(cacert, validDN,
            new GeneralName(GeneralName.iPAddress,
                    new DEROctetString(InetAddress.getByName("2001:DB8::").getAddress())),
            "Disallowed SAN (IPv6 address) was accepted");
}

From source file:org.codice.ddf.security.certificate.generator.CertificateCommandTest.java

License:Open Source License

/**
 * Expected SAN general name is now a function of the CN, since a SAN representing the CN is now
 * required./*from   w ww. j  a  v  a  2 s .  c om*/
 */
private static byte[] expectedSanGeneralName(String alias, boolean withAdditionalSans) {
    try {
        GeneralNamesBuilder builder = new GeneralNamesBuilder()
                .addName(new GeneralName(GeneralName.dNSName, alias));
        if (withAdditionalSans) {
            builder.addName(new GeneralName(GeneralName.iPAddress, IP_FROM_SAN))
                    .addName(new GeneralName(GeneralName.dNSName, DNS_FROM_SAN));
        }
        return builder.build().getEncoded(ASN1Encoding.DER);
    } catch (IOException e) {
        throw new IllegalStateException(e);
    }
}

From source file:org.codice.ddf.security.certificate.generator.CertificateSigningRequestTest.java

License:Open Source License

@Test
public void testAddSubjectAlternativeNames() {
    assertThat("CSR should not have any SAN by default", csr.getSubjectAlternativeNames(),
            emptyCollectionOf(GeneralName.class));
    csr.addSubjectAlternativeNames("IP:1.2.3.4", "DNS:A");
    assertThat(csr.getSubjectAlternativeNames(), contains(new GeneralName(GeneralName.iPAddress, "1.2.3.4"),
            new GeneralName(GeneralName.dNSName, "A")));
    csr.addSubjectAlternativeNames("RID:0.2.1.4", "DNS:A");
    assertThat(csr.getSubjectAlternativeNames(), contains(new GeneralName(GeneralName.iPAddress, "1.2.3.4"),
            new GeneralName(GeneralName.dNSName, "A"), new GeneralName(GeneralName.registeredID, "0.2.1.4")));
}

From source file:org.codice.ddf.security.certificate.generator.CertificateSigningRequestTest.java

License:Open Source License

@Test
public void testNewCertificateBuilderWithSan() throws Exception {
    final DateTime start = DateTime.now().minusDays(1);
    final DateTime end = start.plusYears(100);
    final KeyPair kp = makeKeyPair();

    csr.setSerialNumber(1);//  w  w w .  ja va  2 s . com
    csr.setNotBefore(start);
    csr.setNotAfter(end);
    csr.setCommonName("A");
    csr.setSubjectKeyPair(kp);
    csr.addSubjectAlternativeNames("IP:1.2.3.4", "DNS:A");
    final X509Certificate issuerCert = mock(X509Certificate.class);

    doReturn(new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US")).when(issuerCert)
            .getSubjectX500Principal();
    final JcaX509v3CertificateBuilder builder = csr.newCertificateBuilder(issuerCert);
    final X509CertificateHolder holder = builder.build(new DemoCertificateAuthority().getContentSigner());

    assertThat(holder.getSerialNumber(), equalTo(BigInteger.ONE));
    assertThat(holder.getNotBefore(), equalTo(new Time(start.toDate()).getDate()));
    assertThat(holder.getNotAfter(), equalTo(new Time(end.toDate()).getDate()));
    assertThat(holder.getSubject().toString(), equalTo("cn=A"));
    assertThat("Unable to validate public key", holder.getSubjectPublicKeyInfo(),
            equalTo(SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded())));
    final org.bouncycastle.asn1.x509.Extension csn = holder
            .getExtension(org.bouncycastle.asn1.x509.Extension.subjectAlternativeName);

    assertThat(csn.getParsedValue().toASN1Primitive().getEncoded(ASN1Encoding.DER),
            equalTo(new GeneralNamesBuilder().addName(new GeneralName(GeneralName.iPAddress, "1.2.3.4"))
                    .addName(new GeneralName(GeneralName.dNSName, "A")).build().getEncoded(ASN1Encoding.DER)));
}

From source file:org.cryptable.pki.communication.PKICMPMessagesTest.java

License:Open Source License

/**
 * Check the extensions in the certification request
 *
 * @throws OperatorCreationException//w  w  w  .j  ava 2s. c om
 * @throws PKICMPMessageException
 * @throws CertificateEncodingException
 * @throws IOException
 * @throws CRMFException
 * @throws CMPException
 * @throws CMSException
 */
@Test
public void testCertificationWithExtensions()
        throws OperatorCreationException, PKICMPMessageException, CertificateEncodingException, IOException,
        CRMFException, CMPException, CMSException, NoSuchFieldException, IllegalAccessException {
    String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

    KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

    List<Extension> extensionList = new ArrayList<Extension>();
    // KeyUsage
    extensionList.add(new Extension(X509Extension.keyUsage, true,
            new KeyUsage(KeyUsage.digitalSignature | KeyUsage.nonRepudiation).getEncoded()));
    // Extended keyUsage
    List<KeyPurposeId> keyPurposeIds = new ArrayList<KeyPurposeId>();
    keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_clientAuth));
    keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_emailProtection));
    extensionList.add(new Extension(X509Extension.extendedKeyUsage, false,
            new ExtendedKeyUsage(keyPurposeIds.toArray(new KeyPurposeId[keyPurposeIds.size()])).getEncoded()));
    // Subject alternative names
    List<GeneralName> generalNames = new ArrayList<GeneralName>();
    generalNames.add(new GeneralName(GeneralName.dNSName, "www1.cryptable.org"));
    generalNames.add(new GeneralName(GeneralName.dNSName, "www2.cryptable.org"));
    GeneralNames subjectAlternativeName = new GeneralNames(
            generalNames.toArray(new GeneralName[generalNames.size()]));
    extensionList.add(
            new Extension(X509Extension.subjectAlternativeName, false, subjectAlternativeName.getEncoded()));

    PKICMPMessages pkiMessages = new PKICMPMessages();
    pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
    pkiMessages.setExtensions(extensionList.toArray(new Extension[extensionList.size()]));
    byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

    ASN1InputStream asn1InputStream = new ASN1InputStream(result);
    ASN1Primitive asn1Primitive = asn1InputStream.readObject();
    PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

    CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
            .toCertReqMsgArray();
    // KeyUsage
    KeyUsage verifyKeyUsage = KeyUsage.getInstance(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions()
            .getExtensionParsedValue(Extension.keyUsage));
    Assert.assertEquals(KeyUsage.digitalSignature | KeyUsage.nonRepudiation,
            verifyKeyUsage.getBytes()[0] & 0xFF);
    // Extended KeyUsage
    ExtendedKeyUsage verifyExtendedKeyUsage = ExtendedKeyUsage
            .fromExtensions(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions());
    Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_clientAuth));
    Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection));
    // Subject Alternative Name
    GeneralNames verifyGeneralNames = GeneralNames.fromExtensions(
            certReqMsgs[0].getCertReq().getCertTemplate().getExtensions(), Extension.subjectAlternativeName);
    Assert.assertTrue(generalNames.contains(verifyGeneralNames.getNames()[0]));
    Assert.assertTrue(generalNames.contains(verifyGeneralNames.getNames()[1]));
}

From source file:org.cryptacular.x509.ExtensionReaderTest.java

License:Open Source License

private GeneralName uri(final String uri) {
    return new GeneralName(GeneralName.uniformResourceIdentifier, uri);
}

From source file:org.cryptacular.x509.ExtensionReaderTest.java

License:Open Source License

private GeneralName dirName(final String dn) {
    return new GeneralName(GeneralName.directoryName, dn);
}

From source file:org.deviceconnect.android.ssl.CertificateAuthority.java

License:MIT License

/**
 * ???? Subject Alternative Names (SANs) ??.
 *
 * @param request ???/*from   www  .  j a  va  2  s .  c  o m*/
 * @return SubjectAlternativeNames? {@link GeneralNames} 
 * @throws IOException ?????
 */
private GeneralNames parseSANs(final PKCS10CertificationRequest request) throws IOException {
    List<ASN1Encodable> generalNames = new ArrayList<>();

    CertificationRequestInfo info = request.getCertificationRequestInfo();
    ASN1Set attributes = info.getAttributes();
    for (int i = 0; i < attributes.size(); i++) {
        DEREncodable extensionRequestObj = attributes.getObjectAt(i);
        if (!(extensionRequestObj instanceof DERSequence)) {
            continue;
        }
        DERSequence extensionRequest = (DERSequence) extensionRequestObj;
        if (extensionRequest.size() != 2) {
            continue;
        }
        DEREncodable idObj = extensionRequest.getObjectAt(0);
        DEREncodable contentObj = extensionRequest.getObjectAt(1);
        if (!(idObj instanceof ASN1ObjectIdentifier && contentObj instanceof DERSet)) {
            continue;
        }
        ASN1ObjectIdentifier id = (ASN1ObjectIdentifier) idObj;
        DERSet content = (DERSet) contentObj;
        if (!id.getId().equals("1.2.840.113549.1.9.14")) {
            continue;
        }
        if (content.size() < 1) {
            continue;
        }
        DEREncodable extensionsObj = content.getObjectAt(0);
        if (!(extensionsObj instanceof DERSequence)) {
            continue;
        }
        DERSequence extensions = (DERSequence) extensionsObj;

        for (int k = 0; k < extensions.size(); k++) {
            DEREncodable extensionObj = extensions.getObjectAt(k);
            if (!(extensionObj instanceof DERSequence)) {
                continue;
            }
            DERSequence extension = (DERSequence) extensionObj;
            if (extension.size() != 2) {
                continue;
            }
            DEREncodable extensionIdObj = extension.getObjectAt(0);
            DEREncodable extensionContentObj = extension.getObjectAt(1);
            if (!(extensionIdObj instanceof ASN1ObjectIdentifier)) {
                continue;
            }
            ASN1ObjectIdentifier extensionId = (ASN1ObjectIdentifier) extensionIdObj;
            if (extensionId.getId().equals("2.5.29.17")) {
                DEROctetString san = (DEROctetString) extensionContentObj;

                ASN1StreamParser sanParser = new ASN1StreamParser(san.parser().getOctetStream());
                DEREncodable namesObj = sanParser.readObject().getDERObject();
                if (namesObj instanceof DERSequence) {
                    DERSequence names = (DERSequence) namesObj;
                    for (int m = 0; m < names.size(); m++) {
                        DEREncodable nameObj = names.getObjectAt(m);
                        if (nameObj instanceof DERTaggedObject) {
                            DERTaggedObject name = (DERTaggedObject) nameObj;
                            switch (name.getTagNo()) {
                            case GeneralName.dNSName:
                                generalNames.add(new GeneralName(GeneralName.dNSName,
                                        DERIA5String.getInstance(name, false)));
                                break;
                            case GeneralName.iPAddress:
                                generalNames.add(new GeneralName(GeneralName.iPAddress,
                                        DEROctetString.getInstance(name, true)));
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    if (generalNames.size() > 0) {
        return new GeneralNames(new DERSequence(generalNames.toArray(new ASN1Encodable[generalNames.size()])));
    }
    return null;
}