org.eu.mayrhofer.authentication
Class DHOverTCPWithVerification

java.lang.Object
  extended by org.eu.mayrhofer.authentication.AuthenticationEventSender
      extended by org.eu.mayrhofer.authentication.DHOverTCPWithVerification
Direct Known Subclasses:
RelateAuthenticationProtocol

public abstract class DHOverTCPWithVerification
extends AuthenticationEventSender

This is an abstract class that implements the basics of all protocols based on Diffie-Hellman key exchange over TCP with subsequent verification of the key material to check that it is equal on both sides. This verification is necessary to prevent man-in-the-middle attacks. Derived classed need to implement this specific check that the authentication key provided by SimpleKeyAgreement matches by implementing the method startVerification. This method should asynchronously start the verification step, i.e. not block the caller, and should then either call verificationSuccess or verificationFailure depending on the outcome of the check. Upon calling one of the methods, a status exchange with the remote host will be done over the TCP channel to arrive at a common decision if the whole protocol succeeded. The final verdict will be signalled by emitting standard authentication events (as defined by AuthenticationProgressHandler) and by calling either the protocolSucceededHook or the protocolFailedHook function. In short, the whole authentication protocol should be used as follows: 1. Construct the object. Either: 2a. Start the TCP server. 3b. Start an authentication protocol to a remote device by calling startAuthentication. (It is possible to start a server and then initiate a protocol run, but only one protocol run can be active at a time.) 4. After the key agreement phase succeeded, the abstract startVerification method is called. In this method, derived classes should asynchronously start whatever is necessary to verify the provided shared authentication key. 5. When a local decision about the key verification has been made, call either verificationSucceess or verificationFailure. 6. The local decisions will be communicated over the TCP channel and if both devices signalled success, the protocolSucceededHook will be called. In any other case (both or either of the devices signalled failure on verification), the protocolFailedHook will be called. Generally, events will be emitted by this class to all registered listeners.

Version:
1.0
Author:
Rene Mayrhofer

Field Summary
protected  boolean useJSSE
          If set to true, the JSSE will be used, if set to false, the Bouncycastle Lightweight API.
 
Fields inherited from class org.eu.mayrhofer.authentication.AuthenticationEventSender
eventsHandlers
 
Constructor Summary
protected DHOverTCPWithVerification(int tcpPort, boolean keepSocketConnected, java.lang.String instanceId, boolean useJSSE)
          Construct the object by initializing basic variables.
 
Method Summary
 boolean isIdle()
          This method returns true if this object is idle or if it is currently running the authentication protocol with a remote host.
 boolean isVerifying()
          This method returns true if key verification is currently running.
protected abstract  void protocolFailedHook(java.net.InetAddress remote, java.lang.Object optionalRemoteId, java.lang.Exception e, java.lang.String message)
          This hook will be called when the whole authentication protocol has failed.
protected abstract  void protocolProgressHook(java.net.InetAddress remote, java.lang.Object optionalRemoteId, int cur, int max, java.lang.String message)
          This hook will be called when the whole authentication protocol has made some progress.
protected abstract  void protocolSucceededHook(java.net.InetAddress remote, java.lang.Object optionalRemoteId, java.lang.String optionalParameterFromRemote, byte[] sharedSessionKey, java.net.Socket toRemote)
          This hook will be called when the final verdict is that the whole authentication protocol succeeded, i.e.
protected abstract  void resetHook()
          This hook will be called when the object is reset to its "idle" state, i.e.
protected  boolean startAuthentication(java.lang.String remoteHost, java.lang.String param)
          Starts the authentication protocol in the background.
 void startServer()
          This is a helper function to start the "server" part of the authentication protocol.
protected abstract  void startVerification(byte[] sharedAuthenticationKey, java.net.InetAddress remote, java.lang.String param, java.net.Socket socketToRemote)
          This method must be implemented by derived classes.
 void stopServer()
          This is a helper function to stop the "server" part of the authentication protocol.
protected  void verificationFailure(java.lang.Object optionalRemoteId, java.lang.String optionalParameterToRemote, java.lang.Exception e, java.lang.String msg)
          This method should be called by derived classes after key verification has been started with the startVerification method.
