iaik.security.ssl
Class ChainVerifier

java.lang.Object
  extended by iaik.security.ssl.ChainVerifier
Direct Known Subclasses:
DefaultNoTrustChainVerifier, OCSPCertStatusChainVerifier

public class ChainVerifier
extends java.lang.Object

This class implements the ChainVerifier used by iSaSiLk by default. It provides fairly basic X.509v1 style implementation, i.e. it does not handle X.509v3 extensions (except for (Extended)KeyUsage and checks in client/server certificates) and has no kind of revocation checking. If you want to implement a different policy you have several options:

For more information about authentication see the separate document on Certificates and Authentication.


Field Summary
static int CACHE_SIZE
          Default certificate cache size (64).
protected  java.util.Hashtable cachedCerts
          Hashtable containing certificates previously verified ok.
protected  int cacheSize
          Size of the certificate cache.
protected  boolean checkServerName
          Whether to check (on the client side) if the remote peer name matches the name contained in the certificate.
protected  boolean nullTrusted
          Flag indicating if null (no certificate) is trusted.
protected  java.util.Hashtable trustedCerts
          Hashtable containing trusted certificates mapping Principal(subject) -> X509Certificate(trusted certificate).
 
Constructor Summary
  ChainVerifier()
          Creates a new ChainVerifier.
protected ChainVerifier(int k)
          Constructor for use by subclasses.
 
Method Summary
 void addTrustedCertificate(java.security.cert.X509Certificate cert)
          Adds the given certificate as trust anchor.
protected  void cacheCertificate(java.security.cert.X509Certificate cert)
          Mark a certificate as "cached ok."
protected  void cacheCertificates(java.security.cert.X509Certificate[] certs, int start, int end)
          Cache certificates from the chain.
protected  void clearCachedCertificates()
          Clear the cached certificates.
 void clearTrustedCertificates()
          Removes all trusted certificates.
protected  void dumpCertificateChain(java.security.cert.X509Certificate[] certs, SSLTransport transport)
          Dumps the peer certificate chain to the debug stream (if set).
 java.security.cert.X509Certificate[] getCertificateChain(int certChainType, URLAndOptionalHash[] urlAndOptionalHashList)
          Gets the certificates referenced by given URLAndOptionalHash list.
 boolean getCheckServerName()
          Return if the server name check is enabled.
protected  java.security.cert.X509Certificate getIssuerCertificate(java.security.cert.X509Certificate cert)
          Get the issuer certificate of the given certificate (if available in the pool of trusted certificates).
 java.util.Enumeration getTrustedCertificates()
          Gets all trusted certificates.
 java.security.cert.X509Certificate[] getTrustedCertificatesArray()
          Gets all trusted certificates.
 java.util.Enumeration getTrustedPrincipals()
          Gets the distinguished names of all trusted certificates.
 java.security.Principal[] getTrustedPrincipalsArray()
          Gets the distinguished names of all trusted certificates.
protected  boolean isCachedCertificate(java.security.cert.X509Certificate cert)
          Check whether a certificate is cached.
protected  boolean isTrustedCertificate(java.security.cert.X509Certificate cert)
          Checks if the given certificate is explicitly trusted.
 void removeTrustedCertificate(java.security.cert.X509Certificate cert)
          Removes the given certificate from the list of trusted certificates.
protected  void setCacheSize(int cacheSize)
          Sets the size of the cache.
 void setCheckServerName(boolean checkServerName)
          Enable or disable the check of the name in the server certificate.
 int size()
          Gets the number of trusted certificates.
protected  boolean verifyCertificate(java.security.cert.X509Certificate cert, java.security.cert.X509Certificate issuerCert)
          Verify a certificate given its issuer certificates.
 boolean verifyChain(java.security.cert.X509Certificate[] certs, SSLTransport transport)
          Verify a certificate chain.
 boolean verifyChain(java.security.cert.X509Certificate[] certs, SSLTransport transport, int statusType, byte[] statusRequest, byte[] statusResponse)
          Verify a certificate chain.
protected  boolean verifyClient(java.security.cert.X509Certificate[] certs, SSLTransport transport)
          Perform verification specific to client certificates.
protected  boolean verifyServer(java.security.cert.X509Certificate[] certs, SSLTransport transport)
          Perform verification specific to server certificates.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CACHE_SIZE

public static final int CACHE_SIZE
Default certificate cache size (64). If the cache is full, it is cleared.

See Also:
Constant Field Values

trustedCerts

protected java.util.Hashtable trustedCerts
Hashtable containing trusted certificates mapping Principal(subject) -> X509Certificate(trusted certificate).


nullTrusted

protected boolean nullTrusted
Flag indicating if null (no certificate) is trusted.


