1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
require 'net/ssh/transport/kex/abstract'
module Net
module SSH
module Transport
module Kex
# Implement key-exchange algorithm from Elliptic Curve Algorithm Integration
# in the Secure Shell Transport Layer (RFC 5656)
class Abstract5656 < Abstract
alias ecdh dh
def curve_name
raise NotImplementedError, 'abstract class: curve_name not implemented'
end
private
def get_message_types
[KEXECDH_INIT, KEXECDH_REPLY]
end
def build_signature_buffer(result)
response = Net::SSH::Buffer.new
response.write_string data[:client_version_string],
data[:server_version_string],
data[:client_algorithm_packet],
data[:server_algorithm_packet],
result[:key_blob],
ecdh_public_key_bytes,
result[:server_ecdh_pubkey]
response.write_bignum result[:shared_secret]
response
end
def send_kexinit #:nodoc:
init, reply = get_message_types
# send the KEXECDH_INIT message
## byte SSH_MSG_KEX_ECDH_INIT
## string Q_C, client's ephemeral public key octet string
buffer = Net::SSH::Buffer.from(:byte, init, :mstring, ecdh_public_key_bytes)
connection.send_message(buffer)
# expect the following KEXECDH_REPLY message
## byte SSH_MSG_KEX_ECDH_REPLY
## string K_S, server's public host key
## string Q_S, server's ephemeral public key octet string
## string the signature on the exchange hash
buffer = connection.next_message
raise Net::SSH::Exception, 'expected REPLY' unless buffer.type == reply
result = {}
result[:key_blob] = buffer.read_string
result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
result[:server_ecdh_pubkey] = buffer.read_string
result[:shared_secret] = compute_shared_secret(result[:server_ecdh_pubkey])
sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
sig_type = sig_buffer.read_string
if sig_type != algorithms.host_key_format
raise Net::SSH::Exception, "host key algorithm mismatch for signature '#{sig_type}' != '#{algorithms.host_key_format}'"
end
result[:server_sig] = sig_buffer.read_string
result
end
end
end
end
end
end
|