Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ssh_public_key.rb')
-rw-r--r--lib/gitlab/ssh_public_key.rb58
1 files changed, 38 insertions, 20 deletions
diff --git a/lib/gitlab/ssh_public_key.rb b/lib/gitlab/ssh_public_key.rb
index 314cc5e2db6..8a2f3bbe0ee 100644
--- a/lib/gitlab/ssh_public_key.rb
+++ b/lib/gitlab/ssh_public_key.rb
@@ -7,10 +7,12 @@ module Gitlab
# See https://man.openbsd.org/sshd#AUTHORIZED_KEYS_FILE_FORMAT for the list of
# supported algorithms.
TECHNOLOGIES = [
- Technology.new(:rsa, OpenSSL::PKey::RSA, [1024, 2048, 3072, 4096], %w(ssh-rsa)),
- Technology.new(:dsa, OpenSSL::PKey::DSA, [1024, 2048, 3072], %w(ssh-dss)),
- Technology.new(:ecdsa, OpenSSL::PKey::EC, [256, 384, 521], %w(ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521)),
- Technology.new(:ed25519, Net::SSH::Authentication::ED25519::PubKey, [256], %w(ssh-ed25519))
+ Technology.new(:rsa, SSHData::PublicKey::RSA, [1024, 2048, 3072, 4096], %w(ssh-rsa)),
+ Technology.new(:dsa, SSHData::PublicKey::DSA, [1024, 2048, 3072], %w(ssh-dss)),
+ Technology.new(:ecdsa, SSHData::PublicKey::ECDSA, [256, 384, 521], %w(ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521)),
+ Technology.new(:ed25519, SSHData::PublicKey::ED25519, [256], %w(ssh-ed25519)),
+ Technology.new(:ecdsa_sk, SSHData::PublicKey::SKECDSA, [256], %w(sk-ecdsa-sha2-nistp256@openssh.com)),
+ Technology.new(:ed25519_sk, SSHData::PublicKey::SKED25519, [256], %w(sk-ssh-ed25519@openssh.com))
].freeze
def self.technology(name)
@@ -18,7 +20,7 @@ module Gitlab
end
def self.technology_for_key(key)
- TECHNOLOGIES.find { |tech| key.is_a?(tech.key_class) }
+ TECHNOLOGIES.find { |tech| key.instance_of?(tech.key_class) }
end
def self.supported_types
@@ -45,7 +47,7 @@ module Gitlab
parts.each_with_object(+"#{ssh_type} ").with_index do |(part, content), index|
content << part
- if Gitlab::SSHPublicKey.new(content).valid?
+ if self.new(content).valid?
break [content, parts[index + 1]].compact.join(' ') # Add the comment part if present
elsif parts.size == index + 1 # return original content if we've reached the last element
break key_content
@@ -55,41 +57,53 @@ module Gitlab
attr_reader :key_text, :key
- # Unqualified MD5 fingerprint for compatibility
- delegate :fingerprint, to: :key, allow_nil: true
-
def initialize(key_text)
@key_text = key_text
+ # We need to strip options to parse key with options or in known_hosts
+ # format. See https://man.openbsd.org/sshd#AUTHORIZED_KEYS_FILE_FORMAT
+ # and https://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT
+ key_text_without_options = @key_text.to_s.match(/(\A|\s)(#{self.class.supported_algorithms.join('|')}).*/).to_s
+
@key =
begin
- Net::SSH::KeyFactory.load_data_public_key(key_text)
- rescue StandardError, NotImplementedError
+ SSHData::PublicKey.parse_openssh(key_text_without_options)
+ rescue SSHData::DecodeError
end
end
def valid?
- SSHKey.valid_ssh_public_key?(key_text)
+ key.present?
end
def type
- technology.name if key.present?
+ technology.name if valid?
+ end
+
+ def fingerprint
+ key.fingerprint(md5: true) if valid?
+ end
+
+ def fingerprint_sha256
+ 'SHA256:' + key.fingerprint(md5: false) if valid?
end
def bits
- return if key.blank?
+ return unless valid?
case type
when :rsa
- key.n&.num_bits
+ key.n.num_bits
when :dsa
- key.p&.num_bits
+ key.p.num_bits
when :ecdsa
- key.group.order&.num_bits
+ key.openssl.group.order.num_bits
when :ed25519
256
- else
- raise "Unsupported key type: #{type}"
+ when :ecdsa_sk
+ 256
+ when :ed25519_sk
+ 256
end
end
@@ -97,7 +111,11 @@ module Gitlab
def technology
@technology ||=
- self.class.technology_for_key(key) || raise("Unsupported key type: #{key.class}")
+ self.class.technology_for_key(key) || raise_unsupported_key_type_error
+ end
+
+ def raise_unsupported_key_type_error
+ raise("Unsupported key type: #{key.class}")
end
end
end