protected  void verificationSuccess(java.lang.Object optionalRemoteId, java.lang.String optionalParameterToRemote)
          This method should be called by derived classes after key verification has been started with the startVerification method.
 
Methods inherited from class org.eu.mayrhofer.authentication.AuthenticationEventSender
addAuthenticationProgressHandler, raiseAuthenticationFailureEvent, raiseAuthenticationProgressEvent, raiseAuthenticationSuccessEvent, removeAuthenticationProgressHandler
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

useJSSE

protected boolean useJSSE
If set to true, the JSSE will be used, if set to false, the Bouncycastle Lightweight API.

Constructor Detail

DHOverTCPWithVerification

protected DHOverTCPWithVerification(int tcpPort,
                                    boolean keepSocketConnected,
                                    java.lang.String instanceId,
                                    boolean useJSSE)
Construct the object by initializing basic variables.

Parameters:
tcpPort - The TCP port to use for listening and for connecting to remote hosts.
useJSSE - If set to true, the JSSE API with the default JCE provider of the JVM will be used for cryptographic operations. If set to false, an internal copy of the Bouncycastle Lightweight API classes will be used.
keepSocketConnected - If set to true, the opened client socket soc is passed to the authentication success event (in the results parameter) for further re-use of the connection (e.g. passing additional information about further protocol steps). If set to false, the socket will be closed when this protocol is done with it. The socket will always be closed on authentication failures. If in doubt, set to false;
instanceId - This parameter may be used to distinguish differenc instances of this class running on the same machine. It will be used in logging and error messages. May be set to null.
Method Detail

isIdle

public boolean isIdle()
This method returns true if this object is idle or if it is currently running the authentication protocol with a remote host. Callers should check that it is idle before calling startAuthentication, because only one protocol can be run at a time (this might change in the future at least for the host authentication phase, but right now, we only accept new authentication runs to be started when idle).

Returns:
true when the object is idle, i.e. when a new authentication can be started.

isVerifying

public boolean isVerifying()
This method returns true if key verification is currently running.

Returns:
true when the object is in key verification state, false otherwise.

startAuthentication

protected boolean startAuthentication(java.lang.String remoteHost,
                                      java.lang.String param)
                               throws java.net.UnknownHostException,
                                      java.io.IOException
Starts the authentication protocol in the background. Listeners should subscribe to authentication events to get notified about the progress of authentication.

Parameters:
remoteHost - The hostname/IP address of the remote device to send an authentication request to.
param - An optional parameter that should be exchanged with the host, usually describing some parameter(s) of the subsequent verification step.
Returns:
true if the authentication could be started, false otherwise.
Throws:
java.net.UnknownHostException
java.io.IOException
See Also:
AuthenticationEventSender.addAuthenticationProgressHandler(org.eu.mayrhofer.authentication.AuthenticationProgressHandler), DongleProtocolHandler.handleDongleCommunication(byte[], byte[], int, org.eu.mayrhofer.authentication.InterlockProtocol, org.eu.mayrhofer.authentication.InterlockProtocol)

verificationSuccess

protected void verificationSuccess(java.lang.Object optionalRemoteId,
                                   java.lang.String optionalParameterToRemote)
This method should be called by derived classes after key verification has been started with the startVerification method. Calling this method signals a local success of the key verification, but the whoel authentication protocol can still fail when the other host signals a failure. After calling this method, either the protocolSucceededHook or the protocolFailedHook will be called.

Parameters:
optionalRemoteId - An optional remote ID that will be forwarded to the hook functions. It can be used to identify the remote device.
optionalParameterToRemote - An optional parameter that should be sent to the remote device alongside the success status message. This will also be forwarded to the hook functions.

verificationFailure

protected void verificationFailure(java.lang.Object optionalRemoteId,
                                   java.lang.String optionalParameterToRemote,
                                   java.lang.Exception e,
                                   java.lang.String msg)
