diff options
author | Florian Wininger <fw.centrale@gmail.com> | 2019-08-28 11:15:12 +0200 |
---|---|---|
committer | Florian Wininger <fw.centrale@gmail.com> | 2019-08-28 11:44:55 +0200 |
commit | 6e81f63b72c759887ee27ea87f2b651289a41226 (patch) | |
tree | de0c0299f364defb54ca41421e48c36eb105c0aa /lib | |
parent | 2c3450670533b9cda48375b6056f313b02afffcd (diff) | |
download | net-ssh-6e81f63b72c759887ee27ea87f2b651289a41226.tar.gz |
Refactoring kex ecdh RFC5656
Signed-off-by: Florian Wininger <fw.centrale@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/net/ssh/transport/kex/abstract5656.rb | 72 | ||||
-rw-r--r-- | lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb | 72 | ||||
-rw-r--r-- | lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb | 8 | ||||
-rw-r--r-- | lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb | 8 |
4 files changed, 95 insertions, 65 deletions
diff --git a/lib/net/ssh/transport/kex/abstract5656.rb b/lib/net/ssh/transport/kex/abstract5656.rb new file mode 100644 index 0000000..06c874d --- /dev/null +++ b/lib/net/ssh/transport/kex/abstract5656.rb @@ -0,0 +1,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 diff --git a/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb b/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb index 1bc704e..84d0e4a 100644 --- a/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +++ b/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb @@ -1,14 +1,12 @@ -require 'net/ssh/transport/kex/diffie_hellman_group1_sha1' +require 'net/ssh/transport/kex/abstract5656' -module Net - module SSH - module Transport +module Net + module SSH + module Transport module Kex # A key-exchange service implementing the "ecdh-sha2-nistp256" # key-exchange algorithm. (defined in RFC 5656) - class EcdhSHA2NistP256 < Abstract - alias ecdh dh - + class EcdhSHA2NistP256 < Abstract5656 def digester OpenSSL::Digest::SHA256 end @@ -19,64 +17,20 @@ module Net 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.to_bn.to_s(2), - result[:server_ecdh_pubkey] - response.write_bignum result[:shared_secret] - response - end - def generate_key #:nodoc: OpenSSL::PKey::EC.new(curve_name).generate_key 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.to_bn.to_s(2)) - 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 = Hash.new - 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 - - # compute shared secret from server's public key and client's private key + # compute shared secret from server's public key and client's private key + def compute_shared_secret(server_ecdh_pubkey) pk = OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new(curve_name).group, - OpenSSL::BN.new(result[:server_ecdh_pubkey], 2)) - result[:shared_secret] = OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2) - - 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 + OpenSSL::BN.new(server_ecdh_pubkey, 2)) + OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2) + end - return result + ## string Q_C, client's ephemeral public key octet string + def ecdh_public_key_bytes + ecdh.public_key.to_bn.to_s(2) end end end diff --git a/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb b/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb index d2a7a59..8aa3cf5 100644 --- a/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +++ b/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb @@ -1,6 +1,8 @@ -module Net - module SSH - module Transport +require 'net/ssh/transport/kex/ecdh_sha2_nistp256' + +module Net + module SSH + module Transport module Kex # A key-exchange service implementing the "ecdh-sha2-nistp256" # key-exchange algorithm. (defined in RFC 5656) diff --git a/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb b/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb index 5099ce0..f565e37 100644 --- a/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +++ b/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb @@ -1,6 +1,8 @@ -module Net - module SSH - module Transport +require 'net/ssh/transport/kex/ecdh_sha2_nistp256' + +module Net + module SSH + module Transport module Kex # A key-exchange service implementing the "ecdh-sha2-nistp521" # key-exchange algorithm. (defined in RFC 5656) |