nl.nikhef.slcshttps.trust
Class TrustManagerImpl

java.lang.Object
  extended by nl.nikhef.slcshttps.trust.TrustManagerImpl
All Implemented Interfaces:
TrustManager, X509TrustManager

public class TrustManagerImpl
extends Object
implements X509TrustManager

This class implements a X509TrustManager which asks the user for confirmation when something is wrong and in this process also checks whether the hostname is valid for the certificate chain. This is non-trivial since the implemented methods which are called during the SSL handshake, checkServerTrusted() and checkClientTrusted(), do not have the hostname/portnumber. This class provides static fields which can be set using setHostname(String) and setPort(int) to solve this. These methods have to be called before setting up a HTTPS connection, which can be done e.g. by using HttxURLConnection. The user communication is handled by a implementation of TrustManagerImpl.TrustCommunicator. An implementation using just stdio is given by TrustManagerImpl.StdioComm. Note that using static fields for hostname and portnumber makes it non-thread safe. Doing this in a thread safe way is difficult since the response of the user on invalid certificates should be kept global.

Version:
0.1
Author:
Mischa Sallé

Nested Class Summary
(package private) static class TrustManagerImpl.StdioComm
          This Implementation uses only stdio/stderr for I/O.
static interface TrustManagerImpl.TrustCommunicator
          Interface for TrustManagerImpl communication with the user.
 
Field Summary
private static TrustManagerImpl.TrustCommunicator comm
          The TrustManagerImpl.TrustCommunicator to be used, can be set using setCommunicator(String).
private static String COMMPROP
          Propertyname to set the type of communicator "nl.nikhef.slcshttps.comm".
private static String commString
          describes the type of communicator in use, initialized using the value of property "nl.nikhef.slcshttps.comm" by setCommunicator(String).
private static String host
          hostname of the open connection.
private static int port
          portnumber of the open connection, note that for a certain combination hostname/portnumber there can only be one certificate chain; the portnumber is initialized to 443, the default for HTTPS.
private static Hashtable<String,TrustCert> trustCertsTable
          global table of known alias - certificate pairs, where alias is hostname:port.
 
Constructor Summary
TrustManagerImpl()
          Constructs a TrustManagerImpl.
TrustManagerImpl(String hostName)
          Constructs a TrustManagerImpl and sets the global hostName.
TrustManagerImpl(String hostName, int portNumber)
          Constructs a TrustManagerImpl and sets the global hostName and portNumber.
 
Method Summary
private  void addCert(String alias, TrustCert cert)
          Adds an alias/certificate to the list of known certificates.
 void checkClientTrusted(X509Certificate[] chain, String authType)
          Dummy Client Certificate chain checker, which never fails.
 void checkServerTrusted(X509Certificate[] chain, String authType)
          Main checking method, contains all the logic: it checks the Server certificate chain, also against the hostname which can be set either at construction time or using setHostname(String).
 X509Certificate[] getAcceptedIssuers()
          Return an array of certificate authority certificates which are trusted for authenticating peers.
static String getCommunicator()
          Returns the type of TrustManagerImpl.TrustCommunicator used for user interaction.
private  TrustCert getOldCert(X509Certificate x509Cert)
          Finds a certificate in the list of known alias/certificates.
private  void removeCert(String alias, TrustCert cert)
          Removes an alias/certificate from the list of known certificates.
static String setCommunicator(String commInput)
          Sets the type of TrustManagerImpl.TrustCommunicator based on commInput.
static void setHostname(String hostName)
          Sets the (static) hostname to be used during checking.
static void setPort(int portNumber)
          Sets the (static) portnumber to be used during checking.
private  void updateCert(String alias, TrustCert cert)
          Updates the status for a known certificate.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

COMMPROP

private static final String COMMPROP
Propertyname to set the type of communicator "nl.nikhef.slcshttps.comm".

See Also:
Constant Field Values

host

private static String host
hostname of the open connection.


port

private static int port
portnumber of the open connection, note that for a certain combination hostname/portnumber there can only be one certificate chain; the portnumber is initialized to 443, the default for HTTPS.


trustCertsTable

private static Hashtable<String,TrustCert> trustCertsTable
global table of known alias - certificate pairs, where alias is hostname:port.


commString

private static String commString
describes the type of communicator in use, initialized using the value of property "nl.nikhef.slcshttps.comm" by setCommunicator(String).


comm

private static TrustManagerImpl.TrustCommunicator comm
The TrustManagerImpl.TrustCommunicator to be used, can be set using setCommunicator(String).

