java.lang.Object
com.southernstorm.noise.protocol.HandshakeState
- All Implemented Interfaces:
Destroyable, Cloneable
Interface to a Noise handshake.
Field Summary
Modifier and TypeFieldDescriptionprivate intThe next action allowed in the pattern.static final intThe handshake is complete and the data session ciphers have been split() out successfully.private static final byte[]The empty prologue used when none is set.static final intThe handshake has failed due to some kind of error.private static final intFallback is possible from this pattern (two-way, ends in "K").private static final intEphemeral key for fallback pre-message has been provided.static final intEnumerated value that indicates that the handshake object is handling the initiator role.private booleanTrue once the state was destroyed.private final booleanTrue for the initiator of the handshake.private static final intThe local public key is part of the pre-message.private static final intLocal static keypair is required for the handshake.private DHStateOur ephemeral key pair for the handshake.private DHStateOur hybrid key pair for the handshake.private DHStateOur static key pair for the handshake.static final intNo action is required of the application yet because the handshake has not started.private final short[]The token list of the handshake pattern.static final StringRatchetprivate static final StringHybrid Basestatic final StringPATTERN_ID_IKHFS_1024.static final StringHybrid Ratchetstatic final StringPATTERN_ID_IKHFS_768.static final StringTunnelsstatic final Stringsame as N but no post-mixHash neededstatic final StringNTCP2static final StringSSU2private static final StringName of the I2P ratchet handshake pattern.static final StringPATTERN_ID_XKHFS_1024.static final StringHybrid NTCP2static final StringHybrid SSU2static final StringPATTERN_ID_XKHFS_768.static final StringPATTERN_ID_XKHFS_768_SSU2.private final NoiseInit.PatternIDThe handshake pattern being run.private intPosition within the pattern tokens.static final StringNTCP2static final StringprotocolName10.static final StringHybrid SSU2static final StringprotocolName12.static final StringRatchetstatic final StringTunnelsstatic final StringSSU2static final StringHybrid Ratchetstatic final StringprotocolName6.static final StringprotocolName7.static final StringHybrid NTCP2static final StringprotocolName9.private static final intPre-shared key is required for the handshake.static final intThe HandshakeState expects the application to read the next message payload from the handshake.private static final intThe remote public key is part of the pre-message.private static final intRemote static keypai is required for the handshake.private DHStateThe peer's ephemeral key, once received.private DHStateThe peer's hybrid key, once received.private DHStateThe peer's static key, once received.private final intThe key types the pattern requires.static final intEnumerated value that indicates that the handshake object is handling the responder role.static final intThe handshake is over and the application is expected to call split() and begin data session communications.private static final String[]I2P for debuggingprivate final SymmetricStateThe symmetric state carrying the keys.private booleanTrue once the state was cloned for writing.static final intThe HandshakeState expects the application to write the next message payload for the handshake.Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedCopy constructor for cloningHandshakeState(NoiseInit.PatternID patternId, int role, KeyFactory xdh) Creates a new Noise handshake.HandshakeState(NoiseInit.PatternID patternId, int role, KeyFactory xdh, KeyFactory hdh) Creates a new Noise handshake.Method Summary
Modifier and TypeMethodDescriptionclone()I2P Must be called before both eph.private static intcomputeRequirements(short flags, String prefix, int role, boolean isFallback) Computes the requirements for a handshake.voiddestroy()Marks this state destroyed and destroys the symmetric state and keys.intGets the next action that the application should perform for the handshake part of the protocol.byte[]I2P for getting chaining key for siphash calcbyte[]Gets the current value of the handshake hash.Gets the keypair object for the local ephemeral key.Gets the keypair object for the local hybrid key.Gets the keypair object for the local static key.Gets the name of the Noise protocol.Gets the keypair object for the remote hybrid key.Gets the public key object for the remote static key.intgetRole()Gets the role for this handshake.booleanDetermine if this handshake has already been configured with a local static key.booleanDetermine if this handshake has already been configured with a remote static key.private voidMixes the result of a Diffie-Hellman calculation into the chaining key.voidmixHash(byte[] data, int offset, int length) I2P for mixing in padding in messages 1 and 2booleanDetermine if this handshake requires a local static key.booleanDetermine if this handshake requires a remote static key.intreadMessage(byte[] message, int messageOffset, int messageLength, byte[] payload, int payloadOffset) Reads a message payload during the handshake.split()Splits the transport encryption CipherState objects out of this HandshakeState object once the handshake completes.split(byte[] secondaryKey, int offset, int length) Splits the transport encryption CipherState objects out of this HandshakeObject after mixing in a secondary symmetric key.voidstart()Starts the handshake running.toString()I2P debugintwriteMessage(byte[] message, int messageOffset, byte[] payload, int payloadOffset, int payloadLength) Writes a message payload during the handshake.
Field Details
symmetric
The symmetric state carrying the keys.isInitiator
private final boolean isInitiatorTrue for the initiator of the handshake.localKeyPair
Our static key pair for the handshake.localEphemeral
Our ephemeral key pair for the handshake.localHybrid
Our hybrid key pair for the handshake.remotePublicKey
The peer's static key, once received.remoteEphemeral
The peer's ephemeral key, once received.remoteHybrid
The peer's hybrid key, once received.action
private int actionThe next action allowed in the pattern.requirements
private final int requirementsThe key types the pattern requires.patternIndex
private int patternIndexPosition within the pattern tokens.wasCloned
private boolean wasClonedTrue once the state was cloned for writing.isDestroyed
private boolean isDestroyedTrue once the state was destroyed.INITIATOR
public static final int INITIATOREnumerated value that indicates that the handshake object is handling the initiator role.- See Also:
RESPONDER
public static final int RESPONDEREnumerated value that indicates that the handshake object is handling the responder role.- See Also:
NO_ACTION
public static final int NO_ACTIONNo action is required of the application yet because the handshake has not started.- See Also:
WRITE_MESSAGE
public static final int WRITE_MESSAGEThe HandshakeState expects the application to write the next message payload for the handshake.- See Also:
READ_MESSAGE
public static final int READ_MESSAGEThe HandshakeState expects the application to read the next message payload from the handshake.- See Also:
FAILED
public static final int FAILEDThe handshake has failed due to some kind of error.- See Also:
SPLIT
public static final int SPLITThe handshake is over and the application is expected to call split() and begin data session communications.- See Also:
COMPLETE
public static final int COMPLETEThe handshake is complete and the data session ciphers have been split() out successfully.- See Also:
STATE_NAMES
I2P for debuggingLOCAL_REQUIRED
private static final int LOCAL_REQUIREDLocal static keypair is required for the handshake.- See Also:
REMOTE_REQUIRED
private static final int REMOTE_REQUIREDRemote static keypai is required for the handshake.- See Also:
PSK_REQUIRED
private static final int PSK_REQUIREDPre-shared key is required for the handshake.- See Also:
FALLBACK_PREMSG
private static final int FALLBACK_PREMSGEphemeral key for fallback pre-message has been provided.- See Also:
LOCAL_PREMSG
private static final int LOCAL_PREMSGThe local public key is part of the pre-message.- See Also:
REMOTE_PREMSG
private static final int REMOTE_PREMSGThe remote public key is part of the pre-message.- See Also:
FALLBACK_POSSIBLE
private static final int FALLBACK_POSSIBLEFallback is possible from this pattern (two-way, ends in "K").- See Also:
protocolName
protocolName2
protocolName3
protocolName4
protocolName5
protocolName6
protocolName7
protocolName8
protocolName9
protocolName10
protocolName11
protocolName12
patternId
The handshake pattern being run.PATTERN_ID_XK
PATTERN_ID_IK
PATTERN_ID_N
PATTERN_ID_N_NO_RESPONSE
same as N but no post-mixHash needed- See Also:
PATTERN_ID_XK_SSU2
PATTERN_ID_IKHFS
PATTERN_ID_XKHFS
Name of the I2P ratchet handshake pattern.- See Also:
PATTERN_ID_IKHFS_512
PATTERN_ID_IKHFS_768
PATTERN_ID_IKHFS_1024
PATTERN_ID_IKHFS_1024.- See Also:
PATTERN_ID_XKHFS_512
PATTERN_ID_XKHFS_768
PATTERN_ID_XKHFS_1024
PATTERN_ID_XKHFS_1024.- See Also:
PATTERN_ID_XKHFS_512_SSU2
PATTERN_ID_XKHFS_768_SSU2
PATTERN_ID_XKHFS_768_SSU2.- See Also:
pattern
private final short[] patternThe token list of the handshake pattern.emptyPrologue
private static final byte[] emptyPrologueThe empty prologue used when none is set.
Constructor Details
HandshakeState
public HandshakeState(NoiseInit.PatternID 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 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
public HandshakeState(NoiseInit.PatternID patternId, int role, KeyFactory xdh, KeyFactory hdh) 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 keyshdh- 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.
HandshakeState
Copy constructor for cloning- Parameters:
o- the state to clone, whose symmetric state and DH key pairs are copied- Throws:
CloneNotSupportedException- if the handshake has already split or completed
Method Details
getProtocolName
getRole
public int getRole()Gets the role for this handshake.- Returns:
- The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.
getLocalKeyPair
Gets the keypair object for the local static key.- Returns:
- The keypair, or null if a local static key is not required.
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.
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
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.
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.
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.
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
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.
mixDH
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:
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:
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
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()Marks this state destroyed and destroys the symmetric state and keys.- Specified by:
destroyin interfaceDestroyable
computeRequirements
Computes the requirements for a handshake.- Parameters:
flags- The flags from the handshake's pattern.prefix- The prefix from the protocol name; typically "Noise" or "NoisePSK".role- The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.isFallback- Set to true if we need the requirements for a fallback pattern; false for a regular pattern.- Returns:
- The set of requirements for the handshake.
mixHash
public void mixHash(byte[] data, int offset, int length) I2P for mixing in padding in messages 1 and 2- Parameters:
data- the buffer holding the bytes to mix into the handshake hashoffset- index into data of the first byte to mix inlength- count of bytes to mix in starting at offset
getChainingKey
public byte[] getChainingKey()I2P for getting chaining key for siphash calc- Returns:
- a copy of the current chaining key, not the internal array
clone
I2P Must be called before both eph. keys set.- Overrides:
clonein classObject- Throws:
CloneNotSupportedException
toString