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 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 String` | `PATTERN_ID_IK` Ratchet
    `static String` | `PATTERN_ID_IKHFS_1024`
    `static String` | `PATTERN_ID_IKHFS_512` Hybrid Ratchet
    `static String` | `PATTERN_ID_IKHFS_768`
    `static String` | `PATTERN_ID_N` Tunnels
    `static String` | `PATTERN_ID_N_NO_RESPONSE` same as N but no post-mixHash needed
    `static String` | `PATTERN_ID_XK` NTCP2
    `static String` | `PATTERN_ID_XK_SSU2` SSU2
    `static String` | `protocolName` NTCP2
    `static String` | `protocolName2` Ratchet
    `static String` | `protocolName3` Tunnels
    `static String` | `protocolName4` SSU2
    `static String` | `protocolName5` Hybrid Ratchet
    `static String` | `protocolName6`
    `static String` | `protocolName7`
    `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 and Description
    --- | ---
    `protected` | `HandshakeState(HandshakeState o)` Copy constructor for cloning
    `` | `HandshakeState(String patternId, int role, KeyFactory xdh)` Creates a new Noise handshake.
    `` | `HandshakeState(String patternId, int role, KeyFactory xdh, KeyFactory hdh)` Creates a new Noise handshake.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and 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 calc
    `byte[]` | `getHandshakeHash()` Gets the current value of the handshake hash.
    `DHState` | `getLocalEphemeralKeyPair()` Gets the keypair object for the local ephemeral key.
    `DHState` | `getLocalHybridKeyPair()` Gets the keypair object for the local hybrid key.
    `DHState` | `getLocalKeyPair()` Gets the keypair object for the local static key.
    `String` | `getProtocolName()` Gets the name of the Noise protocol.
    `DHState` | `getRemoteHybridKeyPair()` Gets the keypair object for the remote hybrid key.
    `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 2
    `boolean` | `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 debug
    `int` | `writeMessage(byte[] message, int messageOffset, byte[] payload, int payloadOffset, int payloadLength)` Writes a message payload during the handshake.

    - ### Methods inherited from class java.lang.Object

      `equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### 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

    - #### FAILED

          public static final int FAILED

      The handshake has failed due to some kind of error.
      See Also:
        Constant Field Values

    - #### INITIATOR

          public static final int INITIATOR

      Enumerated value that indicates that the handshake object is handling the initiator 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

    - #### PATTERN_ID_IK

          public static final String PATTERN_ID_IK

      Ratchet
      See Also:
        Constant Field Values

    - #### PATTERN_ID_IKHFS_1024

          public static final String PATTERN_ID_IKHFS_1024

      See Also:
        Constant Field Values

    - #### PATTERN_ID_IKHFS_512

          public static final String PATTERN_ID_IKHFS_512

      Hybrid Ratchet
      See Also:
        Constant Field Values

    - #### PATTERN_ID_IKHFS_768

          public static final String PATTERN_ID_IKHFS_768

      See Also:
        Constant Field Values

    - #### PATTERN_ID_N

          public static final String PATTERN_ID_N

      Tunnels
      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

    - #### PATTERN_ID_XK

          public static final String PATTERN_ID_XK

      NTCP2
      See Also:
        Constant Field Values

    - #### PATTERN_ID_XK_SSU2

          public static final String PATTERN_ID_XK_SSU2

      SSU2
      See Also:
        Constant Field Values

    - #### protocolName

          public static final String protocolName

      NTCP2
      See Also:
        Constant Field Values

    - #### protocolName2

          public static final String protocolName2

      Ratchet
      See Also:
        Constant Field Values

    - #### protocolName3

          public static final String protocolName3

      Tunnels
      See Also:
        Constant Field Values

    - #### protocolName4

          public static final String protocolName4

      SSU2
      See Also:
        Constant Field Values

    - #### protocolName5

          public static final String protocolName5

      Hybrid Ratchet
      See Also:
        Constant Field Values

    - #### protocolName6

          public static final String protocolName6

      See Also:
        Constant Field Values

    - #### protocolName7

          public static final String protocolName7

      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

    - #### RESPONDER

          public static final int RESPONDER

      Enumerated value that indicates that the handshake object is handling the responder role.
      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

    - #### 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

  - ### Constructor Detail

    - #### HandshakeState

          protected HandshakeState(HandshakeState o)
                            throws CloneNotSupportedException

      Copy constructor for cloning
      Throws:
        `CloneNotSupportedException`

    - #### HandshakeState

          public HandshakeState(String patternId,
                                int role,
                                KeyFactory xdh)
                         throws NoSuchAlgorithmException

      Creates a new Noise handshake. Noise protocol name is hardcoded. Not for PQ Alice side.
      Parameters:
        `patternId` - XK, IK, or N
        `role` - 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

          public HandshakeState(String patternId,
                                int role,
                                KeyFactory xdh,
                                KeyFactory hdh)
                         throws NoSuchAlgorithmException

      Creates a new Noise handshake. Noise protocol name is hardcoded.
      Parameters:
        `patternId` - XK, IK, or N
        `role` - The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.
        `xdh` - The key pair factory for ephemeral keys
        `hdh` - The key pair factory for hybrid keys, Alice side only, or null for Bob or non-hybrid
      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.

  - ### Method Detail

    - #### clone

          public HandshakeState clone()
                               throws CloneNotSupportedException

      I2P Must be called before both eph. keys set.
      Overrides:
        `clone` in class `Object`
      Throws:
        `CloneNotSupportedException`

    - #### destroy

          public void destroy()

      Description copied from interface: `Destroyable`
      Destroys all sensitive state in the current object.
      Specified by:
        `destroy` in interface `Destroyable`

    - #### 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.

    - #### getChainingKey

          public byte[] getChainingKey()

      I2P for getting chaining key for siphash calc
      Returns:
        a copy

    - #### 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.

    - #### 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.

    - #### getLocalHybridKeyPair

          public DHState getLocalHybridKeyPair()

      Gets the keypair object for the local hybrid key. I2P
      Returns:
        The keypair, or null if a local hybrid key is not required or has not been generated.

    - #### 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.

    - #### getProtocolName

          public String getProtocolName()

      Gets the name of the Noise protocol.
      Returns:
        The protocol name.

    - #### getRemoteHybridKeyPair

          public DHState getRemoteHybridKeyPair()

      Gets the keypair object for the remote hybrid key. I2P
      Returns:
        The keypair, or null if a remote hybrid key is not required or has not been generated.

    - #### 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.

    - #### getRole

          public int getRole()

      Gets the role for this handshake.
      Returns:
        The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.

    - #### 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.

    - #### 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.

    - #### mixHash

          public void mixHash(byte[] data,
                              int offset,
                              int length)

      I2P for mixing in padding in messages 1 and 2

    - #### 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.

    - #### 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.

    - #### readMessage

          public int readMessage(byte[] message,
                                 int messageOffset,
                                 int messageLength,
                                 byte[] payload,
                                 int payloadOffset)
                          throws ShortBufferException,
                                 BadPaddingException

      Reads a message payload during the handshake. Payload (plaintext) and message (encrypted) may be in the same buffer and have the same offset.
      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.

    - #### 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()`

    - #### toString

          public String toString()

      I2P debug
      Overrides:
        `toString` in class `Object`

    - #### writeMessage

          public int writeMessage(byte[] message,
                                  int messageOffset,
                                  byte[] payload,
                                  int payloadOffset,
                                  int payloadLength)
                           throws ShortBufferException

      Writes a message payload during the handshake. Payload (plaintext) and message (encrypted) may be in the same buffer if the payload if offset enough past the message offset to leave room for the key(s) and/or MAC. For 32 byte keys and 16 byte MACs, if message == payload, payloadOffset must be at least this much greater than messageOffset: XK: Message 1: 32; message 2: 32; message 3: 48 IK: Message 1: 80; message 2: 48 N: Message 1: 32
      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)`