user3624390
user3624390

Reputation: 134

Validating a leaf certificate from a third party in java 8

I am looking for a way to validate a java.security.cert.X509Certificate object that is sent from a third party. The certificate provider is using dns or ldap to fetch the certificate. I have included a link with additional information on how the certificate is being retrieved.

http://wiki.directproject.org/w/images/2/24/Certificate_Discovery_for_Direct_Project_Implementation_Guide_v4.1.pdf

I also need to know protocols and default ports that would be used in any of the verification steps. The certificate needs to meet the following criteria from page 13 section 4 of this document:

http://wiki.directproject.org/w/images/e/e6/Applicability_Statement_for_Secure_Health_Transport_v1.2.pdf

  1. Has not expired.
  2. Has a valid signature with a valid message digest
  3. Has not been revoked
  4. Binding to the expected entity
  5. Has a trusted certificate path

Item 1 is straight forward to compare the dates from the getNotAfter and getNotBefore methods on the certificate object to the current date or to use the checkValidity method which throws a checked exception.

For item #2, I see a method to get the signature, but I am unsure how to generate the message digest and verify that the signature and message digest are both valid.

For item #3, The certification revocation list seems to be mixed with some other data by calling this method on the certificate getExtensionValue("2.5.29.31"). Retrieving the certification revocation list data seems possible over http, and ocsp seems to be based on http. I haven't been able to find how to do this in java.

For item #4, I am not sure what binding means in the context of certificates, or what is involved in verifying it.

For item #5, It looks like the data for intermediary certificates is mixed with some other data by calling this method on the certificate getExtensionValue("1.3.6.1.5.5.7.1.1"). CertPathValidator looks like it may be able to help verify this information once the certificates data is retrieved over http.

Upvotes: 3

Views: 1286

Answers (2)

pedrofb
pedrofb

Reputation: 39241

Certificate validation is a complex task. You can perform all the validations you need manually (expiration, revocation, certification chain) using native Java 8 support or Bouncycastle. But the option that I would recommend is to use a specific library that has already taken into account all the possibilities.

Take a look to DSS documentation and Certificate Verification example

    // Trusted certificates sources, root and intermediates (#5 )
    CertificateSource trustedCertSource = null;
    CertificateSource adjunctCertSource = null;


    // The certificate to be validated
    CertificateToken token = DSSUtils.loadCertificate(new File("src/main/resources/keystore/ec.europa.eu.1.cer"));

    // Creates a CertificateVerifier using Online sources. It checks the revocation status with the CRL lists URLs or OCSP server extracted from the certificate #3
    CertificateVerifier cv = new CommonCertificateVerifier();
    cv.setAdjunctCertSource(adjunctCertSource);     
    cv.setTrustedCertSource(trustedCertSource);

    // Creates an instance of the CertificateValidator with the certificate
    CertificateValidator validator = CertificateValidator.fromCertificate(token);
    validator.setCertificateVerifier(cv);

    // We execute the validation (#1, #2, #3, #5)
    CertificateReports certificateReports = validator.validate();

    //The final result. You have also a detailedReport and DiagnosticData
    SimpleCertificateReport simpleReport = certificateReports.getSimpleReport();

The validation will perform all the steps you indicate, including expiration, signing of the certificate, revocation, and checking the chain of trust (including the download of intermediate certificates).

Step # 4 I don't know exactly what you mean. I suppose to validate that the certificate corresponds to one of the certification entities of the trusted list

To load the trusted certificate sources see this

CertificatePool certPool = new CertificatePool();
CommonCertificateSource ccc = new CommonCertificateSource(certPool);
CertificateToken cert = DSSUtils.loadCertificate(new File("root_ca.cer"));
CertificateToken adddedCert = ccc.addCertificate(cert);

Upvotes: 1

Ramachandran.A.G
Ramachandran.A.G

Reputation: 4948

I will split the answer to 3 pieces. The first is the background , the second is the choice of library , implementation code (references that i had used for my implementation with due credit)

In the past i had implemented a very similar use case. I had IOT fabrications done by a vendor and to onboard them i had implement the same X509 verification process that you have mentioned.

Implementation : For my implementation i had refered the following . You can include BC as your defaultProvider (Security.setProvider) and use the following code . The code directly solves 1,3,5. The code is here : https://nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/

Now coming to 2 , the answer to that depends on how you will get the certificate from your client and what additional data will be provided by the application. The high level flow of that is as follows a) Client produces the certificate b) Client does a Digest using some algorithm that is acceptable. SHA256 are quite popular, you can increase the strength based on the needs and how much compute you have. Once the client creates the digest , to prove he is the owner of the certificate you can get the digest signed using the private key of the device. This can be then transmitted to the verifier application c) Once you have the certificate and the signature , you can then use the Certificate and Public key associated with it to verify the signature applying the same digest and then verifying the signature.A good reference is here : http://www.java2s.com/Code/Java/Security/SignatureSignAndVerify.htm

I am not a 100% sure on what 4 means. But if it means proof of identity (who is producing the certificate is bound to be who they are , signing and verifying will provide the same)

Though you can realize the use cases using java security API's , I used bouncycastle core API for realizing the use cases. Bouncycastle API's are far more rich and battle tested especially for weird EC curve algorithms we had to use & you will find that many folks swear by BouncyCastle.

Hope this helps!

Upvotes: 1

Related Questions