Constructor Detail

TrustManagerImpl

public TrustManagerImpl()
Constructs a TrustManagerImpl. Note that the hostname/portnumber have to be set using setHostname(String) and setPort(int).

See Also:
TrustManagerImpl(String,int)

TrustManagerImpl

public TrustManagerImpl(String hostName)
Constructs a TrustManagerImpl and sets the global hostName.

Parameters:
hostName - hostname for which this TrustManager is used. Note that the portnumber has to be set using setPort(int).
See Also:
TrustManagerImpl(String,int)

TrustManagerImpl

public TrustManagerImpl(String hostName,
                        int portNumber)
Constructs a TrustManagerImpl and sets the global hostName and portNumber. Note that they can be changed using setHostname(String) and setPort(int).

Parameters:
hostName - sets the static hostname for the class
portNumber - sets the static port number for the class
Method Detail

checkServerTrusted

public void checkServerTrusted(X509Certificate[] chain,
                               String authType)
                        throws CertificateException
Main checking method, contains all the logic: it checks the Server certificate chain, also against the hostname which can be set either at construction time or using setHostname(String). It uses a table with alias/certificate pairs containing chains it has seen before. There are two reasons for this: if a certificate chain has been accepted once, it will be accepted again within the same session (unless is has expired); secondly the whole chain does not have to be checked again, improving performance. There are roughly 4 different possibilities:

Specified by:
checkServerTrusted in interface X509TrustManager
Parameters:
chain - peer X509Certificate chain to be checked.
authType - the key exchange algorithm used (unused).
Throws:
CertificateException - if the chain doesn't verify, including a unset hostname.

addCert

private void addCert(String alias,
                     TrustCert cert)
Adds an alias/certificate to the list of known certificates. It adds the alias to cert and then adds the alias/cert to the list of known certificates.

Parameters:
alias - the alias to add
cert - the certificate to add

updateCert

private void updateCert(String alias,
                        TrustCert cert)
Updates the status for a known certificate. It does this by removing and then adding the alias to cert, which effectively just changes the status.

Parameters:
alias - the alias
cert - the certificate for which to update the alias.

removeCert

private void removeCert(String alias,
                        TrustCert cert)
Removes an alias/certificate from the list of known certificates. It removes the alias from cert and then removes the alias from the list of known aliases.

Parameters:
alias - the alias to be removed
cert - the certificate that belongs to the alias.

getOldCert

private TrustCert getOldCert(X509Certificate x509Cert)
Finds a certificate in the list of known alias/certificates.

Parameters:
x509Cert - certificate to look for.
Returns:
TrustCert for the given X509Certificate or null when it is unknown.

checkClientTrusted

public void checkClientTrusted(X509Certificate[] chain,
                               String authType)
                        throws CertificateException
Dummy Client Certificate chain checker, which never fails.

Specified by:
checkClientTrusted in interface X509TrustManager
Parameters:
chain - X509Certificate chain to be checked
authType - the authentication type based on the client certificate
Throws:
CertificateException - if the chain doesn't verify

getAcceptedIssuers

public X509Certificate[] getAcceptedIssuers()
Return an array of certificate authority certificates which are trusted for authenticating peers.

Specified by:
getAcceptedIssuers in interface X509TrustManager
Returns:
X509Certificate[] a non-null (possibly empty) array of acceptable CA issuer certificates.
See Also:
CertChainChecker.getAcceptedIssuers()

setHostname

public static void setHostname(String hostName)
Sets the (static) hostname to be used during checking.

Parameters:
hostName - static hostname to be used during checking.
See Also:
TrustManagerImpl(String), TrustManagerImpl(String,int)

setPort

public static void setPort(int portNumber)
Sets the (static) portnumber to be used during checking.

Parameters:
portNumber - static portnumber to be used during checking.
See Also:
TrustManagerImpl(String,int)

setCommunicator

public static String setCommunicator(String commInput)
Sets the type of TrustManagerImpl.TrustCommunicator based on commInput. Valid values are:

Parameters:
commInput - String describing the wished type of communicator to be used.
Returns:
String describing the actual type being used.
See Also:
getCommunicator()

getCommunicator

public static String getCommunicator()
Returns the type of TrustManagerImpl.TrustCommunicator used for user interaction.

Returns:
String describing the type being used.
See Also:
setCommunicator(String)


nl.nikhef.slcshttps Mischa Sallé - msalle(AT)nikhef.nl