sshkey 1.2.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +5 -1
- data/lib/sshkey.rb +74 -37
- data/lib/sshkey/version.rb +1 -1
- data/test/sshkey_test.rb +120 -15
- metadata +4 -4
data/README.md
CHANGED
@@ -53,9 +53,13 @@ k.comment
|
|
53
53
|
# => "foo@bar.com"
|
54
54
|
|
55
55
|
# Returns the MD5 fingerprint as a string
|
56
|
-
k.
|
56
|
+
k.md5_fingerprint
|
57
57
|
# => "2a:89:84:c9:29:05:d1:f8:49:79:1c:ba:73:99:eb:af"
|
58
58
|
|
59
|
+
# Returns the SHA1 fingerprint as a string
|
60
|
+
k.sha1_fingerprint
|
61
|
+
# => "e4:f9:79:f2:fe:d6:be:2d:ef:2e:c2:fa:aa:f8:b0:17:34:fe:0d:c0"
|
62
|
+
|
59
63
|
# Validates SSH Public Key
|
60
64
|
SSHKey.valid_ssh_public_key? "ssh-rsa AAAAB3NzaC1yc2EA...."
|
61
65
|
# => true
|
data/lib/sshkey.rb
CHANGED
@@ -1,24 +1,47 @@
|
|
1
1
|
require 'openssl'
|
2
2
|
require 'base64'
|
3
3
|
require 'digest/md5'
|
4
|
+
require 'digest/sha1'
|
4
5
|
|
5
6
|
class SSHKey
|
6
7
|
SSH_TYPES = {"rsa" => "ssh-rsa", "dsa" => "ssh-dss"}
|
7
8
|
SSH_CONVERSION = {"rsa" => ["e", "n"], "dsa" => ["p", "q", "g", "pub_key"]}
|
8
9
|
|
9
10
|
attr_reader :key_object, :comment, :type
|
10
|
-
|
11
|
+
attr_accessor :passphrase
|
12
|
+
|
13
|
+
# Generate a new keypair and return an SSHKey object
|
14
|
+
#
|
15
|
+
# The default behavior when providing no options will generate a 2048-bit RSA
|
16
|
+
# keypair.
|
17
|
+
#
|
18
|
+
# ==== Parameters
|
19
|
+
# * options<~Hash>:
|
20
|
+
# * :type<~String> - "rsa" or "dsa", "rsa" by default
|
21
|
+
# * :bits<~Integer> - Bit length
|
22
|
+
# * :comment<~String> - Comment to use for the public key, defaults to ""
|
23
|
+
# * :passphrase<~String> - Encrypt the key with this passphrase
|
24
|
+
#
|
11
25
|
def self.generate(options = {})
|
12
|
-
type
|
13
|
-
bits
|
26
|
+
type = options[:type] || "rsa"
|
27
|
+
bits = options[:bits] || 2048
|
28
|
+
cipher = OpenSSL::Cipher::Cipher.new("AES-128-CBC") if options[:passphrase]
|
29
|
+
|
14
30
|
case type.downcase
|
15
|
-
when "rsa" then SSHKey.new(OpenSSL::PKey::RSA.generate(bits).to_pem, options)
|
16
|
-
when "dsa" then SSHKey.new(OpenSSL::PKey::DSA.generate(bits).to_pem, options)
|
31
|
+
when "rsa" then SSHKey.new(OpenSSL::PKey::RSA.generate(bits).to_pem(cipher, options[:passphrase]), options)
|
32
|
+
when "dsa" then SSHKey.new(OpenSSL::PKey::DSA.generate(bits).to_pem(cipher, options[:passphrase]), options)
|
17
33
|
else
|
18
|
-
raise "Unknown key type #{type}"
|
34
|
+
raise "Unknown key type: #{type}"
|
19
35
|
end
|
20
36
|
end
|
21
37
|
|
38
|
+
# Validate an existing SSH public key
|
39
|
+
#
|
40
|
+
# Returns true or false depending on the validity of the public key provided
|
41
|
+
#
|
42
|
+
# ==== Parameters
|
43
|
+
# * ssh_public_key<~String> - "ssh-rsa AAAAB3NzaC1yc2EA...."
|
44
|
+
#
|
22
45
|
def self.valid_ssh_public_key?(ssh_public_key)
|
23
46
|
ssh_type, encoded_key = ssh_public_key.split(" ")
|
24
47
|
type = SSH_TYPES.invert[ssh_type]
|
@@ -45,11 +68,6 @@ class SSHKey
|
|
45
68
|
false
|
46
69
|
end
|
47
70
|
|
48
|
-
def self.valid?(ssh_public_key)
|
49
|
-
puts "DEPRECATION WARNING: SSHKey.valid? has been renamed to SSHKey.valid_ssh_public_key? for clarity. SSHKey.valid? will be removed in 1.3."
|
50
|
-
valid_ssh_public_key?(ssh_public_key)
|
51
|
-
end
|
52
|
-
|
53
71
|
def self.from_byte_array(byte_array, expected_size = nil)
|
54
72
|
num = 0
|
55
73
|
raise "Byte array too short" if !expected_size.nil? && expected_size != byte_array.size
|
@@ -59,59 +77,78 @@ class SSHKey
|
|
59
77
|
num
|
60
78
|
end
|
61
79
|
|
80
|
+
# Create a new SSHKey object
|
81
|
+
#
|
82
|
+
# ==== Parameters
|
83
|
+
# * private_key - Existing RSA or DSA private key
|
84
|
+
# * options<~Hash>
|
85
|
+
# * :comment<~String> - Comment to use for the public key, defaults to ""
|
86
|
+
# * :passphrase<~String> - If the key is encrypted, supply the passphrase
|
87
|
+
#
|
62
88
|
def initialize(private_key, options = {})
|
89
|
+
@passphrase = options[:passphrase]
|
90
|
+
@comment = options[:comment] || ""
|
63
91
|
begin
|
64
|
-
@key_object = OpenSSL::PKey::RSA.new(private_key)
|
92
|
+
@key_object = OpenSSL::PKey::RSA.new(private_key, passphrase)
|
65
93
|
@type = "rsa"
|
66
94
|
rescue
|
67
|
-
@key_object = OpenSSL::PKey::DSA.new(private_key)
|
95
|
+
@key_object = OpenSSL::PKey::DSA.new(private_key, passphrase)
|
68
96
|
@type = "dsa"
|
69
97
|
end
|
70
|
-
|
71
|
-
@comment = options[:comment] || ""
|
72
98
|
end
|
73
99
|
|
100
|
+
# Fetch the RSA/DSA private key
|
101
|
+
#
|
102
|
+
# rsa_private_key and dsa_private_key are aliased for backward compatibility
|
74
103
|
def private_key
|
75
104
|
key_object.to_pem
|
76
105
|
end
|
106
|
+
alias_method :rsa_private_key, :private_key
|
107
|
+
alias_method :dsa_private_key, :private_key
|
77
108
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
def rsa_private_key
|
85
|
-
private_key if type == "rsa"
|
109
|
+
# Fetch the encrypted RSA/DSA private key using the passphrase provided
|
110
|
+
#
|
111
|
+
# If no passphrase is set, returns the unencrypted private key
|
112
|
+
def encrypted_private_key
|
113
|
+
return private_key unless passphrase
|
114
|
+
key_object.to_pem(OpenSSL::Cipher::Cipher.new("AES-128-CBC"), passphrase)
|
86
115
|
end
|
87
116
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
private_key if type == "dsa"
|
94
|
-
end
|
95
|
-
|
96
|
-
def dsa_public_key
|
97
|
-
public_key if type == "dsa"
|
117
|
+
# Fetch the RSA/DSA public key
|
118
|
+
#
|
119
|
+
# rsa_public_key and dsa_public_key are aliased for backward compatibility
|
120
|
+
def public_key
|
121
|
+
key_object.public_key.to_pem
|
98
122
|
end
|
99
|
-
|
123
|
+
alias_method :rsa_public_key, :public_key
|
124
|
+
alias_method :dsa_public_key, :public_key
|
100
125
|
|
126
|
+
# SSH public key
|
101
127
|
def ssh_public_key
|
102
128
|
[SSH_TYPES[type], Base64.encode64(ssh_public_key_conversion).gsub("\n", ""), comment].join(" ").strip
|
103
129
|
end
|
104
130
|
|
105
|
-
|
131
|
+
# Fingerprints
|
132
|
+
#
|
133
|
+
# MD5 fingerprint for the given SSH public key
|
134
|
+
def md5_fingerprint
|
106
135
|
Digest::MD5.hexdigest(ssh_public_key_conversion).gsub(/(.{2})(?=.)/, '\1:\2')
|
107
136
|
end
|
137
|
+
alias_method :fingerprint, :md5_fingerprint
|
138
|
+
|
139
|
+
# SHA1 fingerprint for the given SSH public key
|
140
|
+
def sha1_fingerprint
|
141
|
+
Digest::SHA1.hexdigest(ssh_public_key_conversion).gsub(/(.{2})(?=.)/, '\1:\2')
|
142
|
+
end
|
108
143
|
|
109
144
|
private
|
110
145
|
|
146
|
+
# SSH Public Key Conversion
|
147
|
+
#
|
111
148
|
# All data type encoding is defined in the section #5 of RFC #4251.
|
112
|
-
# String and mpint (multiple precision integer) types are encoded this way
|
149
|
+
# String and mpint (multiple precision integer) types are encoded this way:
|
113
150
|
# 4-bytes word: data length (unsigned big-endian 32 bits integer)
|
114
|
-
# n bytes
|
151
|
+
# n bytes: binary representation of the data
|
115
152
|
|
116
153
|
# For instance, the "ssh-rsa" string is encoded as the following byte array
|
117
154
|
# [0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a']
|
data/lib/sshkey/version.rb
CHANGED
data/test/sshkey_test.rb
CHANGED
@@ -75,21 +75,107 @@ GzM8qwTcXd06uIZAJdTHIQ==
|
|
75
75
|
-----END DSA PRIVATE KEY-----
|
76
76
|
EOF
|
77
77
|
|
78
|
+
ENCRYPTED_PRIVATE_KEY = <<-EOF
|
79
|
+
-----BEGIN RSA PRIVATE KEY-----
|
80
|
+
Proc-Type: 4,ENCRYPTED
|
81
|
+
DEK-Info: AES-128-CBC,3514D8812B519059944A811726594515
|
82
|
+
|
83
|
+
fSr1v51I65MZrSs7u12nype6RH6NS15xN5FDPaPKV++EBPxysEzicU5QHDt/aHa3
|
84
|
+
t87nXkra1M400+zNgFcfi5Ga7w5SBmqEjdNgwhUV2/j1Yqqlr5c7l804OfIPxdE6
|
85
|
+
ELoWH7pen72JnlZe6gXq495W96QTg3IzIWdiKEbKJlEwrNBligqT7GB2mup8nY1D
|
86
|
+
o71R07dIrvfDy3xVgCoRjX4LKUilO6nRnwVCFRgVQTEVKclqt8NiSFGMjzv3iekR
|
87
|
+
f1fJ8Wm6CiST8zdetIXgMnHEK1KELhNeMhI/42Tn/gHPDsckBiKLtM+85OOT92wh
|
88
|
+
L9o/KUySdcsb/ld0yT/kAc99/wqNitHAqUEcLshIWDVhqoT1XK46hEuRN782AN2U
|
89
|
+
shQKirF8QFopYF+u9K2Q0mr1EsYaBWOFFBR7EiwFvEYOx+ad6qGQGPcxWhbf6eCU
|
90
|
+
D///9g1g5q8nWb80UH9Hw1aMhIA+VTlIasM6XJKmGr1LapxlrYsqRovPwkgOQg01
|
91
|
+
jhSV1fy10bbaFBwd9qTdTTVqa368/e3/TxF2VKhDaqoy5lqvRqKzGJxi3ubzDuz9
|
92
|
+
m3qRTCgy1v3XI5DgcjWt5xC5gZLHjKf79fQKRJjuEnWALahpDVWQ6PRCuqPfyph5
|
93
|
+
/vVqGHqvA53HJ9pmXz4J9qtQQ2gkYRj1m2tlRJjtGRMqnAj7bpcDKIrdLudOiWB0
|
94
|
+
FXwmsXljzPaf/SPUa+tGg7jbh+Jq+72vdpo1ijJtLXhWQAJasIbvSXOVHbZ6YhJj
|
95
|
+
vES98gJPzevqemS//C1DMrr0ci6pM9ciT2szkrg71zRacnfqrjeZUI7qHKAsRbD5
|
96
|
+
258Jj6BeFPeQSrUg8sqQdoPxVTNnVr2bOB5SNfh7gqLanPksi6Kr7XNIzsYP5Wzf
|
97
|
+
ADAElPdcRRwYc2kLVqugZTMLSn1r8rQjEyQ8/TT2QefI4ma8mCrBKgqYX+SDbhMJ
|
98
|
+
+KUrah0jCgj86z6fSNkNHaKuzvGCovZsJHXt2SoIWVYWVUz91IHPKXXycIqvf3Yj
|
99
|
+
9HFpJRAPh30MYBgiImCJjmk8tqKGn0Tc80vOsrKMlVuMIIu2eNrddrnHUzSbjIHr
|
100
|
+
tTtSDvsJ/Bn/6+Ox77U/FKg6s6/6PxOA1a+ffKkBXB/g4jS5CfGZl1owb3kX91C/
|
101
|
+
a+bcNWp07DsaTaZd/0UEL2gIvaEuCULgyIvmnBPCOY6Pc5GGegWEJne/sk7j9W4I
|
102
|
+
59YtVfcSXiovYR/QEywytfN/tfPxKfUoqNMIxLkukjFYz4Zzk5kXEeI+1lcry398
|
103
|
+
UQSaOboSDKY6boX4rWgiiqyn5LN+47eAIZPO+zsWXky16F04JpT7V7XqZPXQn7vI
|
104
|
+
pMAoPCkT4qE9Gp2CcSj2l2CoZ3ZA5lOs6Wvxuz0q1zd0uSe8O81/3rnw28DthDQO
|
105
|
+
SuzrY0HinPEFomwMGbfhosB5kOmBXEk7XbSWWHhK0QG63CYqp5caUst2Mie21b0Y
|
106
|
+
FgFTrS1VqUiqDjCmt8F8UCPQS89aFm096wqtmwDO+VWKanuHUUShtTPlYyLe1RTm
|
107
|
+
wqh1BBa05ydM0Vf1NagFB4JNT1qSIL5x4XtkOFwqcdXWYvwYfT8PkZjX/kz+W7jb
|
108
|
+
-----END RSA PRIVATE KEY-----
|
109
|
+
EOF
|
110
|
+
|
111
|
+
DECRYPTED_PRIVATE_KEY = <<-EOF
|
112
|
+
-----BEGIN RSA PRIVATE KEY-----
|
113
|
+
MIIEpAIBAAKCAQEA33H9u4rG0SVMzK8PFyIi30kVHvogmpKVOQL2g2tozi2GipkA
|
114
|
+
imzoCW9jIx1jo6zo0kMKCbMdJCNUc93tQxkJAAWA07WYwE9z+J6MC/3urb4Q0UAZ
|
115
|
+
orlNyN3pPP8ATFIQomd0wW/EHwbmknlJOIZY4MNUQpNJunnBAAzZyLef6+sbLzQZ
|
116
|
+
wc0/vgtmatoCxh4mZWFuFMopkMqScYDKxL30xXXPRGfJvAVWZDnY3ErJSe7uyefI
|
117
|
+
Zo/lp4tsH5XGMcFm+nLs++nJjYZ6Ud/ie1g+ZCJv5Qit1m7zCVjiJ4RVMC/4yTb7
|
118
|
+
CO8n4PhX8gR9d1DRPVvlKa1sZfQeULEIXMniKQIDAQABAoIBAQDEXS74s5rJjhgS
|
119
|
+
AP4n/E3dICK5mGMytAMDmUD+eVQfbQ7BmnhJLjA0qnjbESbRXlE1Bsk5gPjpG0tK
|
120
|
+
kAvEXan1JOD0LLDSwIBQSzUUDNLGSTQKUGS3BlX/YlVoz0h5ydzofDa1D/2wrqXO
|
121
|
+
r1vTmu1ciQvxffLbN8iOvLxfkk+uSMhqnhf/q3WVinu+VALPg8e/v3p4VbnSfP4D
|
122
|
+
eClBiMKEKRFdsa9xBxShijcX1HxjIvp3zDgb127fo2iFw09PIHUZCUo6M77iGrQY
|
123
|
+
mscoA+5q1qSyD6Btw0EkKK55ytNMC2T+KfGYV0ySwhadmM+5+G64etvNGCn/j7CU
|
124
|
+
rhuRhMlpAoGBAPiJlcWaNVw3ttlea+jllxnaCEOmG29NGWxw080XRvjSIrltPAiE
|
125
|
+
8e4FynAMx49aXKsaB8Df2WspdKBxHJgv1U0sapADwxlMO8erj2eDSRqy6bwnI4CT
|
126
|
+
T+vvo2vdmkvkV0D9RskXCi5tgTO5FYnf7CjON6JLkg83V3vzyjsKlvDzAoGBAOYn
|
127
|
+
iC50OdZ84U58wQUsvwXFuyzMQX9r+h0jL2tIDv/yYlMWg9tNt0HkGUOo7H1ZVhdL
|
128
|
+
9Z1B0Ztl2qoJipcQvhzfwdo4XwuLk7D0bOAfZo9YMbU5Jqy+rqE5yv/P4wa7ba4S
|
129
|
+
uUQYvSuv54CtiOZDFyK8dU7y9mm+no3Fvrd9RwdzAoGANzlLACctqBnxFQd37r3k
|
130
|
+
/yeFIpLsEaUN+xxu02lSqcL3WEA/UJ1JrFu5CYCtbtrjMFmOU3rpsnf5pBS+B8rJ
|
131
|
+
GGbAHtPXK+3Wcp1aNePkAHy0lswThWQ2I/SRWUxaFnbcNGKSsefeqUZHqRh9Aq+w
|
132
|
+
p7h6gCNOhvcDB1W6H7hQpaUCgYEAyBRDygaWJUVI5N+FOUduBMmhb09d/TTUKTJm
|
133
|
+
TcBF8fE30v12wVZtYqW15ODcPhhExFnverc2Tf6cukczKSKP8y/+KQPqdHHxgdrr
|
134
|
+
L2d81E6aX+4AFhpqW5SPShXiSf70WWjDkFRlV65C9dVmdq6KVVM6M9j5qHHjCmKG
|
135
|
+
6qLI9csCgYBuhFwwI9DiYvJPR1LJZnJtE0qZiTwpmCjU2LoBRsywvuBeyXtwpmIM
|
136
|
+
5IgfgXXLK5qK/+cp9047T5rzT6ndu5fNZINPzynA8tNhTtHXK8l/GT/iq8Rd6AcM
|
137
|
+
WJmIe8EnUDhHqg7Z2h5tGpX1QPMSA4G8RGPPyrcd3v0G/PZ6pFALlQ==
|
138
|
+
-----END RSA PRIVATE KEY-----
|
139
|
+
EOF
|
140
|
+
|
141
|
+
DECRYPTED_KEY_FINGERPRINT = "2e:ba:06:b1:c7:13:37:24:6f:2d:3a:ba:45:e2:b4:78"
|
142
|
+
|
78
143
|
SSH_PUBLIC_KEY1 = 'AAAAB3NzaC1yc2EAAAABIwAAAQEArfTA/lKVR84IMc9ZzXOCHr8DVtR8hzWuEVHF6KElavRHlk14g0SZu3m908Ejm/XF3EfNHjX9wN+62IMA0QBxkBMFCuLF+U/oeUs0NoDdAEKxjj4n6lq6Ss8aLct+anMy7D1jwvOLbcwV54w1d5JDdlZVdZ6AvHm9otwJq6rNpDgdmXY4HgC2nM9csFpuy0cDpL6fdJx9lcNL2RnkRC4+RMsIB+PxDw0j3vDi04dYLBXMGYjyeGH+mIFpL3PTPXGXwL2XDYXZ2H4SQX6bOoKmazTXq6QXuEB665njh1GxXldoIMcSshoJL0hrk3WrTOG22N2CQA+IfHgrXJ+A+QUzKQ=='
|
79
144
|
SSH_PUBLIC_KEY2 = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAxl6TpN7uFiY/JZ8qDnD7UrxDP+ABeh2PVg8Du1LEgXNk0+YWCeP5S6oHklqaWeDlbmAs1oHsBwCMAVpMa5tgONOLvz4JgwgkiqQEbKR8ofWJ+LADUElvqRVGmGiNEMLI6GJWeneL4sjmbb8d6U+M53c6iWG0si9XE5m7teBQSsCl0Tk3qMIkQGw5zpJeCXjZ8KpJhIJRYgexFkGgPlYRV+UYIhxpUW90t0Ra5i6JOFYwq98k5S/6SJIZQ/A9F4JNzwLw3eVxZj0yVHWxkGz1+TyELNY1kOyMxnZaqSfGzSQJTrnIXpdweVHuYh1LtOgedRQhCyiELeSMGwio1vRPKw=='
|
80
145
|
SSH_PUBLIC_KEY3 = 'AAAAB3NzaC1kc3MAAACBALyVy5dwVwgL3CxXzsvo8DBh58qArQLBNIPW/f9pptmy7jD5QXzOw+12w0/z4lZ86ncoVutRMf44OABcX9ovhRl+luxB7jjpkVXy/p2ZaqPbeyTQUtdTmXa2y4n053Jd61VeMG+iLP7+viT+Ib96y9aVUYQfCrl5heBDUZ9cAFjdAAAAFQDFXnO7JJpFKwkeoor4GWGHtz0D2QAAAIEAqel0RUBO0MY5b3DZ69J/mRzUifN1O6twk4er2ph0JpryuUwZohLpcVZwqoGWmPQy/ZHmV1b3RtT9GWUa+HUqKdMhFVOx/iq1khVfLi83whjMMvXj3ecqd0yzGxGHnSsjVKefa2ywCLHrh4nlUVIaXI5gQpgMyVbMcromDe1WZzoAAACBAIwTRPAEcroqOzaebiVspFcmsXxDQ4wXQZQdho1ExW6FKS8s7/6pItmZYXTvJDwLXgq2/iK1fRRcKk2PJEaSuJR7WeNGsJKfWmQ2UbOhqA3wWLDazIZtcMKjFzD0hM4E8qgjHjMvKDE6WgT6SFP+tqx3nnh7pJWwsbGjSMQexpyR'
|
81
146
|
|
82
|
-
|
83
|
-
|
84
|
-
|
147
|
+
KEY1_MD5_FINGERPRINT = "2a:89:84:c9:29:05:d1:f8:49:79:1c:ba:73:99:eb:af"
|
148
|
+
KEY2_MD5_FINGERPRINT = "3c:af:74:87:cc:cc:a1:12:05:1a:09:b7:7b:ce:ed:ce"
|
149
|
+
KEY3_MD5_FINGERPRINT = "14:f6:6a:12:96:be:44:32:e6:3c:77:43:94:52:f5:7a"
|
150
|
+
|
151
|
+
KEY1_SHA1_FINGERPRINT = "e4:f9:79:f2:fe:d6:be:2d:ef:2e:c2:fa:aa:f8:b0:17:34:fe:0d:c0"
|
152
|
+
KEY2_SHA1_FINGERPRINT = "9a:52:78:2b:6b:cb:39:b7:85:ed:90:8a:28:62:aa:b3:98:88:e6:07"
|
153
|
+
KEY3_SHA1_FINGERPRINT = "15:68:c6:72:ac:18:d1:fc:ab:a2:b7:b5:8c:d1:fe:8f:b9:ae:a9:47"
|
85
154
|
|
86
155
|
def setup
|
87
156
|
@key1 = SSHKey.new(SSH_PRIVATE_KEY1, :comment => "me@example.com")
|
88
157
|
@key2 = SSHKey.new(SSH_PRIVATE_KEY2, :comment => "me@example.com")
|
89
158
|
@key3 = SSHKey.new(SSH_PRIVATE_KEY3, :comment => "me@example.com")
|
159
|
+
@key_encrypted = SSHKey.new(ENCRYPTED_PRIVATE_KEY, :passphrase => "password")
|
90
160
|
@key_without_comment = SSHKey.new(SSH_PRIVATE_KEY1)
|
91
161
|
end
|
92
162
|
|
163
|
+
def test_generator_with_no_args
|
164
|
+
assert_kind_of SSHKey, SSHKey.generate
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_generator_with_comment
|
168
|
+
assert_equal "foo", SSHKey.generate(:comment => "foo").comment
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_generator_with_type
|
172
|
+
assert_equal "dsa", SSHKey.generate(:type => "dsa").type
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_generator_with_passphrase
|
176
|
+
assert_equal "password", SSHKey.generate(:passphrase => "password").passphrase
|
177
|
+
end
|
178
|
+
|
93
179
|
def test_private_key1
|
94
180
|
assert_equal SSH_PRIVATE_KEY1, @key1.private_key
|
95
181
|
assert_equal SSH_PRIVATE_KEY1, @key1.rsa_private_key
|
@@ -105,6 +191,20 @@ EOF
|
|
105
191
|
assert_equal SSH_PRIVATE_KEY3, @key3.dsa_private_key
|
106
192
|
end
|
107
193
|
|
194
|
+
def test_encrypted_private_key_can_be_decrypted
|
195
|
+
assert_equal DECRYPTED_PRIVATE_KEY, @key_encrypted.private_key
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_encrypted_private_key_matches_when_reencrypted
|
199
|
+
key = SSHKey.new(@key_encrypted.encrypted_private_key, :passphrase => "password")
|
200
|
+
assert_equal DECRYPTED_PRIVATE_KEY, key.private_key
|
201
|
+
assert_equal DECRYPTED_KEY_FINGERPRINT, key.md5_fingerprint
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_unencrypted_private_key_returns_private_key_when_asked_for_encrypted
|
205
|
+
assert_equal SSH_PRIVATE_KEY1, @key1.encrypted_private_key
|
206
|
+
end
|
207
|
+
|
108
208
|
def test_ssh_public_key_decoded1
|
109
209
|
assert_equal Base64.decode64(SSH_PUBLIC_KEY1), @key1.send(:ssh_public_key_conversion)
|
110
210
|
end
|
@@ -151,16 +251,16 @@ EOF
|
|
151
251
|
invalid4 = "ssh-rsa A#{SSH_PUBLIC_KEY1}"
|
152
252
|
invalid5 = "ssh-rsa #{SSH_PUBLIC_KEY3} me@example.com"
|
153
253
|
|
154
|
-
assert SSHKey.
|
155
|
-
assert SSHKey.
|
156
|
-
assert SSHKey.
|
157
|
-
assert SSHKey.
|
254
|
+
assert SSHKey.valid_ssh_public_key?(expected1)
|
255
|
+
assert SSHKey.valid_ssh_public_key?(expected2)
|
256
|
+
assert SSHKey.valid_ssh_public_key?(expected3)
|
257
|
+
assert SSHKey.valid_ssh_public_key?(expected4)
|
158
258
|
|
159
|
-
assert !SSHKey.
|
160
|
-
assert !SSHKey.
|
161
|
-
assert !SSHKey.
|
162
|
-
assert !SSHKey.
|
163
|
-
assert !SSHKey.
|
259
|
+
assert !SSHKey.valid_ssh_public_key?(invalid1)
|
260
|
+
assert !SSHKey.valid_ssh_public_key?(invalid2)
|
261
|
+
assert !SSHKey.valid_ssh_public_key?(invalid3)
|
262
|
+
assert !SSHKey.valid_ssh_public_key?(invalid4)
|
263
|
+
assert !SSHKey.valid_ssh_public_key?(invalid5)
|
164
264
|
end
|
165
265
|
|
166
266
|
def test_exponent
|
@@ -174,9 +274,14 @@ EOF
|
|
174
274
|
end
|
175
275
|
|
176
276
|
def test_fingerprint
|
177
|
-
assert_equal
|
178
|
-
assert_equal
|
179
|
-
assert_equal
|
277
|
+
assert_equal KEY1_MD5_FINGERPRINT, @key1.md5_fingerprint
|
278
|
+
assert_equal KEY1_MD5_FINGERPRINT, @key1.fingerprint # Aliased method
|
279
|
+
assert_equal KEY2_MD5_FINGERPRINT, @key2.md5_fingerprint
|
280
|
+
assert_equal KEY3_MD5_FINGERPRINT, @key3.md5_fingerprint
|
281
|
+
|
282
|
+
assert_equal KEY1_SHA1_FINGERPRINT, @key1.sha1_fingerprint
|
283
|
+
assert_equal KEY2_SHA1_FINGERPRINT, @key2.sha1_fingerprint
|
284
|
+
assert_equal KEY3_SHA1_FINGERPRINT, @key3.sha1_fingerprint
|
180
285
|
end
|
181
286
|
|
182
287
|
def test_to_byte_array
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sshkey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70360303706000 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70360303706000
|
25
25
|
description: Generate private/public SSH keypairs using pure Ruby
|
26
26
|
email:
|
27
27
|
- bensie@gmail.com
|