cacheSize

protected int cacheSize
Size of the certificate cache. If the cache is full, it is cleared;


cachedCerts

protected java.util.Hashtable cachedCerts
Hashtable containing certificates previously verified ok. Map Certificate(cert) -> Certificate(cert).


checkServerName

protected boolean checkServerName
Whether to check (on the client side) if the remote peer name matches the name contained in the certificate.

Constructor Detail

ChainVerifier

protected ChainVerifier(int k)
Constructor for use by subclasses. It does not initialize any variables, the value of k is ignored. This constructor is intended for subclasses that override all methods and do not make use of the default implementations.


ChainVerifier

public ChainVerifier()
Creates a new ChainVerifier. Initially the list of trusted certificates is empty.

Method Detail

addTrustedCertificate

public void addTrustedCertificate(java.security.cert.X509Certificate cert)
Adds the given certificate as trust anchor.
Add null if want to accept if the peer does not send a certificate (i.e. you want to trust an anonymous peer).

Parameters:
cert - the certificate to be trusted

removeTrustedCertificate

public void removeTrustedCertificate(java.security.cert.X509Certificate cert)
Removes the given certificate from the list of trusted certificates.

Parameters:
cert - the certificate to be no more trusted

clearTrustedCertificates

public void clearTrustedCertificates()
Removes all trusted certificates.


size

public int size()
Gets the number of trusted certificates.

Returns:
the number of trusted certificates

getTrustedPrincipals

public java.util.Enumeration getTrustedPrincipals()
Gets the distinguished names of all trusted certificates.

Returns:
an enumeration of the distinguished names (as Principal objects) of the trusted certificates; the enumeration may be empty of no trusted certificates are set

getTrustedPrincipalsArray

public java.security.Principal[] getTrustedPrincipalsArray()
Gets the distinguished names of all trusted certificates.

Returns:
an array of the distinguished names (as Principal objects) of the trusted certificates; the array may be empty of no trusted certificates are set

getTrustedCertificates

public java.util.Enumeration getTrustedCertificates()
Gets all trusted certificates.

Returns:
an enumeration of the trusted certificates; the enumeration may be empty of no trusted certificates are set

getTrustedCertificatesArray

public java.security.cert.X509Certificate[] getTrustedCertificatesArray()
Gets all trusted certificates.

Returns:
an array of the trusted certificates; the array may be empty of no trusted certificates are set

isTrustedCertificate

protected boolean isTrustedCertificate(java.security.cert.X509Certificate cert)
Checks if the given certificate is explicitly trusted.

Returns:
true if the certificate is trusted false if it is not trusted

verifyCertificate

protected boolean verifyCertificate(java.security.cert.X509Certificate cert,
                                    java.security.cert.X509Certificate issuerCert)
                             throws java.lang.Exception
Verify a certificate given its issuer certificates. The issuer certificate may be null if it is not available. The method should return true to indicate that verifying of the chain should stop and return true. It should return false to proceed normally, and throw an Exception if the chain should be rejected.

The default implementation does the following in order:

  1. Throw an exception if the certificate is expired.
  2. If the certificate is explicitly trusted, return true.
  3. If the issuer certificate is non null verify the signature of the
  4. main certificate and throw an exception if it is invalid.
  5. Otherwise return false.
In other words, the method does not verify beyond explicitly trusted certificates. This method may be overridden to implement a different policy.

In the default implementation this method is only called by verifyChain().

Throws:
java.lang.Exception

getIssuerCertificate

protected java.security.cert.X509Certificate getIssuerCertificate(java.security.cert.X509Certificate cert)
Get the issuer certificate of the given certificate (if available in the pool of trusted certificates).

In the default implementation this method is called only by verifyChain().


verifyChain

public boolean verifyChain(java.security.cert.X509Certificate[] certs,
                           SSLTransport transport)
                    throws SSLCertificateRuntimeException
Verify a certificate chain.

Note that the default implementation of this method can only be used if the methods isTrustedCertificate(), verifyCertificate(), and getIssuerCertificate() behave as described above.

The default implementation does the following in order:

  1. If the chain is null, it returns true if null is trusted, otherwise false.
  2. When verifying client certs call verifyClient(), for server certs call verifyServer(). If false is returned, return false.
  3. The chain is verified starting at the user certificate via verifyCert(). If any call returns true it returns true, if any throws an exception it returns false.
  4. If the previous steps did not cause the method to stop it returns true if and only if size() returns 0, i.e. no certificates are trusted at all.

That means invalid certificate chains (signatures that do not verify, expired certificates) are never accepted. If trusted certificates are set only valid chains containing a trusted certificate are accepted, otherwise all valid chains are accepted.

