summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFlorian Wininger <fw.centrale@gmail.com>2019-08-28 11:15:12 +0200
committerFlorian Wininger <fw.centrale@gmail.com>2019-08-28 11:44:55 +0200
commit6e81f63b72c759887ee27ea87f2b651289a41226 (patch)
treede0c0299f364defb54ca41421e48c36eb105c0aa /lib
parent2c3450670533b9cda48375b6056f313b02afffcd (diff)
downloadnet-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.rb72
-rw-r--r--lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb72
-rw-r--r--lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb8
-rw-r--r--lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb8
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)