lib/noise/state/handshake_state.rb in noise-ruby-0.7.4 vs lib/noise/state/handshake_state.rb in noise-ruby-0.8.4
- old
+ new
@@ -16,27 +16,24 @@
#
# message_patterns: A sequence of message patterns.
# Each message pattern is a sequence of tokens from the set ("e", "s", "ee", "es", "se", "ss").
class HandshakeState
attr_reader :message_patterns, :symmetric_state
- attr_reader :s, :rs
+ attr_reader :s, :rs, :e, :re
- def initialize(connection, protocol, initiator, prologue, keypairs)
+ def initialize(connection, protocol, initiator, prologue, local_keypairs, remote_keys)
@connection = connection
@protocol = protocol
@symmetric_state = SymmetricState.new
@symmetric_state.initialize_symmetric(@protocol, connection)
@symmetric_state.mix_hash(prologue)
@initiator = initiator
- @s = keypairs[:s]
- @e = keypairs[:e]
- @rs = keypairs[:rs]
- @re = keypairs[:re]
+ @s = local_keypairs[:s]
+ @e = local_keypairs[:e]
+ @rs = remote_keys[:rs]
+ @re = remote_keys[:re]
- # TODO : Calls MixHash() once for each public key listed in the pre-messages from handshake_pattern, with the
- # specified public key as input (see Section 7 for an explanation of pre-messages). If both initiator and
- # responder have pre-messages, the initiator's public keys are hashed first.
get_local_keypair = ->(token) { instance_variable_get('@' + token).public_key }
get_remote_keypair = ->(token) { instance_variable_get('@r' + token) }
if initiator
initiator_keypair_getter = get_local_keypair
@@ -44,20 +41,48 @@
else
initiator_keypair_getter = get_remote_keypair
responder_keypair_getter = get_local_keypair
end
+ # Sets message_patterns to the message patterns from handshake_pattern
+ @message_patterns = @protocol.pattern.tokens.dup
+
@protocol.pattern.initiator_pre_messages&.map do |message|
keypair = initiator_keypair_getter.call(message)
@symmetric_state.mix_hash(keypair)
end
+ if @protocol.pattern.fallback
+ message = @message_patterns.delete_at(0).first
+ public_key = initiator_keypair_getter.call(message)
+ @symmetric_state.mix_hash(public_key)
+ end
+
@protocol.pattern.responder_pre_messages&.map do |message|
keypair = responder_keypair_getter.call(message)
@symmetric_state.mix_hash(keypair)
end
- # Sets message_patterns to the message patterns from handshake_pattern
- @message_patterns = @protocol.pattern.tokens.dup
+ end
+
+ def expected_message_length(payload_size)
+ has_key = @symmetric_state.cipher_state.key?
+ pattern = @message_patterns.first
+ len = pattern.inject(0) do |len, token|
+ case token
+ when 'e'
+ len += @protocol.dh_fn.dhlen
+ has_key = true if @protocol.psk_handshake?
+ when 's'
+ len += @protocol.dh_fn.dhlen
+ len += 16 if has_key
+ when 'ee', 'es', 'se', 'ss', 'psk'
+ has_key = true
+ end
+ len
+ end
+ len += payload_size
+ len += 16 if has_key
+ len
end
# Takes a payload byte sequence which may be zero-length, and a message_buffer to write the output into
def write_message(payload, message_buffer)
pattern = @message_patterns.shift