Parameters:
certs - the certificate chain to be verified
transport - the SSLTransport, maybe required to query for information (e.g. client mode?) and/or printing debug information
Throws:
SSLCertificateRuntimeException - maybe used by an application to wrap an exception thrown by some self-designed ChainVerifier implementation

verifyChain

public boolean verifyChain(java.security.cert.X509Certificate[] certs,
                           SSLTransport transport,
                           int statusType,
                           byte[] statusRequest,
                           byte[] statusResponse)
Verify a certificate chain.

Note that the default implementation of this method can only be used if the methods isTrustedCertificate(), verifyCertificate(), and getIssuerCertificate() behave as described above.

The default implementation does the following in order:

  1. If the chain is null, it returns true if null is trusted, otherwise false.
  2. When verifying client certs call verifyClient(), for server certs call verifyServer(). If false is returned, return false.
  3. The chain is verified starting at the user certificate via verifyCert(). If any call returns true it returns true, if any throws an exception it returns false.
  4. If the previous steps did not cause the method to stop it returns true if and only if size() returns 0, i.e. no certificates are trusted at all.

That means invalid certificate chains (signatures that do not verify, expired certificates) are never accepted. If trusted certificates are set only valid chains containing a trusted certificate are accepted, otherwise all valid chains are accepted.

The statusRequest and statusResponse parameters are only meaningful on the client side and only if client and server have agreed that the server shall provide certificate status information in response to a CertificateStatusRequest extension sent by the client.
In this case, if both statusRequest and statusResponse are not null, they represent the (TLS) encoded request field of a CertificateStatusRequest TLS extension sent to the server and the (TLS) encoded response field of the CertificateStatus handshake message received from the server (see RFC 4366). The ChainVerifier then may use this information to check the revocation status of the server certificate(s). By default these parameters are simple ignored (since it is not possible to check ocsp status in provider independent way). You may use the IAIK-JCE based OCSPCertStatusChainVerifier to check the certificate status based on OCSP CertificateStatus(Request) extensions.

Parameters:
certs - the certificate chain to be verified
transport - the SSLTransport, maybe required to query for information (e.g. client mode) and/or printing debug information
statusType - the type of the certificate status request sent to the server (and of the status response received from the server), or -1 if no status_request extension has been sent to the server (or we are on the server side)
statusRequest - the (TLS) encoded status request sent to the server, or null if no status_request extension has been sent to the server, or we are on the server side
statusResponse - the (TLS) encoded status response of the requested type containing (revocation) status information for the certificates sent by the server, or null if no status response has been sent by the server (or we are on the server side)
Throws:
SSLCertificateRuntimeException - maybe used by an application to wrap an exception thrown by some self-designed ChainVerifier implementation
See Also:
OCSPCertStatusChainVerifier

verifyServer

protected boolean verifyServer(java.security.cert.X509Certificate[] certs,
                               SSLTransport transport)
Perform verification specific to server certificates. This implementation checks KeyUsage and ExtendedKeyUsage (if supported by the SecurityProvider) and whether the remote peer name matches any of the server names contained in the certificate. However, this check is only performed if it has been enabled for this ChainVerifier by calling setCheckServerName(true), or if the client extension list contains a critical ServerNameList extension. In this case the server name(s) in the ServerNameList extension is/are compared with the server name(s) in the certificate.

Note that the server name(s) is/are extracted from the certificate using SecurityProvider.getTLSServerName(X509Certificate) which is implemented for the IAIK JCE provider but not for the default provider.

Also note that this method is only called by method verifyChain.

Parameters:
certs - the certificates sent by the server
transport - the current SSLTransport object
Returns:
true if server name verification is successful, false if not or KeyUsage/ExtendedKeyUsage are not used properly

verifyClient

protected boolean verifyClient(java.security.cert.X509Certificate[] certs,
                               SSLTransport transport)
Perform verification specific to client certificates. In this implementation this method check the ExtendedKeyUsage extension -- if supported by the SecurityProvider -- of the client certificate

Note that this method is only called by verifyChain().

Returns:
true if the ExtendedKeyUsage check succeeds, false otherwise

setCheckServerName

public void setCheckServerName(boolean checkServerName)
Enable or disable the check of the name in the server certificate.
It is disabled by default (except when the client used a critical ServerNameList extension).
When calling
 chainVerifier.setCheckServerName(true);
 
 and the client has sent a server_name extension, the
 server certificate name(s) are checked against the server names of
 the server_name extension, regardless if the 
 server_name extension has been specified as critical
 or not critical. If no server_name extension has been sent,
 the server certificate name(s) are checked against the peer name got from
 the SSLTransport.
 
