Class: Noise::State::HandshakeState
- Inherits:
-
Object
- Object
- Noise::State::HandshakeState
- Defined in:
- lib/noise/state/handshake_state.rb
Overview
A HandshakeState object contains a SymmetricState plus the following variables, any of which may be empty. Empty is a special value which indicates the variable has not yet been initialized.
s: The local static key pair e: The local ephemeral key pair rs: The remote party’s static public key re: The remote party’s ephemeral public key
A HandshakeState also has variables to track its role, and the remaining portion of the handshake pattern:
initiator: A boolean indicating the initiator or responder role.
message_patterns: A sequence of message patterns.
Each pattern is a sequence of tokens from the set ("e", "s", "ee", "es", "se", "ss").
Instance Attribute Summary collapse
-
#e ⇒ Object
readonly
Returns the value of attribute e.
-
#message_patterns ⇒ Object
readonly
Returns the value of attribute message_patterns.
-
#re ⇒ Object
readonly
Returns the value of attribute re.
-
#rs ⇒ Object
readonly
Returns the value of attribute rs.
-
#s ⇒ Object
readonly
Returns the value of attribute s.
-
#symmetric_state ⇒ Object
readonly
Returns the value of attribute symmetric_state.
Instance Method Summary collapse
- #expected_message_length(payload_size) ⇒ Object
- #get_keypair_getter(initiator) ⇒ Object
-
#initialize(connection, initiator, prologue, local_keypairs, remote_keys) ⇒ HandshakeState
constructor
A new instance of HandshakeState.
- #local_keypair_getter ⇒ Object
- #process_fallback(initiator_keypair_getter) ⇒ Object
- #process_initiator_pre_messages(keypair_getter) ⇒ Object
- #process_responder_pre_messages(keypair_getter) ⇒ Object
-
#read_message(message, payload_buffer) ⇒ Object
Takes a byte sequence containing a Noise handshake message, and a payload_buffer to write the message’s plaintext payload into.
- #remote_keypair_getter ⇒ Object
-
#write_message(payload, message_buffer) ⇒ Object
Takes a payload byte sequence which may be zero-length, and a message_buffer to write the output into.
Constructor Details
#initialize(connection, initiator, prologue, local_keypairs, remote_keys) ⇒ HandshakeState
Returns a new instance of HandshakeState.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/noise/state/handshake_state.rb', line 23 def initialize(connection, initiator, prologue, local_keypairs, remote_keys) @connection = connection @protocol = connection.protocol @symmetric_state = SymmetricState.initialize_symmetric(@protocol, connection, prologue: prologue) @initiator = initiator @s = local_keypairs[:s] @e = local_keypairs[:e] @rs = remote_keys[:rs] @re = remote_keys[:re] initiator_keypair_getter, responder_keypair_getter = get_keypair_getter(initiator) # Sets message_patterns to the message patterns from handshake_pattern = @protocol.pattern.tokens.dup (initiator_keypair_getter) process_fallback(initiator_keypair_getter) (responder_keypair_getter) end |
Instance Attribute Details
#e ⇒ Object (readonly)
Returns the value of attribute e.
21 22 23 |
# File 'lib/noise/state/handshake_state.rb', line 21 def e @e end |
#message_patterns ⇒ Object (readonly)
Returns the value of attribute message_patterns.
20 21 22 |
# File 'lib/noise/state/handshake_state.rb', line 20 def end |
#re ⇒ Object (readonly)
Returns the value of attribute re.
21 22 23 |
# File 'lib/noise/state/handshake_state.rb', line 21 def re @re end |
#rs ⇒ Object (readonly)
Returns the value of attribute rs.
21 22 23 |
# File 'lib/noise/state/handshake_state.rb', line 21 def rs @rs end |
#s ⇒ Object (readonly)
Returns the value of attribute s.
21 22 23 |
# File 'lib/noise/state/handshake_state.rb', line 21 def s @s end |
#symmetric_state ⇒ Object (readonly)
Returns the value of attribute symmetric_state.
20 21 22 |
# File 'lib/noise/state/handshake_state.rb', line 20 def symmetric_state @symmetric_state end |
Instance Method Details
#expected_message_length(payload_size) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/noise/state/handshake_state.rb', line 81 def (payload_size) has_key = @symmetric_state.cipher_state.key? pattern = .first len = pattern.inject(0) do |l, token| case token when Noise::Token::E l += @protocol.dh_fn.dhlen has_key = true if @protocol.psk? when Noise::Token::S l += @protocol.dh_fn.dhlen l += 16 if has_key else has_key = true end l end len += payload_size len += 16 if has_key len end |
#get_keypair_getter(initiator) ⇒ Object
43 44 45 46 47 48 49 |
# File 'lib/noise/state/handshake_state.rb', line 43 def get_keypair_getter(initiator) if initiator [local_keypair_getter, remote_keypair_getter] else [remote_keypair_getter, local_keypair_getter] end end |
#local_keypair_getter ⇒ Object
51 52 53 |
# File 'lib/noise/state/handshake_state.rb', line 51 def local_keypair_getter ->(token) { instance_variable_get('@' + token.to_s).public_key } end |
#process_fallback(initiator_keypair_getter) ⇒ Object
66 67 68 69 70 71 72 |
# File 'lib/noise/state/handshake_state.rb', line 66 def process_fallback(initiator_keypair_getter) return unless @protocol.pattern.fallback = .delete_at(0).first public_key = initiator_keypair_getter.call() @symmetric_state.mix_hash(public_key) end |
#process_initiator_pre_messages(keypair_getter) ⇒ Object
59 60 61 62 63 64 |
# File 'lib/noise/state/handshake_state.rb', line 59 def (keypair_getter) @protocol.pattern.&.map do |token| keypair = keypair_getter.call(token) @symmetric_state.mix_hash(keypair) end end |
#process_responder_pre_messages(keypair_getter) ⇒ Object
74 75 76 77 78 79 |
# File 'lib/noise/state/handshake_state.rb', line 74 def (keypair_getter) @protocol.pattern.&.map do |token| keypair = keypair_getter.call(token) @symmetric_state.mix_hash(keypair) end end |
#read_message(message, payload_buffer) ⇒ Object
Takes a byte sequence containing a Noise handshake message, and a payload_buffer to write the message’s plaintext payload into
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/noise/state/handshake_state.rb', line 126 def (, payload_buffer) pattern = .shift pattern.each do |token| case token when Noise::Token::E , re = extract_key(, false) @re ||= re mix_e(@re) when Noise::Token::S , @rs = extract_key(, true) when Noise::Token::EE, Noise::Token::ES, Noise::Token::SE, Noise::Token::SS token.mix(@symmetric_state, @protocol.dh_fn, @initiator, self) when Noise::Token::PSK mix_psk end end payload_buffer << @symmetric_state.decrypt_and_hash() @symmetric_state.split if .empty? end |
#remote_keypair_getter ⇒ Object
55 56 57 |
# File 'lib/noise/state/handshake_state.rb', line 55 def remote_keypair_getter ->(token) { instance_variable_get('@r' + token.to_s) } end |
#write_message(payload, message_buffer) ⇒ Object
Takes a payload byte sequence which may be zero-length, and a message_buffer to write the output into
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/noise/state/handshake_state.rb', line 103 def (payload, ) pattern = .shift pattern.each do |token| case token when Noise::Token::E @e ||= @protocol.dh_fn.generate_keypair << @e.public_key mix_e(@e.public_key) when Noise::Token::S << @symmetric_state.encrypt_and_hash(@s.public_key) when Noise::Token::EE, Noise::Token::ES, Noise::Token::SE, Noise::Token::SS token.mix(@symmetric_state, @protocol.dh_fn, @initiator, self) when Noise::Token::PSK mix_psk end end << @symmetric_state.encrypt_and_hash(payload) @symmetric_state.split if .empty? end |