Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle fragmented NTS-KE messages #3

Merged
merged 2 commits into from
Aug 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions lib/nts/ntske/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,32 @@ def key_establish
EndOfMessage.new
]
client.write(req.map(&:serialize))
res = nil
read, = IO.select([sock], nil, nil, 1)
if read.nil?
warn 'Timeout: receiving for NTS-KE messages'
exit 1
else
res = Ntske.response_deserialize(client.read)
end
res = []
buffer = ''
loop do
read, = IO.select([sock], nil, nil, 1)
if read.nil?
warn 'Timeout: receiving for NTS-KE messages'
exit 1
else
r, b = Ntske.response_deserialize(buffer + client.read)
res += r
buffer = b
end

# Error
er = res.find { |m| m.is_a?(ErrorRecord) }
raise "received Error(#{er.error_code.unpack1('n')})" unless er.nil?

# Error
er = res.find { |m| m.is_a?(ErrorRecord) }
raise "received Error(#{er.error_code.unpack1('n')})" unless er.nil?
# Warning
wr = res.find { |m| m.is_a?(WarningRecord) }
raise "received Warning(#{wr.warning_code})" unless wr.nil?

# Warning
wr = res.find { |m| m.is_a?(WarningRecord) }
raise "received Warning(#{wr.warning_code})" unless wr.nil?
# End of Message
break if res.last&.is_a?(EndOfMessage) &&
res.count { |m| m.is_a?(EndOfMessage) } == 1 &&
buffer.empty?
end

# Next Protocol Negotiation
npn = res.select { |m| m.is_a?(NtsNextProtocolNegotiation) }
Expand Down Expand Up @@ -79,10 +89,6 @@ def key_establish
c2s_key = client.exporter(KE_LABEL, "\x00\x00" + alg + "\x00", key_len)
s2c_key = client.exporter(KE_LABEL, "\x00\x00" + alg + "\x01", key_len)

# End of Message
raise Exception unless res.last&.is_a?(EndOfMessage) &&
res.count { |m| m.is_a?(EndOfMessage) } == 1

[server, port, cookies, c2s_key, s2c_key]
end
# rubocop: enable Metrics/AbcSize
Expand Down
7 changes: 4 additions & 3 deletions lib/nts/ntske/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module Ntske
# @raise [Exception | RuntimeError]
#
# @return [Array of Nts::Ntske::$Object]
# @return [String] surplus binary
# rubocop: disable Metrics/AbcSize
# rubocop: disable Metrics/CyclomaticComplexity
# rubocop: disable Metrics/MethodLength
Expand All @@ -51,12 +52,12 @@ def response_deserialize(s)
res = []
i = 0
while i < s.length
raise Exception if i + 4 > s.length
return [res, s[i..]] if i + 4 > s.length

c = !(s[i].unpack1('c') | 32768).zero?
type = s.slice(i, 2).unpack1('n') & 32767
body_len = s.slice(i + 2, 2).unpack1('n')
raise Exception if i + 4 + body_len > s.length
return [res, s[i..]] if i + 4 + body_len > s.length

sb = s.slice(i + 4, body_len)
case type
Expand Down Expand Up @@ -96,7 +97,7 @@ def response_deserialize(s)
end
raise Exception unless i == s.length

res
[res, '']
end
# rubocop: enable Metrics/AbcSize
# rubocop: enable Metrics/CyclomaticComplexity
Expand Down