Java X509 certificate parsing and verification


Driss Amri

I'm trying to handle X509 certificates in several steps and have run into two issues. I'm new to JCE so I'm not fully up to date yet.

We want to be able to parse several different X509 certificates based on different encodings (PEM, DER and PCKS7). I have exported the same certificate (certificate including chain) in PEM and PCKS7 format using FireFox from https://belgium.be . I put a few lines that the question doesn't need

public List<X509Certificate> parse(FileInputStream fis) {  
    /*
     * Generate a X509 Certificate initialized with the data read from the inputstream. 
     * NOTE: Generation fails when using BufferedInputStream on PKCS7 certificates.
     */
    List<X509Certificate> certificates = null;
      log.debug("Parsing new certificate.");
      certificates = (List<X509Certificate>) cf.generateCertificates(fis);
    return certificates;
  }

This code works fine as long as I use FileInputStream instead of PCKS7's BufferedInputStream, I think it's weird already? But I can live with it.

The next step is to verify these certificate chains. 1) Check if all certificates have an expiry date (easy) 2) Verify the certificate chain using OCSP (fallback to CRL if OCSP URL is not found in certificate). This is where I'm not sure how to go about it.

I'm using Sun JCE, but there doesn't seem to be much documentation available (in examples)?

I first made a simple implementation that just checks the chain without OCSP/CRL checking.

private Boolean validateChain(List<X509Certificate> certificates) {
    PKIXParameters params;
    CertPath certPath;
    CertPathValidator certPathValidator;
    Boolean valid = Boolean.FALSE;

    params = new PKIXParameters(keyStore);
    params.setRevocationEnabled(false);

    certPath = cf.generateCertPath(certificates);
    certPathValidator = CertPathValidator.getInstance("PKIX");

    PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)  
    certPathValidator.validate(certPath, params);

      if(null != result) {
        valid = Boolean.TRUE;
      }
    return valid;
 }

This works fine for my PEM certificate but not for PCKS7 certificate (same certificate, only exported in other format). java.security.cert.CertPathValidatorException: Path is not linked with any trust anchor.

The only difference I can see is that the CertPaths are not formed in the same order? I can't figure out what's wrong, so I'm leaving for now and moving on to the PEM certificate, but let's call this problem 1 ;)

After that what I want to achieve is OCSP check. Apparently if I enable OCSP with: Security.setProperty("ocsp.enable", "true"); and set params.setRevocationEnabled(true); it should be able to find the OCSP URL by itself, but it doesn't. What should the standard implementation do (question 2)? java.security.cert.CertPathValidatorException: The location of the OCSP responder must be specified

Going beyond this, I found a way to retrieve the OCSP URL from the certificate using AuthorityInfoAccessExtension etc.

But after manually setting the OCSP url in the ocsp.url property, I get java.security.cert.CertPathValidatorException: OCSP response error: Unauthorized

It seems like I'm missing many necessary steps, and many online references say that setting the ocsp.enable property should be all you need?

Maybe none of you guides can guide me through this process? tell me i'm totally wrong :)

The next step will be to perform a CRL check, if OCSP is not found, if anyone can point me to any examples or show me some documentation, that would also be greatly appreciated!

Thanks!

EDIT: Since it's not self-selecting properties by itself, I've been trying to set all properties myself using:

    // Activate OCSP
        Security.setProperty("ocsp.enable", "true");
        // Activate CRLDP -- no idea what this is
        Security.setProperty("com.sun.security.enableCRLDP", "true");

        X509Certificate target = (X509Certificate) certPath.getCertificates().get(0);
        Security.setProperty("ocsp.responderURL","http://ocsp.pki.belgium.be/");
        Security.setProperty("ocsp.responderCertIssuerName", target.getIssuerX500Principal().getName());
        Security.setProperty("ocsp.responderCertSubjectName", target.getSubjectX500Principal().getName());
        Security.setProperty("ocsp.responderCertSerialNumber", target.getSerialNumber().toString(16));

An exception occurred: java.security.cert.CertPathValidatorException: The responder's certificate (set with the OCSP security attribute) could not be found.

Driss Amri

For future reference, I'll post the answer to my own question (partially at least)

OCSP and CRL checks are already implemented in the standard Java implementation and do not require custom code or other providers (BC, ..). They are disabled by default.

To do this, you must set at least two parameters:

(PKIXParameters or PKIXParameterBuilder) params.setRevocationEnabled(true);
Security.setProperty("ocsp.enable", "true");

This activates the OCSP check when you try to validate the certificate path (PKIXCertPathValidatorResult.validate()).

If you want to add a fallback check for CRL when no OCSP is available, add additional properties:

System.setProperty("com.sun.security.enableCRLDP", "true");

A lot of problems happened since I had to support different certificate formats (PKCS7, PEM). My implementation works fine for PEM, but it's a little harder since PKCS7 doesn't preserve the order of certificates in the chain ( http://bugs.sun.com/view_bug.do?bug_id=6238093 )

X509CertSelector targetConstraints = new X509CertSelector();

targetConstraints.setCertificate(certificates.get(0));
// Here's the issue for PKCS7 certificates since they are not ordered,
// but I havent figured out how I can see what the target certificate
// (lowest level) is in the incoming certificates..

PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, targetConstraints);   

