sshkey 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +16 -0
- data/lib/sshkey.rb +60 -0
- data/lib/sshkey/version.rb +3 -0
- data/sshkey.gemspec +21 -0
- data/test/sshkey_test.rb +121 -0
- metadata +63 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
7
|
+
desc 'Default: run unit tests.'
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
desc 'Test the sshkey gem.'
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
12
|
+
t.libs << 'lib'
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = true
|
16
|
+
end
|
data/lib/sshkey.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
class SSHKey
|
5
|
+
|
6
|
+
def self.generate(comment)
|
7
|
+
SSHKey.new(OpenSSL::PKey::RSA.generate(2048), comment)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :key_object, :comment, :rsa_private_key, :rsa_public_key, :ssh_public_key
|
11
|
+
|
12
|
+
def initialize(key_object, comment)
|
13
|
+
@key_object = key_object
|
14
|
+
@comment = comment
|
15
|
+
@rsa_private_key = key_object.to_pem
|
16
|
+
@rsa_public_key = key_object.public_key.to_pem
|
17
|
+
@ssh_public_key = ["ssh-rsa", Base64.strict_encode64(ssh_public_key_conversion), @comment].join(" ")
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# All data type encoding is defined in the section #5 of RFC #4251.
|
23
|
+
# String and mpint (multiple precision integer) types are encoded this way :
|
24
|
+
# 4-bytes word: data length (unsigned big-endian 32 bits integer)
|
25
|
+
# n bytes : binary representation of the data
|
26
|
+
|
27
|
+
# For instance, the "ssh-rsa" string is encoded as the following byte array
|
28
|
+
# [0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a']
|
29
|
+
def ssh_public_key_conversion
|
30
|
+
e = @key_object.public_key.e.to_i
|
31
|
+
n = @key_object.public_key.n.to_i
|
32
|
+
|
33
|
+
out = [0,0,0,7].pack("c*")
|
34
|
+
out += "ssh-rsa"
|
35
|
+
out += encode_unsigned_int_32(to_byte_array(e).length).pack("c*")
|
36
|
+
out += to_byte_array(e).pack("c*")
|
37
|
+
out += encode_unsigned_int_32(to_byte_array(n).length).pack("c*")
|
38
|
+
out += to_byte_array(n).pack("c*")
|
39
|
+
|
40
|
+
return out
|
41
|
+
end
|
42
|
+
|
43
|
+
def encode_unsigned_int_32(value)
|
44
|
+
out = []
|
45
|
+
out[0] = value >> 24 & 0xff
|
46
|
+
out[1] = value >> 16 & 0xff
|
47
|
+
out[2] = value >> 8 & 0xff
|
48
|
+
out[3] = value & 0xff
|
49
|
+
return out
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_byte_array(num)
|
53
|
+
result = []
|
54
|
+
begin
|
55
|
+
result << (num & 0xff)
|
56
|
+
num >>= 8
|
57
|
+
end until (num == 0 || num == -1) && (result.last[7] == num[7])
|
58
|
+
result.reverse
|
59
|
+
end
|
60
|
+
end
|
data/sshkey.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "sshkey/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "sshkey"
|
7
|
+
s.version = SSHKey::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["James Miller"]
|
10
|
+
s.email = ["bensie@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/bensie/sshkey"
|
12
|
+
s.summary = %q{SSH private/public key generator in Ruby}
|
13
|
+
s.description = %q{Generate private/public SSH keys using Ruby without the ssh-keygen system command.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "sshkey"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
data/test/sshkey_test.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'sshkey'
|
3
|
+
|
4
|
+
class SSHKeyTest < Test::Unit::TestCase
|
5
|
+
SSH_PRIVATE_KEY1 = <<-EOF
|
6
|
+
-----BEGIN RSA PRIVATE KEY-----
|
7
|
+
MIIEogIBAAKCAQEArfTA/lKVR84IMc9ZzXOCHr8DVtR8hzWuEVHF6KElavRHlk14
|
8
|
+
g0SZu3m908Ejm/XF3EfNHjX9wN+62IMA0QBxkBMFCuLF+U/oeUs0NoDdAEKxjj4n
|
9
|
+
6lq6Ss8aLct+anMy7D1jwvOLbcwV54w1d5JDdlZVdZ6AvHm9otwJq6rNpDgdmXY4
|
10
|
+
HgC2nM9csFpuy0cDpL6fdJx9lcNL2RnkRC4+RMsIB+PxDw0j3vDi04dYLBXMGYjy
|
11
|
+
eGH+mIFpL3PTPXGXwL2XDYXZ2H4SQX6bOoKmazTXq6QXuEB665njh1GxXldoIMcS
|
12
|
+
shoJL0hrk3WrTOG22N2CQA+IfHgrXJ+A+QUzKQIBIwKCAQBAnLy2O+5N3s/X/I8R
|
13
|
+
y9E+nrgY79Z7XRTEmrc5JelTnI+eOggwwbVxhP1dR7zE5kItPz2O4NqYGJXbY9u7
|
14
|
+
V++qiri65oQMJP6Tc7ROwiYzS/jObtugMFPSpLHzwJyrMho6fTOuz3zuRH0qHiJ8
|
15
|
+
3o4WAs9I8brJqY+UQxmI56t3gfHcX4nRhueyUvmEdDG+4Mob21wED1GD5ENh9ebX
|
16
|
+
UiuYkeROqd+lfBUkWoxUXi2fjRMSRt7n3bq59pyZQCwKiShIVaonciV8xAAlNvhI
|
17
|
+
RBzYvXbQ47YgsTmcW4Srlv0j/Oij2/RaDhkJtaXyPkqw9k4B8oCaX3C2x4sdhcwa
|
18
|
+
iLU7AoGBANb4Rmz1w4wfZSnu/HlW4G0Us+AWVEX+6zePoOartP5Pe5t3XhHW7vpi
|
19
|
+
YoB4ecqhz4Y1LoYZL07cSsQZHfntUV4eh/apuo/5slrhDkk0ewJkUh6SKLOFNv6Q
|
20
|
+
7iJnmtzzRovW1MQPa0NeInsUrZYe4B4iGZmK4yEr9+c7IQCPFQvVAoGBAM8ofVgb
|
21
|
+
gzDYY2uX1lvU9bGAHqA/qNJHcYZBu5AZr7bkZC1GlSKh93ppczdQhiZmj2FQr09R
|
22
|
+
Z5GgKIlSWk8MYC+kYq7l5r2O42g3Unp+i1Zc5KCYUWYpyeE/jfl5IFJFQJFVtdB1
|
23
|
+
JlsFxruQIF/HuTzY6D+zF8GzK/T5ZQwigBgFAoGAGJFnImU663FNY+DMZaOHXOxs
|
24
|
+
VB/PHfE/dBBqKP2uSPMkEcR/x4ZHMo7mr5i9dj5g3CNVxi7Dk/vrSZx4dFWi5i9f
|
25
|
+
/u7TfisqU4dvWNLMOsmi/C32BeNWvgHvVGOcq4mEZ8DH2+SBSYcZ4i4/uWKdRUW5
|
26
|
+
yGek7dkjpWXX4s6GD/sCgYEAiCHr+BIUYe1Ipcotx1FuQXFzNhs0bO0et0/EZgJA
|
27
|
+
RPx8WERTX+bHMy9aV4yv7VlW6C21CDzPB+zncC7NoakMAgzwZE3vZp+6AqgDAAoD
|
28
|
+
ywnYEcMuLTFnaCJzPYocjdW8t0bz0iEZNIAjgpHpY4M/Np0q6Af5qyyZOpVCZw9b
|
29
|
+
fX8CgYEAqFpBwetp78UfwvWyKkfN56cY8EaC7gMkwE4gnXsByrqW0f/Shf5ofpO1
|
30
|
+
kCMav5GhplRYcF3mUO9xiAPx1FxWj/MjeevkmmugIrcYi5OpGu70KoaBmCmb5uV6
|
31
|
+
zJLsX4h3i0JFdIOaECZEOXhPA7btQT8Vvznj8cHFeeronqdFWf0=
|
32
|
+
-----END RSA PRIVATE KEY-----
|
33
|
+
EOF
|
34
|
+
SSH_PRIVATE_KEY2 = <<-EOF
|
35
|
+
-----BEGIN RSA PRIVATE KEY-----
|
36
|
+
MIIEogIBAAKCAQEAxl6TpN7uFiY/JZ8qDnD7UrxDP+ABeh2PVg8Du1LEgXNk0+YW
|
37
|
+
CeP5S6oHklqaWeDlbmAs1oHsBwCMAVpMa5tgONOLvz4JgwgkiqQEbKR8ofWJ+LAD
|
38
|
+
UElvqRVGmGiNEMLI6GJWeneL4sjmbb8d6U+M53c6iWG0si9XE5m7teBQSsCl0Tk3
|
39
|
+
qMIkQGw5zpJeCXjZ8KpJhIJRYgexFkGgPlYRV+UYIhxpUW90t0Ra5i6JOFYwq98k
|
40
|
+
5S/6SJIZQ/A9F4JNzwLw3eVxZj0yVHWxkGz1+TyELNY1kOyMxnZaqSfGzSQJTrnI
|
41
|
+
XpdweVHuYh1LtOgedRQhCyiELeSMGwio1vRPKwIBIwKCAQEAiAZWnPCjQmNegDKg
|
42
|
+
fu5jMWsmzLbccP5TqLnWrFYDFvAKn+46/3fA421HBUVxJ7AoS6+pt6mL54tYsHhu
|
43
|
+
6rOvsfAlT/AGhbxw1Biyk6P9sOLiRCDsVE+dBjp5jRR9/N1WkLh10FH5hZETCW0b
|
44
|
+
0y88DG8DkWeR2UUIgngLr+pFr5jV/e4nvA5QpvbNscOwoiR7sFsMGLcMgM2fT4Hj
|
45
|
+
ZZovcGQMrDr6AG+y0/Vdf9wX22j+XKj7huIqM3GZvyqGPqJnP9sOKkPcuTck8Wx3
|
46
|
+
55BX675RVdoW9OTcHbUh3qHcCND4d9WZqHarW/a7XBdIiuRmC2kBX5WBmVXnm/RF
|
47
|
+
bvxoCwKBgQDqyVNWwm98gIw7LS8dR6Ec7t3kOeLNo/rtNTszo631yZ4hqdwgYR3Q
|
48
|
+
q6rhjufsVVRLVzfTDXucbhZ5h+UB9wXAM49ZPxKNw+ddHsRbhCuIWUl/iO8E/Aub
|
49
|
+
H3eZupo73N9JGa4STFw056ejOQrTTCMf0M316V4wgFAXOZeHEErxSQKBgQDYSuqR
|
50
|
+
nr3Hdw1n/iXfKrfd9fJI++nm14uQ4mkA+9HrtQpj/RTxr66/QSj7p3r6GF4dDYY4
|
51
|
+
XaqK+iCfhUKMr8+3CP7NoS/saZAUqvMnL+RCvX14sV55xRMwplaaNIwqDhQAhkmL
|
52
|
+
UeOBq40kmBsunjfp06JedmWhWKHYc1eR2iPw0wKBgA1qlwxFn/h8X8jeArE3Swj3
|
53
|
+
tOh4VhphJEgRq5yNAqBUqfNLiOvoSti5WjjGVmVGtFwTnMo7SOReD+mv/nUkDvUK
|
54
|
+
QrSkhLeky2RoKHpCER279ZJCVs0Vt4U0/4UgmxldFBLORHYS/fRlAkPXX7RNflmW
|
55
|
+
5zKfnvt1C+QR62bNuyO7AoGBAI4imiUtzStOPAKCcKiYajLGMYBrB2vPePjPTFEa
|
56
|
+
gqI1JBXSMlWt9n2uegR1X3El9LQBkrdTfrMZZeUrr2PD/Ybop3EvaKKrxRTlXfUu
|
57
|
+
GagzYRTMVAbgl5T/l/7vVMst0qFCTZYRPbucnpRj9Jr6QgAOuygh6wOgpN6yMjtG
|
58
|
+
NOAVAoGACIdfR5oZ4tvNIeqjtLF83HmUJARv86eMmjqgiQTFcZS3A8vk5y05STxX
|
59
|
+
HU3kTCfT6sypRi9zDQafIIyqYFgaOezr2eRRFRojQZqzHjtuFUeKLrKf7R9bzwwx
|
60
|
+
DPlNgYq8p4FOY5ZOL/ZOxUHW4vKRewURJttnxzw+LEy0T1FyAE0=
|
61
|
+
-----END RSA PRIVATE KEY-----
|
62
|
+
EOF
|
63
|
+
|
64
|
+
SSH_PUBLIC_KEY1 = 'AAAAB3NzaC1yc2EAAAABIwAAAQEArfTA/lKVR84IMc9ZzXOCHr8DVtR8hzWuEVHF6KElavRHlk14g0SZu3m908Ejm/XF3EfNHjX9wN+62IMA0QBxkBMFCuLF+U/oeUs0NoDdAEKxjj4n6lq6Ss8aLct+anMy7D1jwvOLbcwV54w1d5JDdlZVdZ6AvHm9otwJq6rNpDgdmXY4HgC2nM9csFpuy0cDpL6fdJx9lcNL2RnkRC4+RMsIB+PxDw0j3vDi04dYLBXMGYjyeGH+mIFpL3PTPXGXwL2XDYXZ2H4SQX6bOoKmazTXq6QXuEB665njh1GxXldoIMcSshoJL0hrk3WrTOG22N2CQA+IfHgrXJ+A+QUzKQ=='
|
65
|
+
SSH_PUBLIC_KEY2 = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAxl6TpN7uFiY/JZ8qDnD7UrxDP+ABeh2PVg8Du1LEgXNk0+YWCeP5S6oHklqaWeDlbmAs1oHsBwCMAVpMa5tgONOLvz4JgwgkiqQEbKR8ofWJ+LADUElvqRVGmGiNEMLI6GJWeneL4sjmbb8d6U+M53c6iWG0si9XE5m7teBQSsCl0Tk3qMIkQGw5zpJeCXjZ8KpJhIJRYgexFkGgPlYRV+UYIhxpUW90t0Ra5i6JOFYwq98k5S/6SJIZQ/A9F4JNzwLw3eVxZj0yVHWxkGz1+TyELNY1kOyMxnZaqSfGzSQJTrnIXpdweVHuYh1LtOgedRQhCyiELeSMGwio1vRPKw=='
|
66
|
+
|
67
|
+
FINGERPRINT = "2a:89:84:c9:29:05:d1:f8:49:79:1c:ba:73:99:eb:af"
|
68
|
+
|
69
|
+
def setup
|
70
|
+
@key1 = SSHKey.new(OpenSSL::PKey::RSA.new(SSH_PRIVATE_KEY1), "me@example.com")
|
71
|
+
@key2 = SSHKey.new(OpenSSL::PKey::RSA.new(SSH_PRIVATE_KEY2), "me@example.com")
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_private_key1
|
75
|
+
assert_equal SSH_PRIVATE_KEY1, @key1.rsa_private_key
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_private_key2
|
79
|
+
assert_equal SSH_PRIVATE_KEY2, @key2.rsa_private_key
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_ssh_public_key_decoded1
|
83
|
+
assert_equal Base64.strict_decode64(SSH_PUBLIC_KEY1), @key1.send(:ssh_public_key_conversion)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_ssh_public_key_decoded2
|
87
|
+
assert_equal Base64.strict_decode64(SSH_PUBLIC_KEY2), @key2.send(:ssh_public_key_conversion)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_ssh_public_key_encoded1
|
91
|
+
assert_equal SSH_PUBLIC_KEY1, Base64.strict_encode64(@key1.send(:ssh_public_key_conversion))
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_ssh_public_key_encoded2
|
95
|
+
assert_equal SSH_PUBLIC_KEY2, Base64.strict_encode64(@key2.send(:ssh_public_key_conversion))
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_ssh_public_key_output
|
99
|
+
expected1 = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArfTA/lKVR84IMc9ZzXOCHr8DVtR8hzWuEVHF6KElavRHlk14g0SZu3m908Ejm/XF3EfNHjX9wN+62IMA0QBxkBMFCuLF+U/oeUs0NoDdAEKxjj4n6lq6Ss8aLct+anMy7D1jwvOLbcwV54w1d5JDdlZVdZ6AvHm9otwJq6rNpDgdmXY4HgC2nM9csFpuy0cDpL6fdJx9lcNL2RnkRC4+RMsIB+PxDw0j3vDi04dYLBXMGYjyeGH+mIFpL3PTPXGXwL2XDYXZ2H4SQX6bOoKmazTXq6QXuEB665njh1GxXldoIMcSshoJL0hrk3WrTOG22N2CQA+IfHgrXJ+A+QUzKQ== me@example.com"
|
100
|
+
expected2 = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxl6TpN7uFiY/JZ8qDnD7UrxDP+ABeh2PVg8Du1LEgXNk0+YWCeP5S6oHklqaWeDlbmAs1oHsBwCMAVpMa5tgONOLvz4JgwgkiqQEbKR8ofWJ+LADUElvqRVGmGiNEMLI6GJWeneL4sjmbb8d6U+M53c6iWG0si9XE5m7teBQSsCl0Tk3qMIkQGw5zpJeCXjZ8KpJhIJRYgexFkGgPlYRV+UYIhxpUW90t0Ra5i6JOFYwq98k5S/6SJIZQ/A9F4JNzwLw3eVxZj0yVHWxkGz1+TyELNY1kOyMxnZaqSfGzSQJTrnIXpdweVHuYh1LtOgedRQhCyiELeSMGwio1vRPKw== me@example.com"
|
101
|
+
assert_equal expected1, @key1.ssh_public_key
|
102
|
+
assert_equal expected2, @key2.ssh_public_key
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_exponent
|
106
|
+
assert_equal 35, @key1.key_object.e.to_i
|
107
|
+
assert_equal 35, @key2.key_object.e.to_i
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_modulus
|
111
|
+
assert_equal 21959919395955180268707532246136630338880737002345156586705317733493418045367765414088155418090419238250026039981229751319343545922377196559932805781226688384973919515037364518167604848468288361633800200593870224270802677578686553567598208927704479575929054501425347794297979215349516030584575472280923909378896367886007339003194417496761108245404573433556449606964806956220743380296147376168499567508629678037211105349574822849913423806275470761711930875368363589001630573570236600319099783704171412637535837916991323769813598516411655563604244942820475880695152610674934239619752487880623016350579174487901241422633, @key1.key_object.n.to_i
|
112
|
+
assert_equal 25041821909255634338594631709409930006900629565221199423527442992482865961613864019776541767273966885435978473182530882048894721263421597979360058644777295324028381353356143013803778109979347540540538361684778724178534886189535456555760676722894784592989232554962714835255398111716791175503010379276254975882143986862239829255392231575481418297073759441882528318940783011390002193682320028951031205422825662402426266933458263786546846123394508656926946338411182471843223455365249418245551220933173115037201835242811305615780499842939975996344432437312062643436832423359634116147870328774728910949553186982115987967787, @key2.key_object.n.to_i
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_to_byte_array
|
116
|
+
ba1 = @key1.send(:to_byte_array, 35)
|
117
|
+
ba2 = @key1.send(:to_byte_array, 65537)
|
118
|
+
assert_equal [35], ba1
|
119
|
+
assert_equal [1, 0, 1], ba2
|
120
|
+
end
|
121
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sshkey
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- James Miller
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-03-12 00:00:00 -08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Generate private/public SSH keys using Ruby without the ssh-keygen system command.
|
18
|
+
email:
|
19
|
+
- bensie@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- Gemfile
|
29
|
+
- Rakefile
|
30
|
+
- lib/sshkey.rb
|
31
|
+
- lib/sshkey/version.rb
|
32
|
+
- sshkey.gemspec
|
33
|
+
- test/sshkey_test.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: https://github.com/bensie/sshkey
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project: sshkey
|
58
|
+
rubygems_version: 1.5.1
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: SSH private/public key generator in Ruby
|
62
|
+
test_files:
|
63
|
+
- test/sshkey_test.rb
|