|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectorg.openuat.authentication.AuthenticationEventSender
org.openuat.authentication.HostProtocolHandler
public class HostProtocolHandler
This class handles the key agreement protocol between two hosts on a stream
level. It implements both sides of the protocol, allowing to handle incoming
connections (i.e. incoming authentication requests) as well as initiating
outgoing connections (i.e. outgoing authentication requests). Events are
raised upon authentication success, failure and during the progress of an
authentication protocol.
The protocol is called UACAP (unified auxiliary channel authentication
protocol) and is based on the MANA IV family of multi-channel authentication
protocols as specified in [Sven Laur and Kaisa Nyberg: "Efficient Mutual Data
Authentication Using Manually Authenticated Strings: Extended Version"],
specifically the MA-DH variant. However, it additionally implements an
optional commitment-based exchange instead of just producing an out-of-band
message from the key material for the input type authentication as
explained below. This optional exchange is based on the MANA III protocol
presented earlier and a variant proposed by Wong and Stajano.
This class has a dual interface and can thus be used in two different ways:
either by driving the steps in the protocol from an outside caller on the
instantiated object (henceforth referred to as the PlainObject style) or by
registering an out-of-band channel that is subsequently used by
HostProtocolHandler to handle the complete protocol run (henceforth referred
to as the Hollywood style, cf. http://c2.com/cgi/wiki?HollywoodPrinciple).
The PlainObject style is more flexible, as all steps "outside" the basic
crypto protocol can be handled in any way, and is used by instantiating the
object with the "basic" constructor.
The Hollywood style can be easier to use, making the whole authentication
protocol a black box by reducing it to a single method call, and can be used
when an object implementing the OOBChannel interface is conveniently
available. In this case, instantiate the object by passing the
AuxiliaryChannel object to the constructor.
In both cases, the object will fire usual authentication events for any
outside listener.
TODO: This explanation needs to be updated to actually be true...
The simplest possible case to use the ManaIV class for authentication is to
instantiate it, Hollywood style, with an existing OOBChannel object and to
let it run the key agreement:
ManaIV m = new ManaIV(myOobChannel, true); m.addAuthenticationProgressHandler(myself); m.authenticate(); // this method returns immediately // ... wait for AuthenticationSuccess event and use the embedded keyAlternatively, it may e.g. be used for the heavy crypto lifting, but out-of-band message transfer is handled in a custom way, PlainObject style: ManaIV m1 = new ManaIV(true); byte[] msg = m1.getOobMessage(); // transfer msg to the remote side in a secure way // on the other side: m2.addOobMessage(msg); The authentication success event generated by this protocol will return a RemoteConnection object for the remote parameter and an Object array as the result parameter. This object array will always have at least 3 objects: two byte arrays representing the session key and the out-of-band message for transfer or comparison verification, and a String representing the optional parameter that might have been specified by the client or which might have been passed to the protocol when in client mode. This third object in the object array can be null if no parameter was specified, but it will always be there. For input type authentication, the second object (the out-of-band message) will be null because authentication will have already happened at this stage. For the other two types, the first object (the session key) may only be used after successful (mutual) verification of the out-of-band message. An optional fourth object will be included with the array when the keepSocketConnected flag was set. This fourth parameter will then contain the still connected channel object.
| Field Summary | |
|---|---|
static int |
AuthenticationStages
At the moment, the whole protocol consists of 5 stages. |
protected RemoteConnection |
connection
The (already opened) connection used to communicate with the remote end, for both incoming and outgoing connections. |
protected boolean |
dontWipeKeyAgreement
If ephemeral Diffie-Hellman keys should not be used (for example, because this host must use permanent keys because its pre-authentication commitment is on a printed sticker that can't be changed), then this can be set to true. |
protected java.io.InputStream |
fromRemote
The stream to receive messages from the remote end. |
protected boolean |
keepConnected
If set to false, connection will be closed after the protocol finished successfully. |
protected SimpleKeyAgreement |
keyAgreement
This holds the single instance of our (Diffie-Hellman) based key agreement protocol. |
protected byte[] |
myPublicKey
As soon as keyAgreement is initialized, this will also be set to our public key. |
protected java.lang.String |
optionalParameter
An optional parameter that can be passed from the client to the server in its authentication request message. |
protected java.util.Vector |
presharedShortSecrets
If this is set, then we have some form of user input that has been created _before_ starting the protocol instance and is assumed to be secret. |
static java.lang.String |
Protocol_AuthenticationAcknowledge
|
static java.lang.String |
Protocol_AuthenticationAcknowledge2
|
static java.lang.String |
Protocol_AuthenticationInputCommit
|
static java.lang.String |
Protocol_AuthenticationInputOpen
|
static java.lang.String |
Protocol_AuthenticationRequest
|
static java.lang.String |
Protocol_AuthenticationRequest_Param
This is an optional field in the authentication request line, where the client can pass parameters to the next authentication protocol. |
static java.lang.String |
Protocol_Hello
These are the messages of the ASCII authentication protocol. |
static java.lang.String |
ProtocolTypeMaDH
This is the protocol and version string to identify which protocol we expect. |
protected byte[] |
remotePreAuthenticationMessage
|
protected int |
timeoutMs
If ! |
protected java.io.OutputStreamWriter |
toRemote
The stream to send messages to the remote end. |
protected int |
totalTransferSize
The number of bytes that have been transferred in both directions. |
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.openuat.authentication.AuthenticationEventSender |
|---|
eventsHandlers |
| Constructor Summary | |
|---|---|
HostProtocolHandler(RemoteConnection con,
int timeoutMs,
boolean keepConnected,
boolean useJSSE)
This constructor should only be used by HostServerBase for incoming connections or with the static startAuthenticatingWith method for outgoing connections. |
|
HostProtocolHandler(RemoteConnection con,
java.util.Vector presharedShortSecrets,
SimpleKeyAgreement permanentKeyAgreement,
int timeoutMs,
boolean keepConnected,
boolean useJSSE)
This constructor should only be used by HostServerBase for incoming connections or with the static startAuthenticatingWith method for outgoing connections. |
|
| Method Summary | |
|---|---|
void |
addProtocolCommandHandler(java.lang.String command,
ProtocolCommandHandler handler)
Adds a protocol command handler. |
static byte[] |
commitment(byte[] ownPublicKey,
boolean useJSSE)
This method implements the simplest possible commitment scheme for public Diffie-Hellman keys: a hash value on the key. |
protected java.lang.String |
getLine(java.lang.String expectedMsg,
RemoteConnection remote,
boolean allowOtherCommands)
Tries to receive a properly formatted line from the remote host. |
byte[] |
getPreAuthenticationMessage()
For the pre-authentication transfer case, this method returns our pre-authentication message. |
static byte[] |
keyedHash(byte[] oobInput,
byte[] oobKey,
boolean useJSSE)
This method implements the keyed hash function for computing the l-Bit out-of-band message. |
protected java.lang.Object[] |
parseLine(java.lang.String line,
java.lang.String expectedMsg,
boolean[] isHexNumber,
java.lang.String[] expectedParts,
int numMandatoryParms,
RemoteConnection remote)
Tries to decode properly formatted Strings and numbers from the protocol line. |
protected void |
performAuthenticationProtocol(boolean serverSide)
This method depends on prior initialization and assumes to be launched in an independent thread, i.e. it performs blocking operations. |
protected void |
println(java.lang.String line)
Simple helper function for writing a line to the remote. |
protected java.lang.String |
readLine()
Simple helper function for reading a line from the remote. |
boolean |
removeProtocolCommandHandler(java.lang.String command)
Removes a protocol command handler. |
void |
setPreAuthenticationMessage(byte[] publicKeyCommitment)
Set the remote pre-authentication message. |
void |
setProtocolCommandHandlers(java.util.Hashtable handlers)
Set the list of registered protocol command handlers, if none has been registered so far. |
static void |
startAuthenticationWith(RemoteConnection remote,
AuthenticationProgressHandler eventHandler,
int timeoutMs,
boolean keepConnected,
java.lang.String optionalParameter,
boolean useJSSE)
This is a convenience wrapper setting all options to null and thus starting the protocol in transfer or verification mode. |
static void |
startAuthenticationWith(RemoteConnection remote,
AuthenticationProgressHandler eventHandler,
SimpleKeyAgreement permanentKeyAgreementInstance,
java.util.Vector presharedShortSecrets,
byte[] remotePreAuthenticationMessage,
int timeoutMs,
boolean keepConnected,
java.lang.String optionalParameter,
boolean useJSSE)
Outgoing authentication connections are done asynchronously just like the incoming connections. |
void |
startIncomingAuthenticationThread(boolean asynchronousCall)
Starts a background thread for handling an incoming authentication request. |
| Methods inherited from class org.openuat.authentication.AuthenticationEventSender |
|---|
addAuthenticationProgressHandler, raiseAuthenticationFailureEvent, raiseAuthenticationProgressEvent, raiseAuthenticationStartedEvent, raiseAuthenticationSuccessEvent, removeAuthenticationProgressHandler, setAuthenticationProgressHandlers |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
public static final java.lang.String Protocol_Hello
public static final java.lang.String ProtocolTypeMaDH
public static final java.lang.String Protocol_AuthenticationRequest
Protocol_Hello,
Constant Field Valuespublic static final java.lang.String Protocol_AuthenticationRequest_Param
Protocol_AuthenticationRequest,
Constant Field Valuespublic static final java.lang.String Protocol_AuthenticationAcknowledge
Protocol_Hello,
Constant Field Valuespublic static final java.lang.String Protocol_AuthenticationAcknowledge2
Protocol_Hello,
Constant Field Valuespublic static final java.lang.String Protocol_AuthenticationInputCommit
public static final java.lang.String Protocol_AuthenticationInputOpen
public static final int AuthenticationStages
protected boolean useJSSE
protected int timeoutMs
protected SimpleKeyAgreement keyAgreement
protected byte[] myPublicKey
protected boolean dontWipeKeyAgreement
protected RemoteConnection connection
protected boolean keepConnected
connection,
#HostProtocolHandler(RemoteConnection, boolean, boolean)protected java.lang.String optionalParameter
protected java.io.OutputStreamWriter toRemote
protected java.io.InputStream fromRemote
protected int totalTransferSize
protected java.util.Vector presharedShortSecrets
Vector may contain multiple entries,
in this case each entry is assumed to be a 'candidate secret'.
protected byte[] remotePreAuthenticationMessage
| Constructor Detail |
|---|
public HostProtocolHandler(RemoteConnection con,
int timeoutMs,
boolean keepConnected,
boolean useJSSE)
con - The RemoteConnection to use for communication. It must already be
connected to the other side, but will be shut down and closed
before the protocol handler methods return, depending on the
parameter keepConnected. The reason for this asymmetry (the
connection must be connected by the caller, but is closed by
the methods of this class) lies in the asynchronicity: the
protocol handler methods are called in background threads
and must therefore dispose the objects before exiting.timeoutMs - The maximum duration in milliseconds that this authentication
protocol may take before it will abort with an AuthenticationFailed
exception. Set to -1 to disable the timeout.keepConnected - If set to true, the open connection con 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.
Even when set to true, the connection will still be closed
upon any protocol failure (e.g. I/O error or unparseable
messages).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.
public HostProtocolHandler(RemoteConnection con,
java.util.Vector presharedShortSecrets,
SimpleKeyAgreement permanentKeyAgreement,
int timeoutMs,
boolean keepConnected,
boolean useJSSE)
presharedShortSecrets - A list of secret, shared keys entered by the user
on both sides before any interaction takes place on the wireless
channel. This must remain secret until the protocol finishes
and must not be re-used.permanentKeyAgreement - The key agreement instance (i.e. private
and public Diffie-Hellman key pair) to be used. If set, it will
not be wiped on protocol end.
May be null, in which case a new, ephemeral key agreement
instance will be created during the protocol run.| Method Detail |
|---|
public void addProtocolCommandHandler(java.lang.String command,
ProtocolCommandHandler handler)
command - The command to react to.handler - The handler that will be called to handle the protocol
session when it is started with command.public boolean removeProtocolCommandHandler(java.lang.String command)
command - The command to stop reacting to.
public void setProtocolCommandHandlers(java.util.Hashtable handlers)
handlers - The list of command handlers to use. Keys must
be of type String, while values must be of type
ProtocolCommandHandler.
protected java.lang.String readLine()
throws java.io.IOException
java.io.IOException
protected void println(java.lang.String line)
throws java.io.IOException
java.io.IOException
protected java.lang.String getLine(java.lang.String expectedMsg,
RemoteConnection remote,
boolean allowOtherCommands)
throws java.io.IOException
expectedMsg - Gives the message that is expected to be received.remote - The remote socket. This is only needed for raising events
and is passed unmodified to the event method.allowOtherCommands - If true, then protocolCommandHandlers are checked when the
received word does not match expectedMsg.
java.io.IOException
protected java.lang.Object[] parseLine(java.lang.String line,
java.lang.String expectedMsg,
boolean[] isHexNumber,
java.lang.String[] expectedParts,
int numMandatoryParms,
RemoteConnection remote)
throws java.io.IOException
line - The complete line from the remote, including the command
prefix.expectedMsg - Gives the message that is expected to be received. This is
simply cut off because we assume getLine already checked for
this string to be present.remote - The remote socket. This is only needed for raising events
and is passed unmodified to the event method.isHexNumber - This array both determines the number of parameters to
try to decode and which of the parameters should be further
decoded from String objects to Hex-coded integers.expectedParts - If != null, then this array may contain parameters that are
expected to be a equal to the constant string passed in here.
All null elements are ignored.numMandatoryParms - The number of parameters that _must_ be found in line after
expectedMsg. It may be less than isHexNumber.length.
java.io.IOException
public static byte[] commitment(byte[] ownPublicKey,
boolean useJSSE)
throws InternalApplicationException
ownPublicKey - This side's public key for MA-DH.
InternalApplicationException
public static byte[] keyedHash(byte[] oobInput,
byte[] oobKey,
boolean useJSSE)
throws InternalApplicationException
InternalApplicationExceptionprotected void performAuthenticationProtocol(boolean serverSide)
serverSide - true for server side ("authenticator"), false for client side
("authenticatee")public byte[] getPreAuthenticationMessage()
public void setPreAuthenticationMessage(byte[] publicKeyCommitment)
publicKeyCommitment - The pre-authentication commitment to the
remote public key as returned by the other side's
getPreAuthenticationMessage() method and transmitted over
an authentic channel. This is highly important for security:
The pre-authentication commitment must be guaranteed to
have been created by the legitimate remote device and have not
been tampered with.public void startIncomingAuthenticationThread(boolean asynchronousCall)
asynchronousCall - When set to true, this method will perform the
protocol asynchronously an return immediately to the
caller (firing events later on from the other thread).
When set to false, this method will block until the
authentication protocol has been completed (events will
be fired from within the thread of the caller)
public static void startAuthenticationWith(RemoteConnection remote,
AuthenticationProgressHandler eventHandler,
SimpleKeyAgreement permanentKeyAgreementInstance,
java.util.Vector presharedShortSecrets,
byte[] remotePreAuthenticationMessage,
int timeoutMs,
boolean keepConnected,
java.lang.String optionalParameter,
boolean useJSSE)
throws java.io.IOException
remote - The remote connection to use for key agreement.eventHandler - The event handler that should be notified of authentication
events. Can be null (in which case no events are sent). If not
null, it will be registered with a new HostProtocolHandler
object before starting the authentication protocol so that it
is guaranteed that all events are posted to the event handler.presharedShortSecret - If a user has already entered the same short secret
key into both sides, it may be passed in this parameter to
avoid further authentication via out-of-band channel. It is
important this this must remain secret until the
protocol finishes and that it must not be re-used.timeoutMs - The maximum duration in milliseconds that this authentication
protocol may take before it will abort with an AuthenticationFailed
exception. Set to -1 to disable the timeout.keepConnected - When set to true, the connection passed into this method in
the form of the remote parameter is not closed on success but
passed to the authentation success event for further reuse.
Even if set to true, it will be closed when any protocol
failure occurs, though, because this most probably means that
the connection itself suffers from I/O errors or that it is
being tampered with.optionalParameter - If not null, this string will be passed to the server in the
authentication request message. Both the server and the client
will then subsequently forward this string in their
authentication success message. This parameter must be
encoded in 7-bit ASCII and must not contain spaces.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.
java.io.IOException
public static void startAuthenticationWith(RemoteConnection remote,
AuthenticationProgressHandler eventHandler,
int timeoutMs,
boolean keepConnected,
java.lang.String optionalParameter,
boolean useJSSE)
throws java.io.IOException
java.io.IOExceptionstartAuthenticationWith
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||