From 246058ffbb8f1c2ba09e6da96fe400915cb9a916 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Mon, 12 Apr 2021 17:28:52 -0700 Subject: [PATCH 1/2] Add `#signature_algorithm` and update `#ssh_do_sign` and `#to_blob` Modifies `OpenSSL::PKey::RSA` to provide a `#signature_algorithm` method which provides the signature algorithm value expected by OpenSSH. The `#ssh_do_sign` method is updated to use the set algorithm (SHA256) and `#to_blob` is updated to include the signature algorithm instead of the key type. --- lib/vagrant/patches/net-ssh.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/vagrant/patches/net-ssh.rb b/lib/vagrant/patches/net-ssh.rb index 35b0292a0..bdd717048 100644 --- a/lib/vagrant/patches/net-ssh.rb +++ b/lib/vagrant/patches/net-ssh.rb @@ -99,6 +99,18 @@ if Net::SSH::Version::STRING == "6.1.0" verify(digester, sig, data) end + + def signature_algorithm + "rsa-sha2-256" + end + + def ssh_do_sign(data) + sign(OpenSSL::Digest::SHA256.new, data) + end + + def to_blob + @blob ||= Net::SSH::Buffer.from(:string, signature_algorithm, :bignum, e, :bignum, n).to_s + end end OpenSSL::PKey::DSA.class_eval do From a08597d7878bce2b1e7642edd4548d6388f9f8cf Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Mon, 12 Apr 2021 17:33:01 -0700 Subject: [PATCH 2/2] Tighten constraints on net-ssh to ensure functionality. Update patch Keep the constraint on net-ssh tight so we can be confident that the patching will be successful and that a net-ssh release won't inadvertently cause our local updates to become non-functional. Fix patch to only update the behavior for RSA based keys when the server is recent enough to include the signature changes --- lib/vagrant/patches/net-ssh.rb | 42 ++++++++++++++++++++++++++++++---- vagrant.gemspec | 2 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/vagrant/patches/net-ssh.rb b/lib/vagrant/patches/net-ssh.rb index bdd717048..a5d65a23a 100644 --- a/lib/vagrant/patches/net-ssh.rb +++ b/lib/vagrant/patches/net-ssh.rb @@ -4,6 +4,32 @@ require "net/ssh" # these patches pull 6.1.0 up to the as of now # current 6.2.0 beta if Net::SSH::Version::STRING == "6.1.0" + require "net/ssh/authentication/methods/publickey" + Net::SSH::Authentication::Methods::Publickey.class_eval do + def rsa_compat_build_request(pub_key, *args) + s_ver_str = session.transport.server_version.version.match(/OpenSSH_(?\d+\.\d+)/)[:version] + begin + s_ver = Gem::Version.new(s_ver_str) + if s_ver >= Gem::Version.new("7.2") && pub_key.is_a?(OpenSSL::PKey::RSA) + pub_key.deprecated_ssh_rsa = true + debug { "public key has been marked for deprecated ssh-rsa SHA1 behavior" } + info = key_manager.known_identities[pub_key] + if info && info[:key] + info[:key].deprecated_ssh_rsa = true + debug { "private key has been marked for deprecated ssh-rsa SHA1 behavior" } + else + warn { "cannot deprecate ssh rsa on private key, not loaded (#{info[:file]})" } + end + end + rescue ArgumentError + warn { "failed to parse OpenSSH version (raw: #{session.transport.server_version.version} attempted: #{s_ver_str}" } + end + _raw_build_request(pub_key, *args) + end + alias_method :_raw_build_request, :build_request + alias_method :build_request, :rsa_compat_build_request + end + require "net/ssh/authentication/agent" # net/ssh/authentication/agent Net::SSH::Authentication::Agent.class_eval do @@ -87,6 +113,8 @@ if Net::SSH::Version::STRING == "6.1.0" require "net/ssh/transport/openssl" # net/ssh/transport/openssl OpenSSL::PKey::RSA.class_eval do + attr_accessor :deprecated_ssh_rsa + def ssh_do_verify(sig, data, options = {}) digester = if options[:host_key] == "rsa-sha2-512" @@ -100,16 +128,20 @@ if Net::SSH::Version::STRING == "6.1.0" verify(digester, sig, data) end + def ssh_type + deprecated_ssh_rsa ? signature_algorithm : "ssh-rsa" + end + def signature_algorithm "rsa-sha2-256" end def ssh_do_sign(data) - sign(OpenSSL::Digest::SHA256.new, data) - end - - def to_blob - @blob ||= Net::SSH::Buffer.from(:string, signature_algorithm, :bignum, e, :bignum, n).to_s + if deprecated_ssh_rsa + sign(OpenSSL::Digest::SHA256.new, data) + else + sign(OpenSSL::Digest::SHA1.new, data) + end end end diff --git a/vagrant.gemspec b/vagrant.gemspec index 1643681b4..99ed2083c 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency "listen", "~> 3.4" s.add_dependency "log4r", "~> 1.1.9", "< 1.1.11" s.add_dependency "mime-types", "~> 3.3" - s.add_dependency "net-ssh", ">= 6.1.0", "< 7" + s.add_dependency "net-ssh", ">= 6.1.0", "< 6.2" s.add_dependency "net-sftp", "~> 3.0" s.add_dependency "net-scp", "~> 1.2.0" s.add_dependency "rb-kqueue", "~> 0.2.0"