public class HandshakeState extends java.lang.Object implements Destroyable
Modifier and Type | Field and Description |
---|---|
static int |
COMPLETE
The handshake is complete and the data session ciphers
have been split() out successfully.
|
static int |
FAILED
The handshake has failed due to some kind of error.
|
static int |
INITIATOR
Enumerated value that indicates that the handshake object
is handling the initiator role.
|
static int |
NO_ACTION
No action is required of the application yet because the
handshake has not started.
|
static int |
READ_MESSAGE
The HandshakeState expects the application to read the
next message payload from the handshake.
|
static int |
RESPONDER
Enumerated value that indicates that the handshake object
is handling the responder role.
|
static int |
SPLIT
The handshake is over and the application is expected to call
split() and begin data session communications.
|
static int |
WRITE_MESSAGE
The HandshakeState expects the application to write the
next message payload for the handshake.
|
Constructor and Description |
---|
HandshakeState(java.lang.String protocolName,
int role)
Creates a new Noise handshake.
|
Modifier and Type | Method and Description |
---|---|
void |
destroy()
Destroys all sensitive state in the current object.
|
void |
fallback()
Falls back to the "XXfallback" handshake pattern.
|
void |
fallback(java.lang.String patternName)
Falls back to another handshake pattern.
|
int |
getAction()
Gets the next action that the application should perform for
the handshake part of the protocol.
|
DHState |
getFixedEphemeralKey()
Gets the DHState object containing a fixed local ephemeral
key value for this handshake.
|
DHState |
getFixedHybridKey()
Gets the DHState object containing a fixed local hybrid
key value for this handshake.
|
byte[] |
getHandshakeHash()
Gets the current value of the handshake hash.
|
DHState |
getLocalKeyPair()
Gets the keypair object for the local static key.
|
java.lang.String |
getProtocolName()
Gets the name of the Noise protocol.
|
DHState |
getRemotePublicKey()
Gets the public key object for the remote static key.
|
int |
getRole()
Gets the role for this handshake.
|
boolean |
hasLocalKeyPair()
Determine if this handshake has already been configured
with a local static key.
|
boolean |
hasPreSharedKey()
Determine if this object has already been configured with a
pre-shared key.
|
boolean |
hasRemotePublicKey()
Determine if this handshake has already been configured
with a remote static key.
|
boolean |
needsLocalKeyPair()
Determine if this handshake requires a local static key.
|
boolean |
needsPreSharedKey()
Determine if this handshake needs a pre-shared key value
and one has not been configured yet.
|
boolean |
needsRemotePublicKey()
Determine if this handshake requires a remote static key.
|
int |
readMessage(byte[] message,
int messageOffset,
int messageLength,
byte[] payload,
int payloadOffset)
Reads a message payload during the handshake.
|
void |
setPreSharedKey(byte[] key,
int offset,
int length)
Sets the pre-shared key for this handshake.
|
void |
setPrologue(byte[] prologue,
int offset,
int length)
Sets the prologue for this handshake.
|
CipherStatePair |
split()
Splits the transport encryption CipherState objects out of
this HandshakeState object once the handshake completes.
|
CipherStatePair |
split(byte[] secondaryKey,
int offset,
int length)
Splits the transport encryption CipherState objects out of
this HandshakeObject after mixing in a secondary symmetric key.
|
void |
start()
Starts the handshake running.
|
int |
writeMessage(byte[] message,
int messageOffset,
byte[] payload,
int payloadOffset,
int payloadLength)
Writes a message payload during the handshake.
|
public static final int INITIATOR
public static final int RESPONDER
public static final int NO_ACTION
public static final int WRITE_MESSAGE
public static final int READ_MESSAGE
public static final int FAILED
public static final int SPLIT
public static final int COMPLETE
public HandshakeState(java.lang.String protocolName, int role) throws java.security.NoSuchAlgorithmException
protocolName
- The name of the Noise protocol.role
- The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.java.lang.IllegalArgumentException
- The protocolName is not
formatted correctly, or the role is not recognized.java.security.NoSuchAlgorithmException
- One of the cryptographic algorithms
that is specified in the protocolName is not supported.public java.lang.String getProtocolName()
public int getRole()
public boolean needsPreSharedKey()
public boolean hasPreSharedKey()
public void setPreSharedKey(byte[] key, int offset, int length)
key
- Buffer containing the pre-shared key value.offset
- Offset into the buffer of the first byte of the key.length
- The length of the pre-shared key, which must be 32.java.lang.IllegalArgumentException
- The length is not 32.java.lang.UnsupportedOperationException
- Pre-shared keys are not
supported for this handshake type.java.lang.IllegalStateException
- The handshake has already started,
so the pre-shared key can no longer be set.public void setPrologue(byte[] prologue, int offset, int length)
prologue
- Buffer containing the prologue value.offset
- Offset into the buffer of the first byte of the prologue.length
- The length of the prologue in bytes.java.lang.IllegalStateException
- The handshake has already started,
so the prologue can no longer be set.public DHState getLocalKeyPair()
public boolean needsLocalKeyPair()
public boolean hasLocalKeyPair()
public DHState getRemotePublicKey()
public boolean needsRemotePublicKey()
public boolean hasRemotePublicKey()
public DHState getFixedEphemeralKey()
public DHState getFixedHybridKey()
public void start()
java.lang.IllegalStateException
- The handshake has already started, or one or
more of the required parameters has not been supplied.java.lang.UnsupportedOperationException
- An attempt was made to start a
fallback handshake pattern without first calling fallback() on a
previous handshake.getAction()
,
writeMessage(byte[], int, byte[], int, int)
,
readMessage(byte[], int, int, byte[], int)
,
fallback()
public void fallback() throws java.security.NoSuchAlgorithmException
java.lang.UnsupportedOperationException
- The current handshake pattern
is not compatible with "XXfallback".java.lang.IllegalStateException
- The previous protocol has not started
or it has not reached the fallback position yet.java.security.NoSuchAlgorithmException
- One of the cryptographic algorithms
that is specified in the new protocolName is not supported.start()
public void fallback(java.lang.String patternName) throws java.security.NoSuchAlgorithmException
patternName
- The name of the pattern to fall back to;
e.g. "XXfallback", "NXfallback", etc.
This function resets a HandshakeState object with the original
handshake pattern, and converts it into an object with the new handshake
patternName. Information from the previous session such as the local
keypair, the initiator's ephemeral key, the prologue value, and the
pre-shared key, are passed to the new session.
Once the fallback has been initiated, the application can set
new values for the handshake parameters if the values from the
previous session do not apply. For example, the application may
use a different prologue for the fallback than for the original
session.
After setting any new parameters, the application calls start()
again to restart the handshake from where it left off before the fallback.
The new pattern may have greater key requirements than the original;
for example changing from "NK" from "XXfallback" requires that the
initiator's static public key be set. The application is responsible for
setting any extra keys before calling start().
Note that this function reverses the roles of initiator and responder.java.lang.UnsupportedOperationException
- The current handshake pattern
is not compatible with the patternName, or patternName is not a
fallback pattern.java.lang.IllegalStateException
- The previous protocol has not started
or it has not reached the fallback position yet.java.security.NoSuchAlgorithmException
- One of the cryptographic algorithms
that is specified in the new protocolName is not supported.start()
public int getAction()
public int writeMessage(byte[] message, int messageOffset, byte[] payload, int payloadOffset, int payloadLength) throws javax.crypto.ShortBufferException
message
- The buffer that will be populated with the
handshake packet to be written to the transport.messageOffset
- First offset within the message buffer
to be populated.payload
- Buffer containing the payload to add to the
handshake message; can be null if there is no payload.payloadOffset
- Offset into the payload buffer of the
first payload buffer.payloadLength
- Length of the payload in bytes.java.lang.IllegalStateException
- The action is not WRITE_MESSAGE.java.lang.IllegalArgumentException
- The payload is null, but
payloadOffset or payloadLength is non-zero.javax.crypto.ShortBufferException
- The message buffer does not have
enough space for the handshake message.getAction()
,
readMessage(byte[], int, int, byte[], int)
public int readMessage(byte[] message, int messageOffset, int messageLength, byte[] payload, int payloadOffset) throws javax.crypto.ShortBufferException, javax.crypto.BadPaddingException
message
- Buffer containing the incoming handshake
that was read from the transport.messageOffset
- Offset of the first message byte.messageLength
- The length of the incoming message.payload
- Buffer that will be populated with the message payload.payloadOffset
- Offset of the first byte in the
payload buffer to be populated with payload data.java.lang.IllegalStateException
- The action is not READ_MESSAGE.javax.crypto.ShortBufferException
- The message buffer does not have
sufficient bytes for a valid message or the payload buffer does
not have enough space for the decrypted payload.javax.crypto.BadPaddingException
- A MAC value in the message failed
to verify.getAction()
,
writeMessage(byte[], int, byte[], int, int)
public CipherStatePair split()
java.lang.IllegalStateException
- The action is not SPLIT.public CipherStatePair split(byte[] secondaryKey, int offset, int length)
secondaryKey
- The buffer containing the secondary key.offset
- The offset of the first secondary key byte.length
- The length of the secondary key in bytes, which
must be either 0 or 32.java.lang.IllegalStateException
- The action is not SPLIT.java.lang.IllegalArgumentException
- The length is not 0 or 32.public byte[] getHandshakeHash()
java.lang.IllegalStateException
- The action is not SPLIT or COMPLETE.public void destroy()
Destroyable
destroy
in interface Destroyable