Class: Noise::Connection::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/noise/connection/base.rb

Direct Known Subclasses

Initiator, Responder

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, keypairs: { s: nil, e: nil, rs: nil, re: nil }) ⇒ Base

Returns a new instance of Base.



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/noise/connection/base.rb', line 11

def initialize(name, keypairs: { s: nil, e: nil, rs: nil, re: nil })
  @protocol = Protocol.create(name)

  # parameter keypairs[:e] and keypairs[:s] are strings, so should convert Noise::Key object.
  @local_keypairs = {}
  @local_keypairs[:e] = @protocol.dh_fn.class.from_private(keypairs[:e]) if keypairs[:e]
  @local_keypairs[:s] = @protocol.dh_fn.class.from_private(keypairs[:s]) if keypairs[:s]
  @remote_keys = { rs: keypairs[:rs], re: keypairs[:re] }
  @handshake_started = false
  @handshake_finished = false
  initialize_next_message
end

Instance Attribute Details

#cipher_state_decryptObject (readonly)

Returns the value of attribute cipher_state_decrypt.



7
8
9
# File 'lib/noise/connection/base.rb', line 7

def cipher_state_decrypt
  @cipher_state_decrypt
end

#cipher_state_encryptObject (readonly)

Returns the value of attribute cipher_state_encrypt.



7
8
9
# File 'lib/noise/connection/base.rb', line 7

def cipher_state_encrypt
  @cipher_state_encrypt
end

#cipher_state_handshakeObject (readonly)

Returns the value of attribute cipher_state_handshake.



7
8
9
# File 'lib/noise/connection/base.rb', line 7

def cipher_state_handshake
  @cipher_state_handshake
end

#handshake_finishedObject (readonly)

Returns the value of attribute handshake_finished.



6
7
8
# File 'lib/noise/connection/base.rb', line 6

def handshake_finished
  @handshake_finished
end

#handshake_hashObject (readonly)

Returns the value of attribute handshake_hash.



6
7
8
# File 'lib/noise/connection/base.rb', line 6

def handshake_hash
  @handshake_hash
end

#handshake_startedObject (readonly)

Returns the value of attribute handshake_started.



6
7
8
# File 'lib/noise/connection/base.rb', line 6

def handshake_started
  @handshake_started
end

#handshake_stateObject (readonly)

Returns the value of attribute handshake_state.



6
7
8
# File 'lib/noise/connection/base.rb', line 6

def handshake_state
  @handshake_state
end

#prologueObject

Returns the value of attribute prologue.



8
9
10
# File 'lib/noise/connection/base.rb', line 8

def prologue
  @prologue
end

#protocolObject (readonly)

Returns the value of attribute protocol.



6
7
8
# File 'lib/noise/connection/base.rb', line 6

def protocol
  @protocol
end

#psksObject

Returns the value of attribute psks.



8
9
10
# File 'lib/noise/connection/base.rb', line 8

def psks
  @psks
end

#rsObject (readonly)

Returns the value of attribute rs.



9
10
11
# File 'lib/noise/connection/base.rb', line 9

def rs
  @rs
end

#sObject (readonly)

Returns the value of attribute s.



9
10
11
# File 'lib/noise/connection/base.rb', line 9

def s
  @s
end

Instance Method Details

#decrypt(data) ⇒ Object



85
86
87
88
89
# File 'lib/noise/connection/base.rb', line 85

def decrypt(data)
  raise Noise::Exceptions::NoiseHandshakeError unless @handshake_finished

  @cipher_state_decrypt.decrypt_with_ad('', data)
end

#encrypt(data) ⇒ Object



79
80
81
82
83
# File 'lib/noise/connection/base.rb', line 79

def encrypt(data)
  raise Noise::Exceptions::NoiseHandshakeError unless @handshake_finished

  @cipher_state_encrypt.encrypt_with_ad('', data)
end

#fallback(fallback_name) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/noise/connection/base.rb', line 30

def fallback(fallback_name)
  @protocol = Protocol.create(fallback_name)
  @handshake_started = false
  @handshake_finished = false
  # initialize_next_message
  @local_keypairs = { e: @handshake_state.e, s: @handshake_state.s }
  @remote_keys = { re: @handshake_state.re, rs: @handshake_state.rs }
  start_handshake
end

#handshake_done(_c1, _c2) ⇒ Object



114
115
116
117
118
119
120
121
# File 'lib/noise/connection/base.rb', line 114

def handshake_done(_c1, _c2)
  @handshake_hash = @symmetric_state.handshake_hash
  @s = @handshake_state.s
  @rs = @handshake_state.rs
  @handshake_state = nil
  @symmetric_state = nil
  @cipher_state_handshake = nil
end

#initialise_handshake_stateObject



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/noise/connection/base.rb', line 40

def initialise_handshake_state
  @handshake_state = Noise::State::HandshakeState.new(
    self,
    protocol,
    initiator?,
    @prologue,
    @local_keypairs,
    @remote_keys
  )
  @symmetric_state = @handshake_state.symmetric_state
  @cipher_state_handshake = @symmetric_state.cipher_state
end

#psk_handshake?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/noise/connection/base.rb', line 110

def psk_handshake?
  @protocol.is_psk_handshake
end

#read_message(data) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/noise/connection/base.rb', line 66

def read_message(data)
  # Call NoiseConnection.start_handshake first
  raise Noise::Exceptions::NoiseHandshakeError unless @handshake_started
  raise Noise::Exceptions::NoiseHandshakeError if @next_message != :read
  raise Noise::Exceptions::NoiseHandshakeError if @handshake_finished

  @next_message = :write
  buffer = +''
  result = @handshake_state.read_message(data, buffer)
  @handshake_finished = true if result
  buffer
end

#start_handshakeObject



24
25
26
27
28
# File 'lib/noise/connection/base.rb', line 24

def start_handshake
  validate
  initialise_handshake_state
  @handshake_started = true
end

#valid_keypairs?Boolean

Returns:

  • (Boolean)


97
98
99
100
# File 'lib/noise/connection/base.rb', line 97

def valid_keypairs?
  keypairs = @local_keypairs.merge(@remote_keys)
  @protocol.pattern.required_keypairs(initiator?).any? { |keypair| !keypairs[keypair] }
end

#validateObject



102
103
104
105
106
107
108
# File 'lib/noise/connection/base.rb', line 102

def validate
  validate_psk! if psk_handshake?

  raise Noise::Exceptions::NoiseValidationError if valid_keypairs?

  true
end

#validate_psk!Object



91
92
93
94
95
# File 'lib/noise/connection/base.rb', line 91

def validate_psk!
  # Invalid psk length! Has to be 32 bytes long
  raise Noise::Exceptions::NoisePSKError if @psks.any? { |psk| psk.bytesize != 32 }
  raise Noise::Exceptions::NoisePSKError if @protocol.pattern.psk_count != @psks.count
end

#write_message(payload = '') ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/noise/connection/base.rb', line 53

def write_message(payload = '')
  # Call NoiseConnection.start_handshake first
  raise Noise::Exceptions::NoiseHandshakeError unless @handshake_started
  raise Noise::Exceptions::NoiseHandshakeError if @next_message != :write
  raise Noise::Exceptions::NoiseHandshakeError if @handshake_finished

  @next_message = :read
  buffer = +''
  result = @handshake_state.write_message(payload, buffer)
  @handshake_finished = true if result
  buffer
end