summaryrefslogtreecommitdiff
path: root/lib/net
diff options
context:
space:
mode:
authorMiklós Fazekas <mfazekas@szemafor.com>2021-08-05 08:53:06 +0200
committerMiklós Fazekas <mfazekas@szemafor.com>2021-08-05 08:53:06 +0200
commit3f55af876caf797e89e9288aa4084897cded41bb (patch)
treede09927ef2dcf12e5f9cb8f63f29968c767a2262 /lib/net
parent52d16fbe353b8eb9669e967d1922cbaa4c904c21 (diff)
downloadnet-ssh-3f55af876caf797e89e9288aa4084897cded41bb.tar.gz
Initial version of cert base host auth
Diffstat (limited to 'lib/net')
-rw-r--r--lib/net/ssh/known_hosts.rb43
-rw-r--r--lib/net/ssh/verifiers/always.rb5
2 files changed, 36 insertions, 12 deletions
diff --git a/lib/net/ssh/known_hosts.rb b/lib/net/ssh/known_hosts.rb
index f3d773a..7fbda9b 100644
--- a/lib/net/ssh/known_hosts.rb
+++ b/lib/net/ssh/known_hosts.rb
@@ -6,6 +6,21 @@ require 'net/ssh/authentication/ed25519_loader'
module Net
module SSH
+ class HostCertPub
+ def ssh_type
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com"
+ end
+
+ def initialize(content)
+ @content = content
+ end
+
+ def matches?(server_key)
+ certblob = Buffer.new(server_key).read_key
+ certblob.signature_valid? && (certblob.signature_key.to_blob == @content.to_blob)
+ end
+ end
+
# Represents the result of a search in known hosts
# see search_for
class HostKeys
@@ -127,22 +142,28 @@ module Net
File.open(source) do |file|
file.each_line do |line|
- hosts, type, key_content = line.split(' ')
- # Skip empty line or one that is commented
- next if hosts.nil? || hosts.start_with?('#')
+ if line.start_with?("@cert-authority ")
+ cert_auth, hosts, type, key_content = line.split(' ')
+ blob = key_content.unpack("m*").first
+ keys << HostCertPub.new(Net::SSH::Buffer.new(blob).read_key )
+ else
+ hosts, type, key_content = line.split(' ')
+ # Skip empty line or one that is commented
+ next if hosts.nil? || hosts.start_with?('#')
- hostlist = hosts.split(',')
+ hostlist = hosts.split(',')
- next unless SUPPORTED_TYPE.include?(type)
+ next unless SUPPORTED_TYPE.include?(type)
- found = hostlist.any? { |pattern| match(host_name, pattern) } || known_host_hash?(hostlist, entries)
- next unless found
+ found = hostlist.any? { |pattern| match(host_name, pattern) } || known_host_hash?(hostlist, entries)
+ next unless found
- found = hostlist.include?(host_ip) if options[:check_host_ip] && entries.size > 1 && hostlist.size > 1
- next unless found
+ found = hostlist.include?(host_ip) if options[:check_host_ip] && entries.size > 1 && hostlist.size > 1
+ next unless found
- blob = key_content.unpack("m*").first
- keys << Net::SSH::Buffer.new(blob).read_key
+ blob = key_content.unpack("m*").first
+ keys << Net::SSH::Buffer.new(blob).read_key
+ end
end
end
diff --git a/lib/net/ssh/verifiers/always.rb b/lib/net/ssh/verifiers/always.rb
index 0f52a29..48c70bb 100644
--- a/lib/net/ssh/verifiers/always.rb
+++ b/lib/net/ssh/verifiers/always.rb
@@ -23,7 +23,10 @@ module Net
# blob also match.
found = host_keys.any? do |key|
key.ssh_type == arguments[:key].ssh_type &&
- key.to_blob == arguments[:key].to_blob
+ (
+ (key.respond_to?(:to_blob) && key.to_blob == arguments[:key].to_blob) ||
+ (key.respond_to?(:matches?) && key.matches?(arguments[:key].to_blob))
+ )
end
# If a match was found, return true. Otherwise, raise an exception