Hope this is useful to others too, maybe someone can shed some light on how to find the target certificate in the unordered PKCS7 list?

Related


Java X509 certificate parsing and verification

Driss Amri I'm trying to handle X509 certificates in several steps and have run into two issues. I'm new to JCE so I'm not fully up to date yet. We want to be able to parse several different X509 certificates based on different encodings (PEM, DER and PCKS7).

Java X509 certificate parsing and verification

Driss Amri I'm trying to handle X509 certificates in several steps and have run into two issues. I'm new to JCE so I'm not fully up to date yet. We want to be able to parse several different X509 certificates based on different encodings (PEM, DER and PCKS7).

Java Security - X509 certificate verification with public key

wrong person I'm doing so many security operations in a project. I've never had a security issue before. So my question can be beginner level. In my problem I am getting a byte array data which contains a certificate and some other parameters. I need to verify

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 =

How to skip (X509) certificate verification in Gocloak?

dexter dexter : I am trying to authenticate my token from keycloak using gocloak and for that I put the following code. token:="" client:= gocloak.NewClient("https://example.com") _, err := client.RetrospectToken(token,"client-id" ,"client-secret", "realm") lo

How to skip (X509) certificate verification in Gocloak?

dexter dexter I am trying to authenticate my token from keycloak using gocloak and for that I put the following code. token:="" client:= gocloak.NewClient("https://example.com") _, err := client.RetrospectToken(token,"client-id" ,"client-secret", "realm") log.

How to skip (X509) certificate verification in Gocloak?

dexter dexter I am trying to authenticate my token from keycloak using gocloak and for that I put the following code. token:="" client:= gocloak.NewClient("https://example.com") _, err := client.RetrospectToken(token,"client-id" ,"client-secret", "realm") log.

Generate X509 certificate using Bouncy Castle Java

Reddy: I am looking for an example or tutorial for generating X509 certificates using BC in Java. Many examples have/use deprecated APIs. I looked at BC but it doesn't show which class is doing what or doesn't have proper documentation/examples. If you have an

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

Create X509 certificate in Java without BouncyCastle?

Yuliy: Is it possible to reasonably create an X509 certificate in Java code without using the Bouncy Castle X509V*CertificateGeneratorclasses ? Erickson: The ability to sign certificates is not part of the standard Java library or extension. Much of the code y

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

Convert RSAP public key to X509 certificate (Java)

spy Q: Is it possible to read an RSA key pair from a Java keystore so that the public key subject identity can be captured from the public key? I have generated RSA with SHA1 2048 bit key using Java Keytool and stored the key pair in a JKS file. I can load the

Write x509 certificate to PEM formatted string in Java?

Pizza Hut: Is there any advanced way to write an X509 certificate into a PEM formatted string? Currently, I'm doing x509cert.encode() to write it to a DER formatted string, then base 64 encoding it, appending the header and footer to create the PEM string, but

Generate X509 certificate using Bouncy Castle Java

Reddy: I am looking for an example or tutorial for generating X509 certificates using BC in Java. Many examples have/use deprecated APIs. I looked at BC but it doesn't show which class is doing what or doesn't have proper documentation/examples. If you have an

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 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

X509 Certificate Sharing Standard (java servlet)

Jada I'm trying to develop a simple web service using servlets and Apache Tomcat, where client and server exchange their public keys; this is to send some signed data during a further communication phase. I read on the internet that the best way to share publi

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

Convert RSAP public key to X509 certificate (Java)

spy Q: Is it possible to read an RSA key pair from a Java keystore so that the public key subject identity can be captured from the public key? I have generated RSA with SHA1 2048 bit key using Java Keytool and stored the key pair in a JKS file. I can load the

Convert RSAP public key to X509 certificate (Java)

spy Q: Is it possible to read an RSA key pair from a Java keystore so that the public key subject identity can be captured from the public key? I have generated RSA with SHA1 2048 bit key using Java Keytool and stored the key pair in a JKS file. I can load the

Generate X509 certificate with BouncyCastle using Java

Suresh Atta This is my ability to generate digital certificates now. Now I can generate a digital certificate whose password is protected by the private key. public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastlePro

Generate X509 certificate with BouncyCastle using Java

Suresh Atta This is my ability to generate digital certificates now. Now I can generate a digital certificate whose password is protected by the private key. public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastlePro

Write x509 certificate to PEM formatted string in Java?

Pizza Hut: Is there any advanced way to write an X509 certificate into a PEM formatted string? Currently, I'm doing x509cert.encode() to write it to a DER formatted string, then base 64 encoding it, appending the header and footer to create the PEM string, but

Generate X509 certificate using Bouncy Castle Java

Reddy: I am looking for an example or tutorial for generating X509 certificates using BC in Java. Many examples have/use deprecated APIs. I looked at BC but it doesn't show which class is doing what or doesn't have proper documentation/examples. If you have an

Create X509 certificate in Java without BouncyCastle?

Yuliy: Is it possible to reasonably create an X509 certificate in Java code without using the Bouncy Castle X509V*CertificateGeneratorclasses ? Erickson: The ability to sign certificates is not part of the standard Java library or extension. Much of the code y

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