sshkey 1.6.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://secure.travis-ci.org/bensie/sshkey.png)](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
|