Patch net-ssh for ecdsa private keys
This patches net-ssh so it will properly handle loading and using ecdsa private keys. Patching is restricted to tested versions.
This commit is contained in:
parent
96f2039bcd
commit
2d5c9c0d12
@ -5,6 +5,7 @@ require "log4r"
|
|||||||
|
|
||||||
# Add patches to log4r to support trace level
|
# Add patches to log4r to support trace level
|
||||||
require "vagrant/patches/log4r"
|
require "vagrant/patches/log4r"
|
||||||
|
require "vagrant/patches/net-ssh"
|
||||||
# Set our log levels and include trace
|
# Set our log levels and include trace
|
||||||
require 'log4r/configurator'
|
require 'log4r/configurator'
|
||||||
Log4r::Configurator.custom_levels(*(["TRACE"] + Log4r::Log4rConfig::LogLevels))
|
Log4r::Configurator.custom_levels(*(["TRACE"] + Log4r::Log4rConfig::LogLevels))
|
||||||
|
|||||||
76
lib/vagrant/patches/net-ssh.rb
Normal file
76
lib/vagrant/patches/net-ssh.rb
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
require "net/ssh"
|
||||||
|
require "net/ssh/buffer"
|
||||||
|
|
||||||
|
# Set the version requirement for when net-ssh should be patched
|
||||||
|
NET_SSH_PATCH_REQUIREMENT = Gem::Requirement.new(">= 7.0.0", "< 7.2.2")
|
||||||
|
|
||||||
|
# This patch provides support for properly loading ECDSA private keys
|
||||||
|
if NET_SSH_PATCH_REQUIREMENT.satisfied_by?(Gem::Version.new(Net::SSH::Version::STRING))
|
||||||
|
Net::SSH::Buffer.class_eval do
|
||||||
|
def vagrant_read_private_keyblob(type)
|
||||||
|
case type
|
||||||
|
when /^ecdsa\-sha2\-(\w*)$/
|
||||||
|
curve_name_in_type = $1
|
||||||
|
curve_name_in_key = read_string
|
||||||
|
|
||||||
|
unless curve_name_in_type == curve_name_in_key
|
||||||
|
raise Net::SSH::Exception, "curve name mismatched (`#{curve_name_in_key}' with `#{curve_name_in_type}')"
|
||||||
|
end
|
||||||
|
|
||||||
|
public_key_oct = read_string
|
||||||
|
priv_key_bignum = read_bignum
|
||||||
|
begin
|
||||||
|
curvename = OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key]
|
||||||
|
group = OpenSSL::PKey::EC::Group.new(curvename)
|
||||||
|
point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
|
||||||
|
priv_bn = OpenSSL::BN.new(priv_key_bignum, 2)
|
||||||
|
asn1 = OpenSSL::ASN1::Sequence(
|
||||||
|
[
|
||||||
|
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(0)),
|
||||||
|
OpenSSL::ASN1::Sequence.new(
|
||||||
|
[
|
||||||
|
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
|
||||||
|
OpenSSL::ASN1::ObjectId(curvename)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
OpenSSL::ASN1::OctetString.new(
|
||||||
|
OpenSSL::ASN1::Sequence.new(
|
||||||
|
[
|
||||||
|
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(1)),
|
||||||
|
OpenSSL::ASN1::OctetString.new(priv_bn.to_s(2)),
|
||||||
|
OpenSSL::ASN1::ASN1Data.new(
|
||||||
|
[
|
||||||
|
OpenSSL::ASN1::BitString.new(point.to_octet_string(:uncompressed)),
|
||||||
|
], 1, :CONTEXT_SPECIFIC,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
).to_der
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
key = OpenSSL::PKey::EC.new(asn1.to_der)
|
||||||
|
|
||||||
|
return key
|
||||||
|
rescue OpenSSL::PKey::ECError
|
||||||
|
raise NotImplementedError, "unsupported key type `#{type}'"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
netssh_read_private_keyblob(type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :netssh_read_private_keyblob, :read_private_keyblob
|
||||||
|
alias_method :read_private_keyblob, :vagrant_read_private_keyblob
|
||||||
|
end
|
||||||
|
|
||||||
|
OpenSSL::PKey::EC::Point.class_eval do
|
||||||
|
include Net::SSH::Authentication::PubKeyFingerprint
|
||||||
|
def to_pem
|
||||||
|
"#{ssh_type} #{self.to_bn.to_s(2)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user