Skip to content

Commit 624fe2d

Browse files
committed
Re-implement SSHKey to remove sshkey gem dependency
Refactor the `VCAP::CloudController::Diego::SSHKey` class to remove the dependency on the `sshkey` gem. This change reduces external dependencies and avoids potential compilation issues related to native extensions. The class is re-implemented using the standard `openssl` and `digest` libraries. The public interface and output formats of the `private_key`, `authorized_key`, `fingerprint` (SHA1), and `sha256_fingerprint` methods are preserved, ensuring it acts as a transparent, drop-in replacement. The performance impact is negligible as the most expensive operation, RSA key generation, still relies on OpenSSL, and all derived values are memoized.
1 parent 3d8464b commit 624fe2d

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

Gemfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ gem 'sequel', '~> 5.97'
3636
gem 'sequel_pg', require: 'sequel'
3737
gem 'sinatra', '~> 3.2'
3838
gem 'sinatra-contrib'
39-
gem 'sshkey'
4039
gem 'statsd-ruby', '~> 1.5.0'
4140
gem 'steno'
4241
gem 'talentbox-delayed_job_sequel', '~> 4.3.0'

Gemfile.lock

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,6 @@ GEM
578578
spring (4.4.0)
579579
spring-commands-rspec (1.0.4)
580580
spring (>= 0.9.1)
581-
sshkey (3.0.0)
582581
statsd-ruby (1.5.0)
583582
steno (1.3.5)
584583
fluent-logger
@@ -710,7 +709,6 @@ DEPENDENCIES
710709
spork!
711710
spring
712711
spring-commands-rspec
713-
sshkey
714712
statsd-ruby (~> 1.5.0)
715713
steno
716714
talentbox-delayed_job_sequel (~> 4.3.0)

lib/cloud_controller/diego/ssh_key.rb

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'net/ssh'
2-
require 'sshkey'
2+
require 'openssl'
3+
require 'base64'
4+
require 'digest'
35

46
module VCAP
57
module CloudController
@@ -14,27 +16,42 @@ def private_key
1416
end
1517

1618
def authorized_key
17-
@authorized_key ||= begin
18-
type = key.ssh_type
19-
data = [key.to_blob].pack('m0')
20-
21-
"#{type} #{data}"
22-
end
19+
@authorized_key ||= "ssh-rsa #{Base64.strict_encode64(public_key_blob)}"
2320
end
2421

2522
def fingerprint
26-
@fingerprint ||= ::SSHKey.new(key.to_der).sha1_fingerprint
23+
@fingerprint ||= Digest::SHA1.hexdigest(public_key_blob).scan(/../).join(':')
2724
end
2825

2926
def sha256_fingerprint
30-
@sha256_fingerprint ||= ::SSHKey.new(key.to_der).sha256_fingerprint
27+
@sha256_fingerprint ||= Base64.strict_encode64(Digest::SHA256.digest(public_key_blob))
3128
end
3229

3330
private
3431

3532
def key
3633
@key ||= OpenSSL::PKey::RSA.new(@bits)
3734
end
35+
36+
def to_ssh_string(value)
37+
[value.bytesize].pack('N') + value
38+
end
39+
40+
def to_ssh_mpint(number)
41+
return to_ssh_string([0].pack('C')) if number.zero?
42+
43+
binary = number.to_s(2)
44+
binary = "\x00" + binary if binary.getbyte(0) & 0x80 != 0
45+
to_ssh_string(binary)
46+
end
47+
48+
def public_key_blob
49+
@public_key_blob ||= begin
50+
e = key.public_key.e
51+
n = key.public_key.n
52+
to_ssh_string('ssh-rsa') + to_ssh_mpint(e) + to_ssh_mpint(n)
53+
end
54+
end
3855
end
3956
end
4057
end

0 commit comments

Comments
 (0)