debian-mirror-gitlab/lib/gitlab/ssh_public_key.rb

90 lines
2.2 KiB
Ruby
Raw Normal View History

2018-12-13 13:39:08 +05:30
# frozen_string_literal: true
2018-03-17 18:26:18 +05:30
module Gitlab
class SSHPublicKey
Technology = Struct.new(:name, :key_class, :supported_sizes)
2019-02-15 15:39:39 +05:30
TECHNOLOGIES = [
2018-03-17 18:26:18 +05:30
Technology.new(:rsa, OpenSSL::PKey::RSA, [1024, 2048, 3072, 4096]),
Technology.new(:dsa, OpenSSL::PKey::DSA, [1024, 2048, 3072]),
Technology.new(:ecdsa, OpenSSL::PKey::EC, [256, 384, 521]),
Technology.new(:ed25519, Net::SSH::Authentication::ED25519::PubKey, [256])
].freeze
def self.technology(name)
2019-02-15 15:39:39 +05:30
TECHNOLOGIES.find { |tech| tech.name.to_s == name.to_s }
2018-03-17 18:26:18 +05:30
end
def self.technology_for_key(key)
2019-02-15 15:39:39 +05:30
TECHNOLOGIES.find { |tech| key.is_a?(tech.key_class) }
2018-03-17 18:26:18 +05:30
end
def self.supported_sizes(name)
technology(name)&.supported_sizes
end
2018-03-27 19:54:05 +05:30
def self.sanitize(key_content)
ssh_type, *parts = key_content.strip.split
return key_content if parts.empty?
2018-12-13 13:39:08 +05:30
parts.each_with_object(+"#{ssh_type} ").with_index do |(part, content), index|
2018-03-27 19:54:05 +05:30
content << part
if Gitlab::SSHPublicKey.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
end
end
end
2018-03-17 18:26:18 +05:30
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
@key =
begin
Net::SSH::KeyFactory.load_data_public_key(key_text)
rescue StandardError, NotImplementedError
end
end
def valid?
2018-03-27 19:54:05 +05:30
SSHKey.valid_ssh_public_key?(key_text)
2018-03-17 18:26:18 +05:30
end
def type
2018-03-27 19:54:05 +05:30
technology.name if key.present?
2018-03-17 18:26:18 +05:30
end
def bits
2018-03-27 19:54:05 +05:30
return if key.blank?
2018-03-17 18:26:18 +05:30
case type
when :rsa
2018-03-27 19:54:05 +05:30
key.n&.num_bits
2018-03-17 18:26:18 +05:30
when :dsa
2018-03-27 19:54:05 +05:30
key.p&.num_bits
2018-03-17 18:26:18 +05:30
when :ecdsa
2018-03-27 19:54:05 +05:30
key.group.order&.num_bits
2018-03-17 18:26:18 +05:30
when :ed25519
256
else
raise "Unsupported key type: #{type}"
end
end
private
def technology
@technology ||=
self.class.technology_for_key(key) || raise("Unsupported key type: #{key.class}")
end
end
end