sshkey 1.6.0 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -9,8 +9,33 @@ rvm:
9
9
  - jruby-19mode
10
10
  - jruby-20mode
11
11
  - jruby-head
12
- - rbx-18mode
13
- - rbx-19mode
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
@@ -1,5 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "jruby-openssl", "~> 0.8.2", :platform => :jruby
3
+ gem "jruby-openssl", ">= 0.8.2", :platforms => :jruby
4
+ gem "rubysl", "~> 2.0.14", :platforms => :rbx
4
5
 
5
6
  gemspec
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 or later), Rubinius. Ruby must be compiled with OpenSSL support.
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
- ### Validate existing SSH public keys
155
+ ### Existing SSH public keys
156
156
 
157
- 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.
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
@@ -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.size * 8
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 = [0,0,0,7].pack("C*")
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
- if Base64.encode64(decoded).gsub("\n", "") != encoded_key || decoded.sub!(/^#{prefix}#{ssh_type}/, "").nil?
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
- index = 0
105
- until unpacked[index].nil?
106
- datum_size = from_byte_array unpacked[index..index+4-1], 4
107
- index = index + 4
108
- datum = from_byte_array unpacked[index..index+datum_size-1], datum_size
109
- data << datum
110
- index = index + datum_size
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.gsub(/^(ssh-[dr]s[as]\s+)|(\s+.+\@.+)|\n/, ''))
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
- out = [0,0,0,7].pack("C*")
290
- out += SSH_TYPES[type]
291
-
292
- SSH_CONVERSION[type].each do |method|
293
- byte_array = to_byte_array(key_object.public_key.send(method).to_i)
294
- out += encode_unsigned_int_32(byte_array.length).pack("c*")
295
- out += byte_array.pack("C*")
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
@@ -1,3 +1,3 @@
1
1
  class SSHKey
2
- VERSION = "1.6.0"
2
+ VERSION = "1.6.1"
3
3
  end
@@ -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
 
@@ -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.0
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-09-11 00:00:00.000000000 Z
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: 1.8.23
65
+ rubygems_version: 2.0.3
69
66
  signing_key:
70
- specification_version: 3
67
+ specification_version: 4
71
68
  summary: SSH private/public key generator in Ruby
72
69
  test_files:
73
70
  - test/sshkey_test.rb