21

I am trying to validate a certificate against java key store and this is the code I am using is as below. If it completes succesfully then I assume the validation has gone through correctly, else if an exception is thrown, then the validation fails. My concern is:

Is the code below sufficient to validate a certificate? As in is there something I am missing here (Like checking the data signed by the computer sending me the certificate?)? 2. Should the signature contained within the certificate be verified? If yes, how?

Thanks in advance for the response! pradeep

// To check the validity of the dates
cert.checkValidity();
//Check the chain
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> mylist = new ArrayList<X509Certificate>();          
mylist.add(cert);
CertPath cp = cf.generateCertPath(mylist);
PKIXParameters params = new PKIXParameters(getTrustStore());
params.setRevocationEnabled(false);
CertPathValidator cpv =
      CertPathValidator.getInstance(CertPathValidator.getDefaultType());
PKIXCertPathValidatorResult pkixCertPathValidatorResult =
      (PKIXCertPathValidatorResult) cpv.validate(cp, params);
insumity
  • 5,311
  • 8
  • 36
  • 64
user771870
  • 211
  • 1
  • 2
  • 3

3 Answers3

8

Normally, a certificate will be issued by an intermediate issuing authority, not a "root" authority (which is all that should be in your trust store). Most protocols encourage sending a "chain" of certificates, not just the entity's certificate.

You should add all of the intermediate certs so that a complete chain can be formed.

In order to be certain that the certificate is still valid, you should not disable revocation checks. If you don't want to retrieve a CRL (which can be large), the issuer may offer OCSP support. But, this has to be enabled in the Java runtime by setting certain system properties.

If the path validator returns successfully, you don't need to check anything else. If the certificate is not valid, an exception will be raised.

Also, an explicit check on the validity date is unnecessary. This occurs during validation (using the current time, unless you specify a time via the PKIXParameters).


For a more extensive discussion of validation, including sample code, see a previous answer of mine.

Community
  • 1
  • 1
erickson
  • 265,237
  • 58
  • 395
  • 493
  • Thanks for the response! Do you mean that I have to add all the intermediate certificates to the list of certificates (mylist.add(cert);) and then create a chain using CertPath ? Thanks! – user771870 May 26 '11 at 20:48
  • 2
    Which are the properties of java runtime we need to set to enable the revocation check for certificate. ??? – MayurB Mar 04 '15 at 05:52
4

If you're happy with the default trust settings (as they would be used for the default SSLContext), you could build an X509TrustManager independently of SSL/TLS and use if to verify your certificate independently.

It would look like this:

TrustManagerFactory trustManagerFactory =
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore)null);
// you could use a non-default KeyStore as your truststore too, instead of null.

for (TrustManager trustManager: trustManagerFactory.getTrustManagers()) {  
    if (trustManager instanceof X509TrustManager) {  
        X509TrustManager x509TrustManager = (X509TrustManager)trustManager;  
        x509TrustManager.checkServerTrusted(...);
    }  
}

(You should also check the server's identity and the certificate match, see RFC 6125 (Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)).)

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • 1
    Uh, what goes in `...`? – Paul Draper May 11 '16 at 22:19
  • 1
    @PaulDraper first parameter is the array of X509Certificate, second parameter is the key exchange algorithm (e.g. "RSA"), see also the Javadoc for X509TrustManager https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/X509TrustManager.html – Henno Vermeulen Jul 28 '17 at 14:07
  • 1
    Note that this code will throw no exception if the TrustManagerFactory has no trustManager thereby accepting the certificate. I glanced at the Javadoc for TrustManagerFactory and I believe this might happen if somehow your default Keystore contains no X509 certificates for CA's. To be better safe than sorry I would change the code to throw an exception if the for loop did not find an X509TrustManager. – Henno Vermeulen Jul 28 '17 at 14:18
  • Do you know if checkServerTrusted function checks if certificate has expired and does it check if the entity that send certificate in question is actually the owner of the certificate? Or does it just verifies that certificate is signed by a trusted CA? – Milos Savanovic Jul 26 '18 at 15:17
  • It seems that checkServerTrusted do check if certificate has expired since it throws CertificateExpiredException and CertificateNotYetValidException. – Milos Savanovic Jul 31 '18 at 16:36
1

What you are doing here is verifying if a certificate (in your example cert) has been signed (directly) by any of the trusted CA's in the truststore.
Additionally you check for expiration but no revocation checking is performed.
So if the cert has not been signed by any of the trusted CA's you will get an exception.
So the code is sufficient to verify if cert has been signed by any of the trusted CAs


If you are refering to server authentication, then the code in the post is not sufficient.
This code just verifies that a specific certificate is signed by a trusted CA.
You have no indication though if the "entity" that send you this certificate is actually the owner of the certificate (i.e. they own the private key associated with this certificate).
This is part of the SSL authentication, where e.g. the client sends the ClientKeyExchange message encrypted with the remote server's public key and is certain that if the other party is fake then it will not be possible to decrypt the message

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • Thanks for the quick response! Is the above piece of code sufficient to validate the certificate itself? I mean, if I get this certificate from a server, and I perform the above checks, can I safely assume the server's certificate is valid and the server is who it says it is. Thanks, your help is much appreciated. – user771870 May 26 '11 at 20:31
  • That does help. I am trying to implement server authentication for SSH. So once I get the certificate from the server during the initial exchange, I am trying to validate it to make sure the server is not fake and perform the validation procedure similar to how SSL performs the same. So would that mean that SSH would take care of the server authentication during key exchange(Before exchanges of certificates) and all I have to do is make sure that the certificate is a valid one? Thanks for the response and apologies if these questions seem stupid.I just started digging through SSH workflows :) – user771870 May 26 '11 at 21:04
  • If SSH can be configured with a certificate truststore, then if it works like SSL, SSH would have to verify if the same entity that passes the certificate also owns the matching private key. – Cratylus May 26 '11 at 21:29
  • ah! This is exactly I was not sure how to acheive. That would mean I have to own the public key of this entity as part of the setup right? If not, how can this be done via the fields of the X.509 certificate. The Signature field I gather is a signature encrypted by the CA and not the entity that passes me this certificate. Any suggestions? Thanks! – user771870 May 27 '11 at 13:55
  • I am not clear or what you are trying to do.Are trying to develop your own SSH implementation? – Cratylus May 27 '11 at 20:32
  • I am trying to implement server authentication via X.509 certificates when a SSH client connects to a SSH server. I am using a SSH library(Third party) that provides me with the certificate the server sends(When the server is setup so that it sends a certificate rather than a key). But the validation of this certificate is to be written by me. Hence these above questions. I am using the java keystore and the Keytools and Keystore class to work with the keystore. – user771870 Jun 01 '11 at 20:55