This method should be called by derived classes after key verification has been started with the startVerification method. Calling this method signals a local failure of the key verification, so the whole authentication protocol must fail (it can only succeed when both hosts signal success). After calling this method, the protocolFailedHook will be called.

Parameters:
optionalRemoteId - An optional remote ID that will be forwarded to the hook function. It can be used to identify the remote device.
optionalParameterToRemote - An optional parameter that should be sent to the remote device alongside the success status message. This will also be forwarded to the hook function.

startServer

public void startServer()
                 throws java.io.IOException
This is a helper function to start the "server" part of the authentication protocol. It constructs a HostServerSocket object and sets up this object as a listener.

Throws:
java.io.IOException
See Also:
serverSocket

stopServer

public void stopServer()
This is a helper function to stop the "server" part of the authentication protocol.

See Also:
serverSocket

startVerification

protected abstract void startVerification(byte[] sharedAuthenticationKey,
                                          java.net.InetAddress remote,
                                          java.lang.String param,
                                          java.net.Socket socketToRemote)
This method must be implemented by derived classes. It shoudl start the verification of the shared key to make sure that the other host shared the same and thus rule out man-in-the-middle attacks during the Diffie-Hellman key agreement.

Parameters:
sharedAuthenticationKey - This key should be verified to be equal on both sides.
remote - The remote host with which the key exchange succeeded.
param - Optional parameters sent by the remote host during the key agreement phase.
socketToRemote - This socket is still open and can be used to communicate with the remote host for verifying the authentication key. When it is used, care must be taken not to consume any bytes from the remote end that are not expected during verification, because the same channel will be used for exchanging status information about the success or failure of the whole authentication protocol.

resetHook

protected abstract void resetHook()
This hook will be called when the object is reset to its "idle" state, i.e. so that subsequent authentications can be performed. Derived classes should implement it to react to being reset. A reset of the object will occur after both failure and after success of the whole authentication protocol.


protocolSucceededHook

protected abstract void protocolSucceededHook(java.net.InetAddress remote,
                                              java.lang.Object optionalRemoteId,
                                              java.lang.String optionalParameterFromRemote,
                                              byte[] sharedSessionKey,
                                              java.net.Socket toRemote)
This hook will be called when the final verdict is that the whole authentication protocol succeeded, i.e. both hosts signalled success on key verification.

Parameters:
remote - The remote host with which the key exchange succeeded.
optionalRemoteId - An optional remote ID, exactly as it has been passed to verificationSuccess. May be null.
optionalParameterFromRemote - If the remote device reported an additional parameter with its success message, it will be put into this parameter. May be null.
sharedSessionKey - The shared session key (which is different from the shared authentication key used for verification) that can now be used for subsequent secure communication.
toRemote - If it has been requested that the socket to the remote host should stay connected, it will be passed in this parameter. May be null.

protocolFailedHook

protected abstract void protocolFailedHook(java.net.InetAddress remote,
                                           java.lang.Object optionalRemoteId,
                                           java.lang.Exception e,
                                           java.lang.String message)
This hook will be called when the whole authentication protocol has failed. Derived classes should implement it to react to this failure.

Parameters:
remote - The remote host with which the key exchange succeeded.
optionalRemoteId - An optional remote ID, exactly as it has been passed to verificationSuccess or verificationFailure. May be null.
e - If not null, the exception describing the failure.
message - If not null, the message describing the failure.

protocolProgressHook

protected abstract void protocolProgressHook(java.net.InetAddress remote,
                                             java.lang.Object optionalRemoteId,
                                             int cur,
                                             int max,
                                             java.lang.String message)
This hook will be called when the whole authentication protocol has made some progress. Derived classes should implement it to react to this progress.

Parameters:
remote - The remote host with which the key exchange succeeded.
optionalRemoteId - An optional remote ID, exactly as it has been passed to verificationSuccess or verificationFailure. May be null.
cur - @see AuthenticationProgressHandler#AuthenticationProgress
max - @see AuthenticationProgressHandler#AuthenticationProgress
message - @see AuthenticationProgressHandler#AuthenticationProgress


2005-2006, Rene Mayrhofer.