Question

I am using bouncy castle 1.48 to verify certificate validation with OCSP. It works good. But I'm using Ocsp Url as static variable and I want to read it from certificate. Url is written in certificate as Authority Info Access

[1]Authority Info Access
 Access Method=On-line Certificate Status Protocol (1.3.6.1.5.5.7.48.1)
 Alternative Name:
      URL=http://ocsp.mydomain

I got org.bouncycastle.asn1.x509.AuthorityInformationAccess object from certificate

byte[] octetBytes = certificate.getExtensionValue(X509Extension.authorityInfoAccess.getId());
ASN1InputStream octetStream = new ASN1InputStream(octetBytes);
byte[] encoded = X509ExtensionUtil.fromExtensionValue(octetBytes).getEncoded();
ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(encoded));
AuthorityInformationAccess access = AuthorityInformationAccess.getInstance(seq);

which writes AuthorityInformationAccess: Oid(1.3.6.1.5.5.7.48.1) but cant get Url from there

Was it helpful?

Solution

I found the way.

private String getOcspUrl(X509Certificate certificate) throws Exception {
    byte[] octetBytes = certificate
            .getExtensionValue(X509Extension.authorityInfoAccess.getId());

    DLSequence dlSequence = null;
    ASN1Encodable asn1Encodable = null;

    try {
        ASN1Primitive fromExtensionValue = X509ExtensionUtil
                .fromExtensionValue(octetBytes);
        if (!(fromExtensionValue instanceof DLSequence))
            return null;
        dlSequence = (DLSequence) fromExtensionValue;
        for (int i = 0; i < dlSequence.size(); i++) {
            asn1Encodable = dlSequence.getObjectAt(i);
            if (asn1Encodable instanceof DLSequence)
                break;
        }
        if (!(asn1Encodable instanceof DLSequence))
            return null;
        dlSequence = (DLSequence) asn1Encodable;
        for (int i = 0; i < dlSequence.size(); i++) {
            asn1Encodable = dlSequence.getObjectAt(i);
            if (asn1Encodable instanceof DERTaggedObject)
                break;
        }
        if (!(asn1Encodable instanceof DERTaggedObject))
            return null;
        DERTaggedObject derTaggedObject = (DERTaggedObject) asn1Encodable;
        byte[] encoded = derTaggedObject.getEncoded();
        if (derTaggedObject.getTagNo() == 6) {
            int len = encoded[1];
            return new String(encoded, 2, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

OTHER TIPS

This is how I did it:

 private String getOcspUrlFromCertificate(X509Certificate cert) {
    byte[] extensionValue = cert.getExtensionValue(X509Extensions.AuthorityInfoAccess.getId());

    try {
        ASN1Sequence asn1Seq = (ASN1Sequence) X509ExtensionUtil.fromExtensionValue(extensionValue); // AuthorityInfoAccessSyntax
        Enumeration<?> objects = asn1Seq.getObjects();

        while (objects.hasMoreElements()) {
            ASN1Sequence obj = (ASN1Sequence) objects.nextElement(); // AccessDescription
            DERObjectIdentifier oid = (DERObjectIdentifier) obj.getObjectAt(0); // accessMethod
            DERTaggedObject location = (DERTaggedObject) obj.getObjectAt(1); // accessLocation

            if (location.getTagNo() == GeneralName.uniformResourceIdentifier) {
                DEROctetString uri = (DEROctetString) location.getObject();
                String str = new String(uri.getOctets());
                if (oid.equals(X509ObjectIdentifiers.id_ad_ocsp)) {
                    return str;
                }
            }
        }
    } catch (Exception e) {
        logger.error("Error", e);
    }

    return null;
}

With BouncyCastle 1.9 is:

Dependences

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.59</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.59</version>
    </dependency>

Method for get url OCSP

private ASN1Primitive getExtensionValue(X509Certificate certificate, String oid) throws IOException {
    byte[] bytes = certificate.getExtensionValue(oid);
    if (bytes == null) {
        return null;
    }
    ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
    ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
    aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
    return aIn.readObject();
}

public String getOcspUrl() throws Exception {
    ASN1Primitive obj;
    try {
        obj = getExtensionValue(getFirstCertificate(), Extension.authorityInfoAccess.getId());
    } catch (IOException ex) {
        ex.printStackTrace();
        return null;
    }

    if (obj == null) {
        return null;
    }

    AuthorityInformationAccess authorityInformationAccess = AuthorityInformationAccess.getInstance(obj);

    AccessDescription[] accessDescriptions = authorityInformationAccess.getAccessDescriptions();
    for (AccessDescription accessDescription : accessDescriptions) {
        boolean correctAccessMethod = accessDescription.getAccessMethod().equals(X509ObjectIdentifiers.ocspAccessMethod);
        if (!correctAccessMethod) {
            continue;
        }

        GeneralName name = accessDescription.getAccessLocation();
        if (name.getTagNo() != GeneralName.uniformResourceIdentifier) {
            continue;
        }

        DERIA5String derStr = DERIA5String.getInstance((ASN1TaggedObject) name.toASN1Primitive(), false);
        return derStr.getString();
    }

    return null;
}

Function to verif revocation

public CertificateStatus verifRevocationWithOCSP(X509Certificate certificate,X509Certificate issuerCertificate) throws Exception{
    OcspClientBouncyCastle ocspClient = new OcspClientBouncyCastle();
    String urlOCSP = getOcspUrl();
    BasicOCSPResp basicOCSPResp = ocspClient.getBasicOCSPResp(certificate, issuerCertificate, urlOCSP);

    if (basicOCSPResp == null)
        throw new IOException("Error en la consulta ar servidor OCSP ["+urlOCSP+"]");

    BasicOCSPResp basicResponse = basicOCSPResp;
    SingleResp[] responses = basicResponse.getResponses();
    if (responses.length == 1) {
        SingleResp resp = responses[0];
        Object status = resp.getCertStatus();
        System.out.println("OBJECT: "+status);
        if (status == CertificateStatus.GOOD) {
            return CertificateStatus.GOOD;
        } else if (status instanceof RevokedStatus) {
            RevokedStatus revokedStatus = (RevokedStatus)status;
            return revokedStatus;
        } else if(status instanceof UnknownStatus){
            UnknownStatus unknownStatus = (UnknownStatus)status;
            return unknownStatus;
        }
        throw new IOException("Tipo de respuesta de OCSP ["+status+"] desconocido");
    }
    else
        throw new IOException("No se recibio ni una respuesta al consultar el OCSP para la URL ["+urlOCSP+"]");
}

Use BouncyCastle X509CertificateHolder.

Using BouncyCastle 1.66, Java 8, and Lombok val...

public static String getOcspUrl(final String certPEM) {                                                                                                                                                                                                                                                               
    val certHolder = toCertificateHolder(certPEM);                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                        
    val aiaExtension = AuthorityInformationAccess.fromExtensions(certHolder.getExtensions());                                                                                                                                                                                                                         
    val ocspUrl = Arrays.stream(aiaExtension.getAccessDescriptions())                                                                                                                                                                                                                                                 
          .filter(ad -> ad.getAccessMethod().equals(X509ObjectIdentifiers.id_ad_ocsp))                                                                                                                                                                                                                                  
          .map(ad -> ad.getAccessLocation().getName().toASN1Primitive().toString())                                                                                                                                                                                                                                     
          .findFirst();

    return ocspUrl.get();
}

public static X509CertificateHolder toCertificateHolder(final String certPEM) {                                                                                                                                                                                                                                       
    val parser = new PEMParser(new StringReader(certPEM));                                                                                                                                                                                                                                                   
    return (X509CertificateHolder) parser.readObject();                                                                                                                                                                                                                                                               
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top