Package com.southernstorm.noise.protocol
Class HandshakeState
- java.lang.Object
-
- com.southernstorm.noise.protocol.HandshakeState
-
- All Implemented Interfaces:
Destroyable
,Cloneable
public class HandshakeState extends Object implements Destroyable, Cloneable
Interface to a Noise handshake.
-
-
Field Summary
Fields Modifier and Type Field 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 String
PATTERN_ID_IK
static String
PATTERN_ID_N
static String
PATTERN_ID_N_NO_RESPONSE
same as N but no post-mixHash neededstatic String
PATTERN_ID_XK
static String
protocolName
static String
protocolName2
static String
protocolName3
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 Summary
Constructors Modifier Constructor Description protected
HandshakeState(HandshakeState o)
Copy constructor for cloningHandshakeState(String patternId, int role, KeyFactory xdh)
Creates a new Noise handshake.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description HandshakeState
clone()
I2P Must be called before both eph.void
destroy()
Destroys all sensitive state in the current object.int
getAction()
Gets the next action that the application should perform for the handshake part of the protocol.byte[]
getChainingKey()
I2P for getting chaining key for siphash calcbyte[]
getHandshakeHash()
Gets the current value of the handshake hash.DHState
getLocalEphemeralKeyPair()
Gets the keypair object for the local ephemeral key.DHState
getLocalKeyPair()
Gets the keypair object for the local static key.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
hasRemotePublicKey()
Determine if this handshake has already been configured with a remote static key.void
mixHash(byte[] data, int offset, int length)
I2P for mixing in padding in messages 1 and 2boolean
needsLocalKeyPair()
Determine if this handshake requires a local static key.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.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.String
toString()
I2P debugint
writeMessage(byte[] message, int messageOffset, byte[] payload, int payloadOffset, int payloadLength)
Writes a message payload during the handshake.
-
-
-
Field Detail
-
INITIATOR
public static final int INITIATOR
Enumerated value that indicates that the handshake object is handling the initiator role.- See Also:
- Constant Field Values
-
RESPONDER
public static final int RESPONDER
Enumerated value that indicates that the handshake object is handling the responder role.- See Also:
- Constant Field Values
-
NO_ACTION
public static final int NO_ACTION
No action is required of the application yet because the handshake has not started.- See Also:
- Constant Field Values
-
WRITE_MESSAGE
public static final int WRITE_MESSAGE
The HandshakeState expects the application to write the next message payload for the handshake.- See Also:
- Constant Field Values
-
READ_MESSAGE
public static final int READ_MESSAGE
The HandshakeState expects the application to read the next message payload from the handshake.- See Also:
- Constant Field Values
-
FAILED
public static final int FAILED
The handshake has failed due to some kind of error.- See Also:
- Constant Field Values
-
SPLIT
public static final int SPLIT
The handshake is over and the application is expected to call split() and begin data session communications.- See Also:
- Constant Field Values
-
COMPLETE
public static final int COMPLETE
The handshake is complete and the data session ciphers have been split() out successfully.- See Also:
- Constant Field Values
-
protocolName
public static final String protocolName
- See Also:
- Constant Field Values
-
protocolName2
public static final String protocolName2
- See Also:
- Constant Field Values
-
protocolName3
public static final String protocolName3
- See Also:
- Constant Field Values
-
PATTERN_ID_XK
public static final String PATTERN_ID_XK
- See Also:
- Constant Field Values
-
PATTERN_ID_IK
public static final String PATTERN_ID_IK
- See Also:
- Constant Field Values
-
PATTERN_ID_N
public static final String PATTERN_ID_N
- See Also:
- Constant Field Values
-
PATTERN_ID_N_NO_RESPONSE
public static final String PATTERN_ID_N_NO_RESPONSE
same as N but no post-mixHash needed- See Also:
- Constant Field Values
-
-
Constructor Detail
-
HandshakeState
public HandshakeState(String patternId, int role, KeyFactory xdh) throws NoSuchAlgorithmException
Creates a new Noise handshake. Noise protocol name is hardcoded.- Parameters:
patternId
- XK, IK, or Nrole
- The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.xdh
- The key pair factory for ephemeral keys- Throws:
IllegalArgumentException
- The protocolName is not formatted correctly, or the role is not recognized.NoSuchAlgorithmException
- One of the cryptographic algorithms that is specified in the protocolName is not supported.
-
HandshakeState
protected HandshakeState(HandshakeState o) throws CloneNotSupportedException
Copy constructor for cloning- Throws:
CloneNotSupportedException
- Since:
- 0.9.44
-
-
Method Detail
-
getProtocolName
public String getProtocolName()
Gets the name of the Noise protocol.- Returns:
- The protocol name.
-
getRole
public int getRole()
Gets the role for this handshake.- Returns:
- The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.
-
getLocalKeyPair
public DHState getLocalKeyPair()
Gets the keypair object for the local static key.- Returns:
- The keypair, or null if a local static key is not required.
-
getLocalEphemeralKeyPair
public DHState getLocalEphemeralKeyPair()
Gets the keypair object for the local ephemeral key. I2P- Returns:
- The keypair, or null if a local ephemeral key is not required or has not been generated.
- Since:
- 0.9.44
-
needsLocalKeyPair
public boolean needsLocalKeyPair()
Determine if this handshake requires a local static key.- Returns:
- true if a local static key is needed; false if not. If the local static key has already been set, then this function will return false.
-
hasLocalKeyPair
public boolean hasLocalKeyPair()
Determine if this handshake has already been configured with a local static key.- Returns:
- true if the local static key has been configured; false if not.
-
getRemotePublicKey
public DHState getRemotePublicKey()
Gets the public key object for the remote static key.- Returns:
- The public key, or null if a remote static key is not required.
-
needsRemotePublicKey
public boolean needsRemotePublicKey()
Determine if this handshake requires a remote static key.- Returns:
- true if a remote static key is needed; false if not. If the remote static key has already been set, then this function will return false.
-
hasRemotePublicKey
public boolean hasRemotePublicKey()
Determine if this handshake has already been configured with a remote static key.- Returns:
- true if the remote static key has been configured; false if not.
-
start
public void start()
Starts the handshake running. This function is called after all of the handshake parameters have been provided to the HandshakeState object. This function should be followed by calls to writeMessage() or readMessage() to process the handshake messages. The getAction() function indicates the action to take next.- Throws:
IllegalStateException
- The handshake has already started, or one or more of the required parameters has not been supplied.UnsupportedOperationException
- An attempt was made to start a fallback handshake pattern without first calling fallback() on a previous handshake.- See Also:
getAction()
,writeMessage(byte[], int, byte[], int, int)
,see #fallback()
-
getAction
public int getAction()
Gets the next action that the application should perform for the handshake part of the protocol.- Returns:
- One of HandshakeState.NO_ACTION, HandshakeState.WRITE_MESSAGE, HandshakeState.READ_MESSAGE, HandshakeState.SPLIT, or HandshakeState.FAILED.
-
writeMessage
public int writeMessage(byte[] message, int messageOffset, byte[] payload, int payloadOffset, int payloadLength) throws ShortBufferException
Writes a message payload during the handshake.- Parameters:
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.- Returns:
- The length of the data written to the message buffer.
- Throws:
IllegalStateException
- The action is not WRITE_MESSAGE.IllegalArgumentException
- The payload is null, but payloadOffset or payloadLength is non-zero.ShortBufferException
- The message buffer does not have enough space for the handshake message.- See Also:
getAction()
,readMessage(byte[], int, int, byte[], int)
-
readMessage
public int readMessage(byte[] message, int messageOffset, int messageLength, byte[] payload, int payloadOffset) throws ShortBufferException, BadPaddingException
Reads a message payload during the handshake.- Parameters:
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.- Returns:
- The length of the payload.
- Throws:
IllegalStateException
- The action is not READ_MESSAGE.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.BadPaddingException
- A MAC value in the message failed to verify.- See Also:
getAction()
,writeMessage(byte[], int, byte[], int, int)
-
split
public CipherStatePair split()
Splits the transport encryption CipherState objects out of this HandshakeState object once the handshake completes.- Returns:
- The pair of ciphers for sending and receiving.
- Throws:
IllegalStateException
- The action is not SPLIT.
-
split
public 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.- Parameters:
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.- Returns:
- The pair of ciphers for sending and receiving.
- Throws:
IllegalStateException
- The action is not SPLIT.IllegalArgumentException
- The length is not 0 or 32.
-
getHandshakeHash
public byte[] getHandshakeHash()
Gets the current value of the handshake hash.- Returns:
- The handshake hash. This must not be modified by the caller.
- Throws:
IllegalStateException
- The action is not SPLIT or COMPLETE.
-
destroy
public void destroy()
Description copied from interface:Destroyable
Destroys all sensitive state in the current object.- Specified by:
destroy
in interfaceDestroyable
-
mixHash
public void mixHash(byte[] data, int offset, int length)
I2P for mixing in padding in messages 1 and 2
-
getChainingKey
public byte[] getChainingKey()
I2P for getting chaining key for siphash calc- Returns:
- a copy
-
clone
public HandshakeState clone() throws CloneNotSupportedException
I2P Must be called before both eph. keys set.- Overrides:
clone
in classObject
- Throws:
CloneNotSupportedException
- Since:
- 0.9.44
-
-