Class: Gitlab::SSHPublicKey

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/ssh_public_key.rb

Direct Known Subclasses

SshHostKey::Fingerprint

Defined Under Namespace

Classes: Technology

Constant Summary collapse

TECHNOLOGIES =
[
  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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key_text) ⇒ SSHPublicKey

Returns a new instance of SSHPublicKey.


47
48
49
50
51
52
53
54
55
# File 'lib/gitlab/ssh_public_key.rb', line 47

def initialize(key_text)
  @key_text = key_text

  @key =
    begin
      Net::SSH::KeyFactory.load_data_public_key(key_text)
    rescue StandardError, NotImplementedError
    end
end

Instance Attribute Details

#keyObject (readonly)

Returns the value of attribute key


42
43
44
# File 'lib/gitlab/ssh_public_key.rb', line 42

def key
  @key
end

#key_textObject (readonly)

Returns the value of attribute key_text


42
43
44
# File 'lib/gitlab/ssh_public_key.rb', line 42

def key_text
  @key_text
end

Class Method Details

.sanitize(key_content) ⇒ Object


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/gitlab/ssh_public_key.rb', line 26

def self.sanitize(key_content)
  ssh_type, *parts = key_content.strip.split

  return key_content if parts.empty?

  parts.each_with_object(+"#{ssh_type} ").with_index do |(part, content), index|
    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

.supported_sizes(name) ⇒ Object


22
23
24
# File 'lib/gitlab/ssh_public_key.rb', line 22

def self.supported_sizes(name)
  technology(name)&.supported_sizes
end

.technology(name) ⇒ Object


14
15
16
# File 'lib/gitlab/ssh_public_key.rb', line 14

def self.technology(name)
  TECHNOLOGIES.find { |tech| tech.name.to_s == name.to_s }
end

.technology_for_key(key) ⇒ Object


18
19
20
# File 'lib/gitlab/ssh_public_key.rb', line 18

def self.technology_for_key(key)
  TECHNOLOGIES.find { |tech| key.is_a?(tech.key_class) }
end

Instance Method Details

#bitsObject


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/gitlab/ssh_public_key.rb', line 65

def bits
  return if key.blank?

  case type
  when :rsa
    key.n&.num_bits
  when :dsa
    key.p&.num_bits
  when :ecdsa
    key.group.order&.num_bits
  when :ed25519
    256
  else
    raise "Unsupported key type: #{type}"
  end
end

#typeObject


61
62
63
# File 'lib/gitlab/ssh_public_key.rb', line 61

def type
  technology.name if key.present?
end

#valid?Boolean

Returns:

  • (Boolean)

57
58
59
# File 'lib/gitlab/ssh_public_key.rb', line 57

def valid?
  SSHKey.valid_ssh_public_key?(key_text)
end