diff options
author | Miklós Fazekas <mfazekas@szemafor.com> | 2020-06-10 10:27:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-10 10:27:27 +0200 |
commit | b38f7ba0bf7aa83e49c2e8e17444804b1fce4bcc (patch) | |
tree | 5bf60d797bba382d3fb7e6f76200abdebd0085c5 | |
parent | b44dc7a2513f0abd6044452d74a1817b12524520 (diff) | |
parent | da2b5d4fbe5c04ec07a3a73eba5821026e5e66ae (diff) | |
download | net-ssh-b38f7ba0bf7aa83e49c2e8e17444804b1fce4bcc.tar.gz |
Merge pull request #771 from mfazekas/rsa-sha2-256-512
Implemented rsa-sha2-512, rsa-sha2-256 host_key algs
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | lib/net/ssh/authentication/certificate.rb | 4 | ||||
-rw-r--r-- | lib/net/ssh/authentication/ed25519.rb | 2 | ||||
-rw-r--r-- | lib/net/ssh/transport/algorithms.rb | 4 | ||||
-rw-r--r-- | lib/net/ssh/transport/kex/abstract.rb | 11 | ||||
-rw-r--r-- | lib/net/ssh/transport/openssl.rb | 17 | ||||
-rw-r--r-- | test/integration/Vagrantfile | 5 | ||||
-rw-r--r-- | test/integration/common.rb | 10 | ||||
-rw-r--r-- | test/integration/playbook.yml | 11 | ||||
-rw-r--r-- | test/transport/kex/test_ecdh_sha2_nistp256.rb | 2 | ||||
-rw-r--r-- | test/transport/test_algorithms.rb | 14 |
11 files changed, 59 insertions, 23 deletions
@@ -9,3 +9,5 @@ test/integration/.vagrant test/integration/playbook.retry .byebug_history + +tryout diff --git a/lib/net/ssh/authentication/certificate.rb b/lib/net/ssh/authentication/certificate.rb index 006b45e..310ad7d 100644 --- a/lib/net/ssh/authentication/certificate.rb +++ b/lib/net/ssh/authentication/certificate.rb @@ -70,8 +70,8 @@ module Net key.ssh_do_sign(data) end - def ssh_do_verify(sig, data) - key.ssh_do_verify(sig, data) + def ssh_do_verify(sig, data, options = {}) + key.ssh_do_verify(sig, data, options) end def to_pem diff --git a/lib/net/ssh/authentication/ed25519.rb b/lib/net/ssh/authentication/ed25519.rb index 0c5530c..9416bbc 100644 --- a/lib/net/ssh/authentication/ed25519.rb +++ b/lib/net/ssh/authentication/ed25519.rb @@ -123,7 +123,7 @@ module Net ssh_type end - def ssh_do_verify(sig,data) + def ssh_do_verify(sig, data, options = {}) @verify_key.verify(sig,data) end diff --git a/lib/net/ssh/transport/algorithms.rb b/lib/net/ssh/transport/algorithms.rb index 8126aa6..9ab87b6 100644 --- a/lib/net/ssh/transport/algorithms.rb +++ b/lib/net/ssh/transport/algorithms.rb @@ -33,7 +33,9 @@ module Net ecdsa-sha2-nistp256 ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com - ssh-rsa], + ssh-rsa + rsa-sha2-256 + rsa-sha2-512], kex: %w[ecdh-sha2-nistp521 ecdh-sha2-nistp384 diff --git a/lib/net/ssh/transport/kex/abstract.rb b/lib/net/ssh/transport/kex/abstract.rb index c70eb94..3fd8c3c 100644 --- a/lib/net/ssh/transport/kex/abstract.rb +++ b/lib/net/ssh/transport/kex/abstract.rb @@ -64,11 +64,16 @@ module Net private + def matching?(key_ssh_type, host_key_alg) + return true if key_ssh_type == host_key_alg + return true if key_ssh_type == 'ssh-rsa' && ['rsa-sha2-512', 'rsa-sha2-256'].include?(host_key_alg) + end + # Verify that the given key is of the expected type, and that it # really is the key for the session's host. Raise Net::SSH::Exception # if it is not. def verify_server_key(key) #:nodoc: - if key.ssh_type != algorithms.host_key + unless matching?(key.ssh_type, algorithms.host_key) raise Net::SSH::Exception, "host key algorithm mismatch '#{key.ssh_type}' != '#{algorithms.host_key}'" end @@ -97,7 +102,9 @@ module Net hash = digester.digest(response.to_s) - unless connection.host_key_verifier.verify_signature { result[:server_key].ssh_do_verify(result[:server_sig], hash) } + server_key = result[:server_key] + server_sig = result[:server_sig] + unless connection.host_key_verifier.verify_signature { server_key.ssh_do_verify(server_sig, hash, host_key: algorithms.host_key) } raise Net::SSH::Exception, 'could not verify server signature' end diff --git a/lib/net/ssh/transport/openssl.rb b/lib/net/ssh/transport/openssl.rb index d2d7117..7b16c3d 100644 --- a/lib/net/ssh/transport/openssl.rb +++ b/lib/net/ssh/transport/openssl.rb @@ -63,8 +63,17 @@ module OpenSSL end # Verifies the given signature matches the given data. - def ssh_do_verify(sig, data) - verify(OpenSSL::Digest::SHA1.new, sig, data) + def ssh_do_verify(sig, data, options = {}) + digester = + if options[:host_key] == "rsa-sha2-512" + OpenSSL::Digest::SHA512.new + elsif options[:host_key] == "rsa-sha2-256" + OpenSSL::Digest::SHA256.new + else + OpenSSL::Digest::SHA1.new + end + + verify(digester, sig, data) end # Returns the signature for the given data. @@ -94,7 +103,7 @@ module OpenSSL end # Verifies the given signature matches the given data. - def ssh_do_verify(sig, data) + def ssh_do_verify(sig, data, options = {}) sig_r = sig[0,20].unpack("H*")[0].to_i(16) sig_s = sig[20,20].unpack("H*")[0].to_i(16) a1sig = OpenSSL::ASN1::Sequence([ @@ -192,7 +201,7 @@ module OpenSSL end # Verifies the given signature matches the given data. - def ssh_do_verify(sig, data) + def ssh_do_verify(sig, data, options = {}) digest = digester.digest(data) a1sig = nil diff --git a/test/integration/Vagrantfile b/test/integration/Vagrantfile index 2c42d9a..2327e5d 100644 --- a/test/integration/Vagrantfile +++ b/test/integration/Vagrantfile @@ -1,10 +1,11 @@ VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.provision "ansible" do |ansible| ansible.playbook = "./playbook.yml" - ansible.sudo = true + ansible.become = true + ansible.become_user = 'root' ansible.verbose = 'vvvv' ansible.compatibility_mode = "2.0" end diff --git a/test/integration/common.rb b/test/integration/common.rb index 6295ada..8fe0881 100644 --- a/test/integration/common.rb +++ b/test/integration/common.rb @@ -110,7 +110,15 @@ module IntegrationTestHelpers # down sshd. if pid system('sudo', 'kill', '-15', pid.to_s) - Process.wait(pid) + begin + Timeout.timeout(5) do + Process.wait(pid) + end + rescue Timeout::Error + warn "Failed to kill net-ssh process: #{pid}" + system('sudo', 'kill', '-9', pid) + raise + end end end diff --git a/test/integration/playbook.yml b/test/integration/playbook.yml index 5c6a33a..ae9b96c 100644 --- a/test/integration/playbook.yml +++ b/test/integration/playbook.yml @@ -93,13 +93,20 @@ - name: add host aliases lineinfile: dest='/etc/hosts' owner='root' group='root' mode=0644 regexp='^127\.0\.0\.1\s+gateway.netssh' line='127.0.0.1 gateway.netssh' - - apt: + - name: Update APT Cache + apt: + update_cache: yes + force_apt_get: yes + - name: Wait for locfile removal + become: yes + shell: while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 5; done; + - name: Install packages + apt: pkg: - pv - libgmp3-dev - git state: present - update_cache: yes - copy: content='echo "cd /net-ssh ; rake integration-test"' dest=/etc/update-motd.d/99-net-ssh-tests mode=0755 - name: add user to rvm group so they can change gem wrappers user: diff --git a/test/transport/kex/test_ecdh_sha2_nistp256.rb b/test/transport/kex/test_ecdh_sha2_nistp256.rb index 932d8d7..3489230 100644 --- a/test/transport/kex/test_ecdh_sha2_nistp256.rb +++ b/test/transport/kex/test_ecdh_sha2_nistp256.rb @@ -1,7 +1,7 @@ require 'openssl' require 'ostruct' require_relative '../../common' -require 'transport/kex/test_diffie_hellman_group1_sha1' +require_relative './test_diffie_hellman_group1_sha1' require 'net/ssh/transport/kex/ecdh_sha2_nistp256' module Transport diff --git a/test/transport/test_algorithms.rb b/test/transport/test_algorithms.rb index 105f3af..aac8b9a 100644 --- a/test/transport/test_algorithms.rb +++ b/test/transport/test_algorithms.rb @@ -18,7 +18,7 @@ module Transport end def test_constructor_should_build_default_list_of_preferred_algorithms - assert_equal ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa], algorithms[:host_key] + assert_equal ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512], algorithms[:host_key] assert_equal x25519_kex + ec_kex + %w[diffie-hellman-group-exchange-sha256 diffie-hellman-group14-sha1], algorithms[:kex] assert_equal %w[aes256-ctr aes192-ctr aes128-ctr], algorithms[:encryption] assert_equal %w[hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512 hmac-sha2-256 hmac-sha1], algorithms[:hmac] @@ -27,7 +27,7 @@ module Transport end def test_constructor_should_build_complete_list_of_algorithms_with_append_all_supported_algorithms - assert_equal ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa ssh-dss], algorithms(append_all_supported_algorithms: true)[:host_key] + assert_equal ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512 ssh-dss], algorithms(append_all_supported_algorithms: true)[:host_key] assert_equal x25519_kex + ec_kex + %w[diffie-hellman-group-exchange-sha256 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1], algorithms(append_all_supported_algorithms: true)[:kex] assert_equal %w[aes256-ctr aes192-ctr aes128-ctr aes256-cbc aes192-cbc aes128-cbc rijndael-cbc@lysator.liu.se blowfish-ctr blowfish-cbc cast128-ctr cast128-cbc 3des-ctr 3des-cbc idea-cbc none], algorithms(append_all_supported_algorithms: true)[:encryption] assert_equal %w[hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512 hmac-sha2-256 hmac-sha1 hmac-sha2-512-96 hmac-sha2-256-96 hmac-sha1-96 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-md5 hmac-md5-96 none], algorithms(append_all_supported_algorithms: true)[:hmac] @@ -43,12 +43,12 @@ module Transport end def test_constructor_with_preferred_host_key_type_should_put_preferred_host_key_type_first - assert_equal %w[ssh-dss] + ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa], algorithms(host_key: "ssh-dss", append_all_supported_algorithms: true)[:host_key] + assert_equal %w[ssh-dss] + ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512], algorithms(host_key: "ssh-dss", append_all_supported_algorithms: true)[:host_key] end def test_constructor_with_known_hosts_reporting_known_host_key_should_use_that_host_key_type Net::SSH::KnownHosts.expects(:search_for).with("net.ssh.test,127.0.0.1", {}).returns([stub("key", ssh_type: "ssh-dss")]) - assert_equal %w[ssh-dss] + ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa], algorithms[:host_key] + assert_equal %w[ssh-dss] + ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512], algorithms[:host_key] end def ed_host_keys @@ -73,7 +73,7 @@ module Transport end def test_constructor_with_unrecognized_host_key_type_should_return_whats_supported - assert_equal ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa ssh-dss], + assert_equal ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512 ssh-dss], algorithms(host_key: "bogus ssh-rsa", append_all_supported_algorithms: true)[:host_key] end @@ -182,7 +182,7 @@ module Transport end def test_constructor_with_host_key_removals_with_wildcard - assert_equal ed_host_keys + %w[ecdsa-sha2-nistp521-cert-v01@openssh.com ecdsa-sha2-nistp384-cert-v01@openssh.com ecdsa-sha2-nistp256-cert-v01@openssh.com ecdsa-sha2-nistp521 ecdsa-sha2-nistp384 ecdsa-sha2-nistp256], algorithms(host_key: %w[-ssh-rsa* -ssh-dss])[:host_key] + assert_equal ed_host_keys + %w[ecdsa-sha2-nistp521-cert-v01@openssh.com ecdsa-sha2-nistp384-cert-v01@openssh.com ecdsa-sha2-nistp256-cert-v01@openssh.com ecdsa-sha2-nistp521 ecdsa-sha2-nistp384 ecdsa-sha2-nistp256], algorithms(host_key: %w[-ssh-rsa* -ssh-dss -rsa-sha*])[:host_key] end def test_initial_state_should_be_neither_pending_nor_initialized @@ -407,7 +407,7 @@ module Transport assert_equal KEXINIT, buffer.type assert_equal 16, buffer.read(16).length assert_equal options[:kex] || (x25519_kex + ec_kex + %w[diffie-hellman-group-exchange-sha256 diffie-hellman-group14-sha1]).join(','), buffer.read_string - assert_equal options[:host_key] || (ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa]).join(','), buffer.read_string + assert_equal options[:host_key] || (ed_ec_host_keys + %w[ssh-rsa-cert-v01@openssh.com ssh-rsa-cert-v00@openssh.com ssh-rsa rsa-sha2-256 rsa-sha2-512]).join(','), buffer.read_string assert_equal options[:encryption_client] || 'aes256-ctr,aes192-ctr,aes128-ctr', buffer.read_string assert_equal options[:encryption_server] || 'aes256-ctr,aes192-ctr,aes128-ctr', buffer.read_string assert_equal options[:hmac_client] || 'hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1', buffer.read_string |