Class: Noise::Connection::Base
- Inherits:
-
Object
- Object
- Noise::Connection::Base
- Defined in:
- lib/noise/connection/base.rb
Constant Summary collapse
- MAX_MESSAGE_LENGTH =
The Noise spec caps a handshake or transport message at 65535 bytes.
65_535
Instance Attribute Summary collapse
-
#cipher_state_decrypt ⇒ Object
readonly
Returns the value of attribute cipher_state_decrypt.
-
#cipher_state_encrypt ⇒ Object
readonly
Returns the value of attribute cipher_state_encrypt.
-
#cipher_state_handshake ⇒ Object
readonly
Returns the value of attribute cipher_state_handshake.
-
#handshake_finished ⇒ Object
readonly
Returns the value of attribute handshake_finished.
-
#handshake_hash ⇒ Object
readonly
Returns the value of attribute handshake_hash.
-
#handshake_started ⇒ Object
readonly
Returns the value of attribute handshake_started.
-
#handshake_state ⇒ Object
readonly
Returns the value of attribute handshake_state.
-
#prologue ⇒ Object
Returns the value of attribute prologue.
-
#protocol ⇒ Object
readonly
Returns the value of attribute protocol.
-
#psks ⇒ Object
Returns the value of attribute psks.
-
#rs ⇒ Object
readonly
Returns the value of attribute rs.
-
#s ⇒ Object
readonly
Returns the value of attribute s.
Instance Method Summary collapse
- #decrypt(data) ⇒ Object
- #encrypt(data) ⇒ Object
-
#fallback(fallback_name) ⇒ Object
Restarts the handshake with a fallback pattern, carrying over the keys of the aborted one.
- #handshake_done(_c1, _c2) ⇒ Object
- #initialise_handshake_state ⇒ Object
-
#initialize(name, keypairs: { s: nil, e: nil, rs: nil, re: nil }) ⇒ Base
constructor
A new instance of Base.
- #missing_keypairs? ⇒ Boolean
- #read_message(data) ⇒ Object
- #start_handshake ⇒ Object
- #validate ⇒ Object
- #validate_psk! ⇒ Object
- #write_message(payload = '') ⇒ Object
Constructor Details
#initialize(name, keypairs: { s: nil, e: nil, rs: nil, re: nil }) ⇒ Base
Returns a new instance of Base.
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/noise/connection/base.rb', line 13 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 end |
Instance Attribute Details
#cipher_state_decrypt ⇒ Object (readonly)
Returns the value of attribute cipher_state_decrypt.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def cipher_state_decrypt @cipher_state_decrypt end |
#cipher_state_encrypt ⇒ Object (readonly)
Returns the value of attribute cipher_state_encrypt.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def cipher_state_encrypt @cipher_state_encrypt end |
#cipher_state_handshake ⇒ Object (readonly)
Returns the value of attribute cipher_state_handshake.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def cipher_state_handshake @cipher_state_handshake end |
#handshake_finished ⇒ Object (readonly)
Returns the value of attribute handshake_finished.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def handshake_finished @handshake_finished end |
#handshake_hash ⇒ Object (readonly)
Returns the value of attribute handshake_hash.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def handshake_hash @handshake_hash end |
#handshake_started ⇒ Object (readonly)
Returns the value of attribute handshake_started.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def handshake_started @handshake_started end |
#handshake_state ⇒ Object (readonly)
Returns the value of attribute handshake_state.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def handshake_state @handshake_state end |
#prologue ⇒ Object
Returns the value of attribute prologue.
11 12 13 |
# File 'lib/noise/connection/base.rb', line 11 def prologue @prologue end |
#protocol ⇒ Object (readonly)
Returns the value of attribute protocol.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def protocol @protocol end |
#psks ⇒ Object
Returns the value of attribute psks.
11 12 13 |
# File 'lib/noise/connection/base.rb', line 11 def psks @psks end |
#rs ⇒ Object (readonly)
Returns the value of attribute rs.
9 10 11 |
# File 'lib/noise/connection/base.rb', line 9 def rs @rs end |
#s ⇒ Object (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
94 95 96 97 98 |
# File 'lib/noise/connection/base.rb', line 94 def decrypt(data) raise Noise::Exceptions::NoiseHandshakeError unless @handshake_finished @cipher_state_decrypt.decrypt_with_ad('', data) end |
#encrypt(data) ⇒ Object
88 89 90 91 92 |
# File 'lib/noise/connection/base.rb', line 88 def encrypt(data) raise Noise::Exceptions::NoiseHandshakeError unless @handshake_finished @cipher_state_encrypt.encrypt_with_ad('', data) end |
#fallback(fallback_name) ⇒ Object
Restarts the handshake with a fallback pattern, carrying over the keys of the aborted one.
The roles swap here: the party that wrote the aborted message now reads, and the one that failed to read it now writes. Both sides are already in that state, so @next_message is deliberately left as it is rather than reset through initialize_next_message.
37 38 39 40 41 42 43 44 |
# File 'lib/noise/connection/base.rb', line 37 def fallback(fallback_name) @protocol = Protocol.create(fallback_name) @handshake_started = false @handshake_finished = false @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
119 120 121 122 123 124 125 126 |
# File 'lib/noise/connection/base.rb', line 119 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_state ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/noise/connection/base.rb', line 46 def initialise_handshake_state @handshake_state = Noise::State::HandshakeState.new( self, initiator?, @prologue, @local_keypairs, @remote_keys ) @symmetric_state = @handshake_state.symmetric_state @cipher_state_handshake = @symmetric_state.cipher_state end |
#missing_keypairs? ⇒ Boolean
106 107 108 109 |
# File 'lib/noise/connection/base.rb', line 106 def missing_keypairs? keypairs = @local_keypairs.merge(@remote_keys) @protocol.pattern.required_keypairs(initiator?).any? { |keypair| !keypairs[keypair] } end |
#read_message(data) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/noise/connection/base.rb', line 74 def (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 raise Noise::Exceptions::NoiseHandshakeError, 'Message exceeds the maximum length.' if data.bytesize > MAX_MESSAGE_LENGTH @next_message = :write buffer = +'' @handshake_finished = @handshake_state.(data, buffer) buffer end |
#start_handshake ⇒ Object
26 27 28 29 30 |
# File 'lib/noise/connection/base.rb', line 26 def start_handshake validate initialise_handshake_state @handshake_started = true end |
#validate ⇒ Object
111 112 113 114 115 116 117 |
# File 'lib/noise/connection/base.rb', line 111 def validate validate_psk! if @protocol.psk? raise Noise::Exceptions::NoiseValidationError if missing_keypairs? true end |
#validate_psk! ⇒ Object
100 101 102 103 104 |
# File 'lib/noise/connection/base.rb', line 100 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
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/noise/connection/base.rb', line 58 def (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 if @handshake_state.(payload.bytesize) > MAX_MESSAGE_LENGTH raise Noise::Exceptions::NoiseHandshakeError, 'Message exceeds the maximum length.' end @next_message = :read buffer = +'' @handshake_finished = @handshake_state.(payload, buffer) buffer end |