sshkey 1.6.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.travis.yml +27 -2
- data/Gemfile +2 -1
- data/README.md +26 -3
- data/lib/sshkey.rb +33 -49
- data/lib/sshkey/version.rb +1 -1
- data/sshkey.gemspec +1 -0
- data/test/sshkey_test.rb +6 -15
- metadata +11 -14
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dcab21406c740089ec26317a5499a2b757f03e7c
|
4
|
+
data.tar.gz: 212a9a19f541aea1aeaf577cb2e938f1eae9c4fd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba8bf9fcef2981609256d9765e855e49771992caa20d1b87ff52a20d627a8d2571318486687b2cf51c52d6f8a510281ad351069e94cb092e44a520f069af5ab6
|
7
|
+
data.tar.gz: f1f47cb1a2861aa2a8a741d8b511529c62701e943658c1dead0f6621ad639158874b4c13fc6a00f9bc6375e00ea46aab32612d5337c8e55002503f0aaac6dab9
|
data/.travis.yml
CHANGED
@@ -9,8 +9,33 @@ rvm:
|
|
9
9
|
- jruby-19mode
|
10
10
|
- jruby-20mode
|
11
11
|
- jruby-head
|
12
|
-
- rbx-
|
13
|
-
|
12
|
+
- rbx-2.1.1
|
13
|
+
|
14
14
|
matrix:
|
15
15
|
allow_failures:
|
16
16
|
- rvm: ruby-head
|
17
|
+
include:
|
18
|
+
- rvm: jruby-18mode
|
19
|
+
jdk: openjdk6
|
20
|
+
- rvm: jruby-18mode
|
21
|
+
jdk: openjdk7
|
22
|
+
- rvm: jruby-18mode
|
23
|
+
jdk: oraclejdk7
|
24
|
+
- rvm: jruby-19mode
|
25
|
+
jdk: openjdk6
|
26
|
+
- rvm: jruby-19mode
|
27
|
+
jdk: openjdk7
|
28
|
+
- rvm: jruby-19mode
|
29
|
+
jdk: oraclejdk7
|
30
|
+
- rvm: jruby-20mode
|
31
|
+
jdk: openjdk6
|
32
|
+
- rvm: jruby-20mode
|
33
|
+
jdk: openjdk7
|
34
|
+
- rvm: jruby-20mode
|
35
|
+
jdk: oraclejdk7
|
36
|
+
- rvm: jruby-head
|
37
|
+
jdk: openjdk6
|
38
|
+
- rvm: jruby-head
|
39
|
+
jdk: openjdk7
|
40
|
+
- rvm: jruby-head
|
41
|
+
jdk: oraclejdk7
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Generate private and public SSH keys (RSA and DSA supported) using pure Ruby.
|
|
4
4
|
|
5
5
|
gem install sshkey
|
6
6
|
|
7
|
-
Tested on the following Rubies: MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0, REE, JRuby (1.7.2
|
7
|
+
Tested on the following Rubies: MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0, REE, JRuby (1.7.2 and newer), Rubinius (2.1.1 and newer). Ruby must be compiled with OpenSSL support.
|
8
8
|
|
9
9
|
[](http://travis-ci.org/bensie/sshkey)
|
10
10
|
|
@@ -152,15 +152,38 @@ k.key_object
|
|
152
152
|
# => -----BEGIN RSA PRIVATE KEY-----\nMIIEowI...
|
153
153
|
```
|
154
154
|
|
155
|
-
###
|
155
|
+
### Existing SSH public keys
|
156
156
|
|
157
|
-
|
157
|
+
#### Validation
|
158
|
+
|
159
|
+
Determine if a given SSH public key is valid. Very useful to test user input of public keys to make sure they accurately copy/pasted the key. Just pass the SSH public key as a string. Returns false if the key is invalid.
|
158
160
|
|
159
161
|
```ruby
|
160
162
|
SSHKey.valid_ssh_public_key? "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9HuXvYJPtQE/o/7TYi63yAopsrJ6TP+lDGdyQ+nVVp+5ojAIy9h8/h99UlNxjkiFT2YhI3Fl/pgNDRO4PVo6tlgb3CwiAZjSdeE5RnF79Dkj5XsM4j+FLMoXtbRw0K9ok9RKjz6ygIs1JDmaOdXexFnq4nAYU3fSLUa6WoccqTHe8bFuJoAv1gbnx09Js8YcVMD96mpTJ3V/MK5YfIv10dbtrDhGug3IS1V2J+0BB9orbQja554N+4S0I9rFBgVCpvPmQqddDHd/AdGkLv/zjEfGytjnvp68bEfDinkQkPfuxw01yd5MbcvLv39VVICWtKbqW263HT5LvSxwKorR7"
|
161
163
|
# => true
|
162
164
|
```
|
163
165
|
|
166
|
+
#### Bit length
|
167
|
+
|
168
|
+
Determine the strenth of the key in bits as an integer. Returns `SSHKey::PublicKeyError` if bits cannot be determined.
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
SSHKey.ssh_public_key_bits "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9HuXvYJPtQE/o/7TYi63yAopsrJ6TP+lDGdyQ+nVVp+5ojAIy9h8/h99UlNxjkiFT2YhI3Fl/pgNDRO4PVo6tlgb3CwiAZjSdeE5RnF79Dkj5XsM4j+FLMoXtbRw0K9ok9RKjz6ygIs1JDmaOdXexFnq4nAYU3fSLUa6WoccqTHe8bFuJoAv1gbnx09Js8YcVMD96mpTJ3V/MK5YfIv10dbtrDhGug3IS1V2J+0BB9orbQja554N+4S0I9rFBgVCpvPmQqddDHd/AdGkLv/zjEfGytjnvp68bEfDinkQkPfuxw01yd5MbcvLv39VVICWtKbqW263HT5LvSxwKorR7"
|
172
|
+
# => 2048
|
173
|
+
```
|
174
|
+
|
175
|
+
#### Fingerprints
|
176
|
+
|
177
|
+
Fetch either an MD5 (OpenSSH default) or SHA1 fingerprint of the SSH
|
178
|
+
public key. Returns `SSHKey::PublicKeyError` if a fingerprint cannot be determined.
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
SSHKey.fingerprint "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9HuXvYJPtQE/o/7TYi63yAopsrJ6TP+lDGdyQ+nVVp+5ojAIy9h8/h99UlNxjkiFT2YhI3Fl/pgNDRO4PVo6tlgb3CwiAZjSdeE5RnF79Dkj5XsM4j+FLMoXtbRw0K9ok9RKjz6ygIs1JDmaOdXexFnq4nAYU3fSLUa6WoccqTHe8bFuJoAv1gbnx09Js8YcVMD96mpTJ3V/MK5YfIv10dbtrDhGug3IS1V2J+0BB9orbQja554N+4S0I9rFBgVCpvPmQqddDHd/AdGkLv/zjEfGytjnvp68bEfDinkQkPfuxw01yd5MbcvLv39VVICWtKbqW263HT5LvSxwKorR7"
|
182
|
+
# => "04:1b:d4:18:df:87:60:94:8c:83:8a:7b:5a:35:59:3d"
|
183
|
+
SSHKey.sha1_fingerprint "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9HuXvYJPtQE/o/7TYi63yAopsrJ6TP+lDGdyQ+nVVp+5ojAIy9h8/h99UlNxjkiFT2YhI3Fl/pgNDRO4PVo6tlgb3CwiAZjSdeE5RnF79Dkj5XsM4j+FLMoXtbRw0K9ok9RKjz6ygIs1JDmaOdXexFnq4nAYU3fSLUa6WoccqTHe8bFuJoAv1gbnx09Js8YcVMD96mpTJ3V/MK5YfIv10dbtrDhGug3IS1V2J+0BB9orbQja554N+4S0I9rFBgVCpvPmQqddDHd/AdGkLv/zjEfGytjnvp68bEfDinkQkPfuxw01yd5MbcvLv39VVICWtKbqW263HT5LvSxwKorR7"
|
184
|
+
# => "e5:c2:43:9e:e4:0c:0c:47:82:7a:3b:e9:61:13:bd:9c:43:eb:4c:b7"
|
185
|
+
```
|
186
|
+
|
164
187
|
## Copyright
|
165
188
|
|
166
189
|
Copyright (c) 2011-2013 James Miller
|
data/lib/sshkey.rb
CHANGED
@@ -62,7 +62,7 @@ class SSHKey
|
|
62
62
|
# * ssh_public_key<~String> - "ssh-rsa AAAAB3NzaC1yc2EA...."
|
63
63
|
#
|
64
64
|
def ssh_public_key_bits(ssh_public_key)
|
65
|
-
unpacked_byte_array( *parse_ssh_public_key(ssh_public_key) ).last.
|
65
|
+
unpacked_byte_array( *parse_ssh_public_key(ssh_public_key) ).last.num_bytes * 8
|
66
66
|
end
|
67
67
|
|
68
68
|
# Fingerprints
|
@@ -91,38 +91,29 @@ class SSHKey
|
|
91
91
|
private
|
92
92
|
|
93
93
|
def unpacked_byte_array(ssh_type, encoded_key)
|
94
|
-
prefix = [
|
94
|
+
prefix = [7].pack("N") + ssh_type
|
95
95
|
decoded = Base64.decode64(encoded_key)
|
96
96
|
|
97
97
|
# Base64 decoding is too permissive, so we should validate if encoding is correct
|
98
|
-
|
98
|
+
unless Base64.encode64(decoded).gsub("\n", "") == encoded_key && decoded.slice!(0, prefix.length) == prefix
|
99
99
|
raise PublicKeyError, "validation error"
|
100
100
|
end
|
101
101
|
|
102
|
-
unpacked = decoded.unpack("C*")
|
103
102
|
data = []
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
103
|
+
until decoded.empty?
|
104
|
+
front = decoded.slice!(0,4)
|
105
|
+
size = front.unpack("N").first
|
106
|
+
segment = decoded.slice!(0, size)
|
107
|
+
unless front.length == 4 && segment.length == size
|
108
|
+
raise PublicKeyError, "byte array too short"
|
109
|
+
end
|
110
|
+
data << OpenSSL::BN.new(segment, 2)
|
111
111
|
end
|
112
112
|
return data
|
113
113
|
end
|
114
114
|
|
115
|
-
def from_byte_array(byte_array, expected_size = nil)
|
116
|
-
raise PublicKeyError, "byte array too short" if !expected_size.nil? && expected_size != byte_array.size
|
117
|
-
num = 0
|
118
|
-
byte_array.reverse.each_with_index do |item, index|
|
119
|
-
num += item * 256**(index)
|
120
|
-
end
|
121
|
-
num
|
122
|
-
end
|
123
|
-
|
124
115
|
def decoded_key(key)
|
125
|
-
Base64.decode64(key.
|
116
|
+
Base64.decode64(parse_ssh_public_key(key).last)
|
126
117
|
end
|
127
118
|
|
128
119
|
def fingerprint_regex
|
@@ -286,34 +277,27 @@ class SSHKey
|
|
286
277
|
# For instance, the "ssh-rsa" string is encoded as the following byte array
|
287
278
|
# [0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a']
|
288
279
|
def ssh_public_key_conversion
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
280
|
+
typestr = SSH_TYPES[type]
|
281
|
+
methods = SSH_CONVERSION[type]
|
282
|
+
pubkey = key_object.public_key
|
283
|
+
methods.inject([7].pack("N") + typestr) do |pubkeystr, m|
|
284
|
+
# Given pubkey.class == OpenSSL::BN, pubkey.to_s(0) returns an MPI
|
285
|
+
# formatted string (length prefixed bytes). This is not supported by
|
286
|
+
# JRuby, so we still have to deal with length and data separately.
|
287
|
+
val = pubkey.send(m)
|
288
|
+
|
289
|
+
# Get byte-representation of absolute value of val
|
290
|
+
data = val.to_s(2)
|
291
|
+
|
292
|
+
first_byte = data[0,1].unpack("c").first
|
293
|
+
if val < 0
|
294
|
+
# For negative values, highest bit must be set
|
295
|
+
data[0] = [0x80 & first_byte].pack("c")
|
296
|
+
elsif first_byte < 0
|
297
|
+
# For positive values where highest bit would be set, prefix with \0
|
298
|
+
data = "\0" + data
|
299
|
+
end
|
300
|
+
pubkeystr + [data.length].pack("N") + data
|
296
301
|
end
|
297
|
-
|
298
|
-
return out
|
299
302
|
end
|
300
|
-
|
301
|
-
def encode_unsigned_int_32(value)
|
302
|
-
out = []
|
303
|
-
out[0] = value >> 24 & 0xff
|
304
|
-
out[1] = value >> 16 & 0xff
|
305
|
-
out[2] = value >> 8 & 0xff
|
306
|
-
out[3] = value & 0xff
|
307
|
-
return out
|
308
|
-
end
|
309
|
-
|
310
|
-
def to_byte_array(num)
|
311
|
-
result = []
|
312
|
-
begin
|
313
|
-
result << (num & 0xff)
|
314
|
-
num >>= 8
|
315
|
-
end until (num == 0 || num == -1) && (result.last[7] == num[7])
|
316
|
-
result.reverse
|
317
|
-
end
|
318
|
-
|
319
303
|
end
|
data/lib/sshkey/version.rb
CHANGED
data/sshkey.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "https://github.com/bensie/sshkey"
|
12
12
|
s.summary = %q{SSH private/public key generator in Ruby}
|
13
13
|
s.description = %q{Generate private/public SSH keypairs using pure Ruby}
|
14
|
+
s.licenses = ["MIT"]
|
14
15
|
|
15
16
|
s.rubyforge_project = "sshkey"
|
16
17
|
|
data/test/sshkey_test.rb
CHANGED
@@ -298,18 +298,18 @@ EOF
|
|
298
298
|
assert_equal KEY3_SHA1_FINGERPRINT, @key3.sha1_fingerprint
|
299
299
|
|
300
300
|
assert_equal KEY1_MD5_FINGERPRINT, SSHKey.md5_fingerprint(SSH_PRIVATE_KEY1)
|
301
|
-
assert_equal KEY1_MD5_FINGERPRINT, SSHKey.md5_fingerprint(SSH_PUBLIC_KEY1)
|
301
|
+
assert_equal KEY1_MD5_FINGERPRINT, SSHKey.md5_fingerprint("ssh-rsa #{SSH_PUBLIC_KEY1}")
|
302
302
|
assert_equal KEY2_MD5_FINGERPRINT, SSHKey.md5_fingerprint(SSH_PRIVATE_KEY2)
|
303
|
-
assert_equal KEY2_MD5_FINGERPRINT, SSHKey.md5_fingerprint(SSH_PUBLIC_KEY2)
|
303
|
+
assert_equal KEY2_MD5_FINGERPRINT, SSHKey.md5_fingerprint("ssh-rsa #{SSH_PUBLIC_KEY2} me@me.com")
|
304
304
|
assert_equal KEY3_MD5_FINGERPRINT, SSHKey.md5_fingerprint(SSH_PRIVATE_KEY3)
|
305
|
-
assert_equal KEY3_MD5_FINGERPRINT, SSHKey.md5_fingerprint(SSH_PUBLIC_KEY3)
|
305
|
+
assert_equal KEY3_MD5_FINGERPRINT, SSHKey.md5_fingerprint("ssh-dss #{SSH_PUBLIC_KEY3}")
|
306
306
|
|
307
307
|
assert_equal KEY1_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint(SSH_PRIVATE_KEY1)
|
308
|
-
assert_equal KEY1_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint(SSH_PUBLIC_KEY1)
|
308
|
+
assert_equal KEY1_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint("ssh-rsa #{SSH_PUBLIC_KEY1}")
|
309
309
|
assert_equal KEY2_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint(SSH_PRIVATE_KEY2)
|
310
|
-
assert_equal KEY2_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint(SSH_PUBLIC_KEY2)
|
310
|
+
assert_equal KEY2_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint("ssh-rsa #{SSH_PUBLIC_KEY2} me@me.com")
|
311
311
|
assert_equal KEY3_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint(SSH_PRIVATE_KEY3)
|
312
|
-
assert_equal KEY3_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint(SSH_PUBLIC_KEY3)
|
312
|
+
assert_equal KEY3_SHA1_FINGERPRINT, SSHKey.sha1_fingerprint("ssh-dss #{SSH_PUBLIC_KEY3}")
|
313
313
|
end
|
314
314
|
|
315
315
|
def test_bits
|
@@ -324,15 +324,6 @@ EOF
|
|
324
324
|
assert_equal KEY2_RANDOMART, @key2.randomart
|
325
325
|
assert_equal KEY3_RANDOMART, @key3.randomart
|
326
326
|
end
|
327
|
-
|
328
|
-
def test_to_byte_array
|
329
|
-
ba1 = @key1.send(:to_byte_array, 35)
|
330
|
-
ba2 = @key1.send(:to_byte_array, 65537)
|
331
|
-
ba3 = [0, 1, 255, 256, -1, -128, -256].map{|i| @key1.send(:to_byte_array, i)}
|
332
|
-
assert_equal [35], ba1
|
333
|
-
assert_equal [1, 0, 1], ba2
|
334
|
-
assert_equal [[0], [1], [0, 255], [1, 0], [255], [128], [255, 0]], ba3
|
335
|
-
end
|
336
327
|
end
|
337
328
|
|
338
329
|
class SSHKeyEncryptedTest < Test::Unit::TestCase
|
metadata
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sshkey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
5
|
-
prerelease:
|
4
|
+
version: 1.6.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- James Miller
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
description: Generate private/public SSH keypairs using pure Ruby
|
@@ -46,28 +43,28 @@ files:
|
|
46
43
|
- sshkey.gemspec
|
47
44
|
- test/sshkey_test.rb
|
48
45
|
homepage: https://github.com/bensie/sshkey
|
49
|
-
licenses:
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
50
49
|
post_install_message:
|
51
50
|
rdoc_options: []
|
52
51
|
require_paths:
|
53
52
|
- lib
|
54
53
|
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
56
54
|
requirements:
|
57
|
-
- -
|
55
|
+
- - '>='
|
58
56
|
- !ruby/object:Gem::Version
|
59
57
|
version: '0'
|
60
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
59
|
requirements:
|
63
|
-
- -
|
60
|
+
- - '>='
|
64
61
|
- !ruby/object:Gem::Version
|
65
62
|
version: '0'
|
66
63
|
requirements: []
|
67
64
|
rubyforge_project: sshkey
|
68
|
-
rubygems_version:
|
65
|
+
rubygems_version: 2.0.3
|
69
66
|
signing_key:
|
70
|
-
specification_version:
|
67
|
+
specification_version: 4
|
71
68
|
summary: SSH private/public key generator in Ruby
|
72
69
|
test_files:
|
73
70
|
- test/sshkey_test.rb
|