When calling
 chainVerifier.setCheckServerName(false);
 
 the server certificate name(s) are only checked if the client has
 configured a critical ServerNameList
 extension.

See Also:
verifyServer(java.security.cert.X509Certificate[], iaik.security.ssl.SSLTransport)

getCheckServerName

public boolean getCheckServerName()
Return if the server name check is enabled.
It is disabled by default (except when the client used a critical ServerNameList extension).
When getCheckServerName() is true and the client has sent a server_name extension, the server certificate name(s) are checked against the server names of the server_name extension, regardless if the server_name extension has been specified as critical or not critical. If no server_name extension has been sent, the server certificate name(s) are checked against the peer name got from the SSLTransport.
When getCheckServerName() is false the server certificate name(s) are only checked if the client has configured a critical ServerNameList extension.

See Also:
verifyServer(java.security.cert.X509Certificate[], iaik.security.ssl.SSLTransport)

cacheCertificate

protected void cacheCertificate(java.security.cert.X509Certificate cert)
Mark a certificate as "cached ok." Once a certificate chain has been verified and found to be ok and containing a trusted root, the certificates below the root do not have to be verified again. To save the time verifying signatures these certificates are cached via this method.


cacheCertificates

protected void cacheCertificates(java.security.cert.X509Certificate[] certs,
                                 int start,
                                 int end)
Cache certificates from the chain.


isCachedCertificate

protected boolean isCachedCertificate(java.security.cert.X509Certificate cert)
Check whether a certificate is cached.


clearCachedCertificates

protected void clearCachedCertificates()
Clear the cached certificates.


setCacheSize

protected void setCacheSize(int cacheSize)
Sets the size of the cache. If the cache is full, it is cleared.

Parameters:
cacheSize - the size of the cache

dumpCertificateChain

protected void dumpCertificateChain(java.security.cert.X509Certificate[] certs,
                                    SSLTransport transport)
Dumps the peer certificate chain to the debug stream (if set).

Parameters:
certs - the certificate chain to be dumped
transport - the SSLTransport, maybe required to query for information (e.g. client mode?) and/or printing debug information

getCertificateChain

public java.security.cert.X509Certificate[] getCertificateChain(int certChainType,
                                                                URLAndOptionalHash[] urlAndOptionalHashList)
                                                         throws SSLCertificateException
Gets the certificates referenced by given URLAndOptionalHash list.

When client and server have negotiated a client_certificate_url extension (see RFC 4366), the client may send a CertificateURL handshake message instead of a Certificate message. The CertificateURL contains a list of URLAndOptionalHash elements that point to location(s) from where the server can download the client certificate(s).

iSaSiLk calls this method on the server side to download (or get the cached) certificates from the referenced urls. Depending on the cert chain type the URLAndOptionalHash list may contain a separate url for each certificate of the client chain (cert chain type individual_certs), or may contain only one url pointing to a location from where the client ceritficate chain can be downloaded as DER encoded pki path (ASN.1 SEQUENCE of Certificate). Regardless of representing separate urls to DER encoded X.509 certificates or one url to a DER encoded pki path, the top-level root certificate maybe not linked (since it is expected that it already has been obtained (and used as trust anchor) by the server by other means).
Each URLAndOptionalHash element may contain a SHA-1 hash calculated over the referred DER encoded certificate or pki path to allow the server to check if the downloaded certificate(s) have been actually referenced by the client. This method has to calculate the hash value(s) from the downloaded (or cached) certificate(s) / pki path and throw an exception if the hash verification fails.

Note that the certificates in a PKI path are ordered in a way that the client certificate is located at index [n-1]. However TLS expects certificates in reverse order (client certificate at index 0). For that reason this method may have to reverse the order of the certificates parsed from the PKI path.

Parameters:
certChainType - the cert chain type, either CHT_INDIVIDUAL_CERTS (0) (when each of the given URLAndOptionalHash objects refers to a single DER encoded certificate of the client cert chain), or CHT_PKI_PATH (1) (when the URLAndOptionalHash list contains only one element that points to a location from where the client certificate chain can be downloaded as DER encoded pki path)
urlAndOptionalHashList - an array of URLAndOptionalHash objects pointing to location(s) from where the client certificate(s) can be obtained; the array may contain only one element to refer to a pki path or may contain as many elements as necessary for separatly referring each certificate of the client certificate chain
Returns:
an array holding the certificates parsed from the PKI path; the array has to be ordered according subject-issuer relationship and has to contain the client certificate at index 0
Throws:
SSLCertificateException - if an error occurs when getting/downloading the client certificates or the hash verification fails

This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note).

iSaSiLk 5.104, (c) 2002 IAIK, (c) 2003 - 2015 SIC