net-ssh 5.0.0.beta1 → 5.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.rubocop_todo.yml +98 -258
  5. data/CHANGES.txt +8 -0
  6. data/Gemfile +1 -3
  7. data/Rakefile +37 -39
  8. data/lib/net/ssh.rb +26 -25
  9. data/lib/net/ssh/authentication/agent.rb +228 -225
  10. data/lib/net/ssh/authentication/certificate.rb +166 -164
  11. data/lib/net/ssh/authentication/constants.rb +17 -14
  12. data/lib/net/ssh/authentication/ed25519.rb +107 -104
  13. data/lib/net/ssh/authentication/ed25519_loader.rb +32 -28
  14. data/lib/net/ssh/authentication/key_manager.rb +5 -3
  15. data/lib/net/ssh/authentication/methods/abstract.rb +53 -47
  16. data/lib/net/ssh/authentication/methods/hostbased.rb +32 -33
  17. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -4
  18. data/lib/net/ssh/authentication/methods/none.rb +10 -10
  19. data/lib/net/ssh/authentication/methods/password.rb +13 -13
  20. data/lib/net/ssh/authentication/methods/publickey.rb +54 -55
  21. data/lib/net/ssh/authentication/pageant.rb +468 -465
  22. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +44 -0
  23. data/lib/net/ssh/authentication/session.rb +127 -123
  24. data/lib/net/ssh/buffer.rb +305 -303
  25. data/lib/net/ssh/buffered_io.rb +163 -162
  26. data/lib/net/ssh/config.rb +230 -227
  27. data/lib/net/ssh/connection/channel.rb +659 -654
  28. data/lib/net/ssh/connection/constants.rb +30 -26
  29. data/lib/net/ssh/connection/event_loop.rb +108 -104
  30. data/lib/net/ssh/connection/keepalive.rb +54 -50
  31. data/lib/net/ssh/connection/session.rb +677 -678
  32. data/lib/net/ssh/connection/term.rb +180 -176
  33. data/lib/net/ssh/errors.rb +101 -99
  34. data/lib/net/ssh/key_factory.rb +108 -108
  35. data/lib/net/ssh/known_hosts.rb +148 -154
  36. data/lib/net/ssh/loggable.rb +56 -54
  37. data/lib/net/ssh/packet.rb +82 -78
  38. data/lib/net/ssh/prompt.rb +55 -53
  39. data/lib/net/ssh/proxy/command.rb +103 -102
  40. data/lib/net/ssh/proxy/errors.rb +12 -8
  41. data/lib/net/ssh/proxy/http.rb +92 -91
  42. data/lib/net/ssh/proxy/https.rb +42 -39
  43. data/lib/net/ssh/proxy/jump.rb +50 -47
  44. data/lib/net/ssh/proxy/socks4.rb +0 -2
  45. data/lib/net/ssh/proxy/socks5.rb +11 -11
  46. data/lib/net/ssh/ruby_compat.rb +1 -0
  47. data/lib/net/ssh/service/forward.rb +364 -362
  48. data/lib/net/ssh/test.rb +85 -83
  49. data/lib/net/ssh/test/channel.rb +146 -142
  50. data/lib/net/ssh/test/extensions.rb +148 -146
  51. data/lib/net/ssh/test/kex.rb +35 -31
  52. data/lib/net/ssh/test/local_packet.rb +48 -44
  53. data/lib/net/ssh/test/packet.rb +87 -84
  54. data/lib/net/ssh/test/remote_packet.rb +35 -31
  55. data/lib/net/ssh/test/script.rb +173 -171
  56. data/lib/net/ssh/test/socket.rb +59 -55
  57. data/lib/net/ssh/transport/algorithms.rb +413 -412
  58. data/lib/net/ssh/transport/cipher_factory.rb +108 -105
  59. data/lib/net/ssh/transport/constants.rb +35 -31
  60. data/lib/net/ssh/transport/ctr.rb +1 -1
  61. data/lib/net/ssh/transport/hmac.rb +1 -1
  62. data/lib/net/ssh/transport/hmac/abstract.rb +67 -64
  63. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +1 -1
  64. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +1 -1
  65. data/lib/net/ssh/transport/identity_cipher.rb +55 -51
  66. data/lib/net/ssh/transport/kex.rb +2 -4
  67. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +47 -40
  68. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +201 -197
  69. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -56
  70. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +94 -87
  71. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +17 -10
  72. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +17 -10
  73. data/lib/net/ssh/transport/key_expander.rb +29 -25
  74. data/lib/net/ssh/transport/openssl.rb +17 -30
  75. data/lib/net/ssh/transport/packet_stream.rb +193 -192
  76. data/lib/net/ssh/transport/server_version.rb +64 -66
  77. data/lib/net/ssh/transport/session.rb +286 -284
  78. data/lib/net/ssh/transport/state.rb +198 -196
  79. data/lib/net/ssh/verifiers/lenient.rb +29 -25
  80. data/lib/net/ssh/verifiers/null.rb +13 -9
  81. data/lib/net/ssh/verifiers/secure.rb +45 -45
  82. data/lib/net/ssh/verifiers/strict.rb +20 -16
  83. data/lib/net/ssh/version.rb +55 -53
  84. data/net-ssh.gemspec +4 -4
  85. data/support/ssh_tunnel_bug.rb +2 -2
  86. metadata +25 -24
  87. metadata.gz.sig +0 -0
@@ -1,169 +1,171 @@
1
1
  require 'securerandom'
2
2
 
3
- module Net; module SSH; module Authentication
4
- # Class for representing an SSH certificate.
5
- #
6
- # http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.10&content-type=text/plain
7
- class Certificate
8
- attr_accessor :nonce
9
- attr_accessor :key
10
- attr_accessor :serial
11
- attr_accessor :type
12
- attr_accessor :key_id
13
- attr_accessor :valid_principals
14
- attr_accessor :valid_after
15
- attr_accessor :valid_before
16
- attr_accessor :critical_options
17
- attr_accessor :extensions
18
- attr_accessor :reserved
19
- attr_accessor :signature_key
20
- attr_accessor :signature
21
-
22
- # Read a certificate blob associated with a key of the given type.
23
- def self.read_certblob(buffer, type)
24
- cert = Certificate.new
25
- cert.nonce = buffer.read_string
26
- cert.key = buffer.read_keyblob(type)
27
- cert.serial = buffer.read_int64
28
- cert.type = type_symbol(buffer.read_long)
29
- cert.key_id = buffer.read_string
30
- cert.valid_principals = buffer.read_buffer.read_all(&:read_string)
31
- cert.valid_after = Time.at(buffer.read_int64)
32
- cert.valid_before = Time.at(buffer.read_int64)
33
- cert.critical_options = read_options(buffer)
34
- cert.extensions = read_options(buffer)
35
- cert.reserved = buffer.read_string
36
- cert.signature_key = buffer.read_buffer.read_key
37
- cert.signature = buffer.read_string
38
- cert
39
- end
40
-
41
- def ssh_type
42
- key.ssh_type + "-cert-v01@openssh.com"
43
- end
44
-
45
- def ssh_signature_type
46
- key.ssh_type
47
- end
48
-
49
- # Serializes the certificate (and key).
50
- def to_blob
51
- Buffer.from(
52
- :raw, to_blob_without_signature,
53
- :string, signature
54
- ).to_s
55
- end
56
-
57
- def ssh_do_sign(data)
58
- key.ssh_do_sign(data)
59
- end
60
-
61
- def ssh_do_verify(sig, data)
62
- key.ssh_do_verify(sig, data)
63
- end
64
-
65
- def to_pem
66
- key.to_pem
67
- end
68
-
69
- def fingerprint
70
- key.fingerprint
71
- end
72
-
73
- # Signs the certificate with key.
74
- def sign!(key, sign_nonce=nil)
75
- # ssh-keygen uses 32 bytes of nonce.
76
- self.nonce = sign_nonce || SecureRandom.random_bytes(32)
77
- self.signature_key = key
78
- self.signature = Net::SSH::Buffer.from(
79
- :string, key.ssh_signature_type,
80
- :mstring, key.ssh_do_sign(to_blob_without_signature)
81
- ).to_s
82
- self
83
- end
84
-
85
- def sign(key, sign_nonce=nil)
86
- cert = clone
87
- cert.sign!(key, sign_nonce)
88
- end
89
-
90
- # Checks whether the certificate's signature was signed by signature key.
91
- def signature_valid?
92
- buffer = Buffer.new(signature)
93
- buffer.read_string # skip signature format
94
- signature_key.ssh_do_verify(buffer.read_string, to_blob_without_signature)
95
- end
96
-
97
- def self.read_options(buffer)
98
- names = []
99
- options = buffer.read_buffer.read_all do |b|
100
- name = b.read_string
101
- names << name
102
- data = b.read_string
103
- data = Buffer.new(data).read_string unless data.empty?
104
- [name, data]
105
- end
106
-
107
- if names.sort != names
108
- raise ArgumentError, "option/extension names must be in sorted order"
3
+ module Net
4
+ module SSH
5
+ module Authentication
6
+ # Class for representing an SSH certificate.
7
+ #
8
+ # http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.10&content-type=text/plain
9
+ class Certificate
10
+ attr_accessor :nonce
11
+ attr_accessor :key
12
+ attr_accessor :serial
13
+ attr_accessor :type
14
+ attr_accessor :key_id
15
+ attr_accessor :valid_principals
16
+ attr_accessor :valid_after
17
+ attr_accessor :valid_before
18
+ attr_accessor :critical_options
19
+ attr_accessor :extensions
20
+ attr_accessor :reserved
21
+ attr_accessor :signature_key
22
+ attr_accessor :signature
23
+
24
+ # Read a certificate blob associated with a key of the given type.
25
+ def self.read_certblob(buffer, type)
26
+ cert = Certificate.new
27
+ cert.nonce = buffer.read_string
28
+ cert.key = buffer.read_keyblob(type)
29
+ cert.serial = buffer.read_int64
30
+ cert.type = type_symbol(buffer.read_long)
31
+ cert.key_id = buffer.read_string
32
+ cert.valid_principals = buffer.read_buffer.read_all(&:read_string)
33
+ cert.valid_after = Time.at(buffer.read_int64)
34
+ cert.valid_before = Time.at(buffer.read_int64)
35
+ cert.critical_options = read_options(buffer)
36
+ cert.extensions = read_options(buffer)
37
+ cert.reserved = buffer.read_string
38
+ cert.signature_key = buffer.read_buffer.read_key
39
+ cert.signature = buffer.read_string
40
+ cert
41
+ end
42
+
43
+ def ssh_type
44
+ key.ssh_type + "-cert-v01@openssh.com"
45
+ end
46
+
47
+ def ssh_signature_type
48
+ key.ssh_type
49
+ end
50
+
51
+ # Serializes the certificate (and key).
52
+ def to_blob
53
+ Buffer.from(
54
+ :raw, to_blob_without_signature,
55
+ :string, signature
56
+ ).to_s
57
+ end
58
+
59
+ def ssh_do_sign(data)
60
+ key.ssh_do_sign(data)
61
+ end
62
+
63
+ def ssh_do_verify(sig, data)
64
+ key.ssh_do_verify(sig, data)
65
+ end
66
+
67
+ def to_pem
68
+ key.to_pem
69
+ end
70
+
71
+ def fingerprint
72
+ key.fingerprint
73
+ end
74
+
75
+ # Signs the certificate with key.
76
+ def sign!(key, sign_nonce=nil)
77
+ # ssh-keygen uses 32 bytes of nonce.
78
+ self.nonce = sign_nonce || SecureRandom.random_bytes(32)
79
+ self.signature_key = key
80
+ self.signature = Net::SSH::Buffer.from(
81
+ :string, key.ssh_signature_type,
82
+ :mstring, key.ssh_do_sign(to_blob_without_signature)
83
+ ).to_s
84
+ self
85
+ end
86
+
87
+ def sign(key, sign_nonce=nil)
88
+ cert = clone
89
+ cert.sign!(key, sign_nonce)
90
+ end
91
+
92
+ # Checks whether the certificate's signature was signed by signature key.
93
+ def signature_valid?
94
+ buffer = Buffer.new(signature)
95
+ buffer.read_string # skip signature format
96
+ signature_key.ssh_do_verify(buffer.read_string, to_blob_without_signature)
97
+ end
98
+
99
+ def self.read_options(buffer)
100
+ names = []
101
+ options = buffer.read_buffer.read_all do |b|
102
+ name = b.read_string
103
+ names << name
104
+ data = b.read_string
105
+ data = Buffer.new(data).read_string unless data.empty?
106
+ [name, data]
107
+ end
108
+
109
+ raise ArgumentError, "option/extension names must be in sorted order" if names.sort != names
110
+
111
+ Hash[options]
112
+ end
113
+ private_class_method :read_options
114
+
115
+ def self.type_symbol(type)
116
+ types = { 1 => :user, 2 => :host }
117
+ raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
118
+ types.fetch(type)
119
+ end
120
+ private_class_method :type_symbol
121
+
122
+ private
123
+
124
+ def type_value(type)
125
+ types = { user: 1, host: 2 }
126
+ raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
127
+ types.fetch(type)
128
+ end
129
+
130
+ def ssh_time(t)
131
+ # Times in certificates are represented as a uint64.
132
+ [[t.to_i, 0].max, 2 << 64 - 1].min
133
+ end
134
+
135
+ def to_blob_without_signature
136
+ Buffer.from(
137
+ :string, ssh_type,
138
+ :string, nonce,
139
+ :raw, key_without_type,
140
+ :int64, serial,
141
+ :long, type_value(type),
142
+ :string, key_id,
143
+ :string, valid_principals.inject(Buffer.new) { |acc, elem| acc.write_string(elem) }.to_s,
144
+ :int64, ssh_time(valid_after),
145
+ :int64, ssh_time(valid_before),
146
+ :string, options_to_blob(critical_options),
147
+ :string, options_to_blob(extensions),
148
+ :string, reserved,
149
+ :string, signature_key.to_blob
150
+ ).to_s
151
+ end
152
+
153
+ def key_without_type
154
+ # key.to_blob gives us e.g. "ssh-rsa,<key>" but we just want "<key>".
155
+ tmp = Buffer.new(key.to_blob)
156
+ tmp.read_string # skip the underlying key type
157
+ tmp.read
158
+ end
159
+
160
+ def options_to_blob(options)
161
+ options.keys.sort.inject(Buffer.new) do |b, name|
162
+ b.write_string(name)
163
+ data = options.fetch(name)
164
+ data = Buffer.from(:string, data).to_s unless data.empty?
165
+ b.write_string(data)
166
+ end.to_s
167
+ end
109
168
  end
110
-
111
- Hash[options]
112
- end
113
- private_class_method :read_options
114
-
115
- def self.type_symbol(type)
116
- types = {1 => :user, 2 => :host}
117
- raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
118
- types.fetch(type)
119
- end
120
- private_class_method :type_symbol
121
-
122
- private
123
-
124
- def type_value(type)
125
- types = {user: 1, host: 2}
126
- raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
127
- types.fetch(type)
128
- end
129
-
130
- def ssh_time(t)
131
- # Times in certificates are represented as a uint64.
132
- [[t.to_i, 0].max, 2<<64 - 1].min
133
- end
134
-
135
- def to_blob_without_signature
136
- Buffer.from(
137
- :string, ssh_type,
138
- :string, nonce,
139
- :raw, key_without_type,
140
- :int64, serial,
141
- :long, type_value(type),
142
- :string, key_id,
143
- :string, valid_principals.inject(Buffer.new) { |acc, elem| acc.write_string(elem) }.to_s,
144
- :int64, ssh_time(valid_after),
145
- :int64, ssh_time(valid_before),
146
- :string, options_to_blob(critical_options),
147
- :string, options_to_blob(extensions),
148
- :string, reserved,
149
- :string, signature_key.to_blob
150
- ).to_s
151
- end
152
-
153
- def key_without_type
154
- # key.to_blob gives us e.g. "ssh-rsa,<key>" but we just want "<key>".
155
- tmp = Buffer.new(key.to_blob)
156
- tmp.read_string # skip the underlying key type
157
- tmp.read
158
- end
159
-
160
- def options_to_blob(options)
161
- options.keys.sort.inject(Buffer.new) do |b, name|
162
- b.write_string(name)
163
- data = options.fetch(name)
164
- data = Buffer.from(:string, data).to_s unless data.empty?
165
- b.write_string(data)
166
- end.to_s
167
169
  end
168
170
  end
169
- end; end; end
171
+ end
@@ -1,18 +1,21 @@
1
- module Net; module SSH; module Authentication
1
+ module Net
2
+ module SSH
3
+ module Authentication
2
4
 
3
- # Describes the constants used by the Net::SSH::Authentication components
4
- # of the Net::SSH library. Individual authentication method implemenations
5
- # may define yet more constants that are specific to their implementation.
6
- module Constants
7
- USERAUTH_REQUEST = 50
8
- USERAUTH_FAILURE = 51
9
- USERAUTH_SUCCESS = 52
10
- USERAUTH_BANNER = 53
5
+ # Describes the constants used by the Net::SSH::Authentication components
6
+ # of the Net::SSH library. Individual authentication method implemenations
7
+ # may define yet more constants that are specific to their implementation.
8
+ module Constants
9
+ USERAUTH_REQUEST = 50
10
+ USERAUTH_FAILURE = 51
11
+ USERAUTH_SUCCESS = 52
12
+ USERAUTH_BANNER = 53
11
13
 
12
- USERAUTH_PASSWD_CHANGEREQ = 60
13
- USERAUTH_PK_OK = 60
14
+ USERAUTH_PASSWD_CHANGEREQ = 60
15
+ USERAUTH_PK_OK = 60
14
16
 
15
- USERAUTH_METHOD_RANGE = 60..79
17
+ USERAUTH_METHOD_RANGE = 60..79
18
+ end
19
+ end
16
20
  end
17
-
18
- end; end; end
21
+ end
@@ -6,144 +6,147 @@ require 'ed25519'
6
6
  require 'base64'
7
7
 
8
8
  require 'net/ssh/transport/cipher_factory'
9
+ require 'net/ssh/authentication/pub_key_fingerprint'
9
10
  require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java"
10
11
 
11
- module Net; module SSH; module Authentication
12
- module ED25519
13
- class SigningKeyFromFile < SimpleDelegator
14
- def initialize(pk,sk)
15
- key = ::Ed25519::SigningKey.from_keypair(sk)
16
- raise ArgumentError, "pk does not match sk" unless pk == key.verify_key.to_bytes
12
+ module Net
13
+ module SSH
14
+ module Authentication
15
+ module ED25519
16
+ class SigningKeyFromFile < SimpleDelegator
17
+ def initialize(pk,sk)
18
+ key = ::Ed25519::SigningKey.from_keypair(sk)
19
+ raise ArgumentError, "pk does not match sk" unless pk == key.verify_key.to_bytes
17
20
 
18
- super(key)
19
- end
20
- end
21
+ super(key)
22
+ end
23
+ end
21
24
 
22
- class PubKey
23
- attr_reader :verify_key
25
+ class PubKey
26
+ include Net::SSH::Authentication::PubKeyFingerprint
24
27
 
25
- def initialize(data)
26
- @verify_key = ::Ed25519::VerifyKey.new(data)
27
- end
28
-
29
- def self.read_keyblob(buffer)
30
- PubKey.new(buffer.read_string)
31
- end
28
+ attr_reader :verify_key
32
29
 
33
- def to_blob
34
- Net::SSH::Buffer.from(:mstring,"ssh-ed25519",:string,@verify_key.to_bytes).to_s
35
- end
30
+ def initialize(data)
31
+ @verify_key = ::Ed25519::VerifyKey.new(data)
32
+ end
36
33
 
37
- def ssh_type
38
- "ssh-ed25519"
39
- end
34
+ def self.read_keyblob(buffer)
35
+ PubKey.new(buffer.read_string)
36
+ end
40
37
 
41
- def ssh_signature_type
42
- ssh_type
43
- end
38
+ def to_blob
39
+ Net::SSH::Buffer.from(:mstring,"ssh-ed25519",:string,@verify_key.to_bytes).to_s
40
+ end
44
41
 
45
- def ssh_do_verify(sig,data)
46
- @verify_key.verify(sig,data)
47
- end
42
+ def ssh_type
43
+ "ssh-ed25519"
44
+ end
48
45
 
49
- def to_pem
50
- # TODO this is not pem
51
- ssh_type + Base64.encode64(@verify_key.to_bytes)
52
- end
46
+ def ssh_signature_type
47
+ ssh_type
48
+ end
53
49
 
54
- def fingerprint
55
- @fingerprint ||= OpenSSL::Digest::MD5.hexdigest(to_blob).scan(/../).join(":")
56
- end
57
- end
50
+ def ssh_do_verify(sig,data)
51
+ @verify_key.verify(sig,data)
52
+ end
58
53
 
59
- class PrivKey
60
- CipherFactory = Net::SSH::Transport::CipherFactory
54
+ def to_pem
55
+ # TODO this is not pem
56
+ ssh_type + Base64.encode64(@verify_key.to_bytes)
57
+ end
58
+ end
61
59
 
62
- MBEGIN = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
63
- MEND = "-----END OPENSSH PRIVATE KEY-----\n"
64
- MAGIC = "openssh-key-v1"
60
+ class PrivKey
61
+ CipherFactory = Net::SSH::Transport::CipherFactory
65
62
 
66
- attr_reader :sign_key
63
+ MBEGIN = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
64
+ MEND = "-----END OPENSSH PRIVATE KEY-----\n"
65
+ MAGIC = "openssh-key-v1"
67
66
 
68
- def initialize(datafull,password)
69
- raise ArgumentError.new("Expected #{MBEGIN} at start of private key") unless datafull.start_with?(MBEGIN)
70
- raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
71
- datab64 = datafull[MBEGIN.size ... -MEND.size]
72
- data = Base64.decode64(datab64)
73
- raise ArgumentError.new("Expected #{MAGIC} at start of decoded private key") unless data.start_with?(MAGIC)
74
- buffer = Net::SSH::Buffer.new(data[MAGIC.size+1 .. -1])
67
+ attr_reader :sign_key
75
68
 
76
- ciphername = buffer.read_string
77
- raise ArgumentError.new("#{ciphername} in private key is not supported") unless
78
- CipherFactory.supported?(ciphername)
69
+ def initialize(datafull,password)
70
+ raise ArgumentError.new("Expected #{MBEGIN} at start of private key") unless datafull.start_with?(MBEGIN)
71
+ raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
72
+ datab64 = datafull[MBEGIN.size...-MEND.size]
73
+ data = Base64.decode64(datab64)
74
+ raise ArgumentError.new("Expected #{MAGIC} at start of decoded private key") unless data.start_with?(MAGIC)
75
+ buffer = Net::SSH::Buffer.new(data[MAGIC.size + 1..-1])
79
76
 
80
- kdfname = buffer.read_string
81
- raise ArgumentError.new("Expected #{kdfname} to be or none or bcrypt") unless %w(none bcrypt).include?(kdfname)
77
+ ciphername = buffer.read_string
78
+ raise ArgumentError.new("#{ciphername} in private key is not supported") unless
79
+ CipherFactory.supported?(ciphername)
82
80
 
83
- kdfopts = Net::SSH::Buffer.new(buffer.read_string)
84
- num_keys = buffer.read_long
85
- raise ArgumentError.new("Only 1 key is supported in ssh keys #{num_keys} was in private key") unless num_keys == 1
86
- _pubkey = buffer.read_string
81
+ kdfname = buffer.read_string
82
+ raise ArgumentError.new("Expected #{kdfname} to be or none or bcrypt") unless %w[none bcrypt].include?(kdfname)
87
83
 
88
- len = buffer.read_long
84
+ kdfopts = Net::SSH::Buffer.new(buffer.read_string)
85
+ num_keys = buffer.read_long
86
+ raise ArgumentError.new("Only 1 key is supported in ssh keys #{num_keys} was in private key") unless num_keys == 1
87
+ _pubkey = buffer.read_string
89
88
 
90
- keylen, blocksize, ivlen = CipherFactory.get_lengths(ciphername, iv_len: true)
91
- raise ArgumentError.new("Private key len:#{len} is not a multiple of #{blocksize}") if
92
- ((len < blocksize) || ((blocksize > 0) && (len % blocksize) != 0))
89
+ len = buffer.read_long
93
90
 
94
- if kdfname == 'bcrypt'
95
- salt = kdfopts.read_string
96
- rounds = kdfopts.read_long
91
+ keylen, blocksize, ivlen = CipherFactory.get_lengths(ciphername, iv_len: true)
92
+ raise ArgumentError.new("Private key len:#{len} is not a multiple of #{blocksize}") if
93
+ ((len < blocksize) || ((blocksize > 0) && (len % blocksize) != 0))
97
94
 
98
- raise "BCryptPbkdf is not implemented for jruby" if RUBY_PLATFORM == "java"
99
- key = BCryptPbkdf::key(password, salt, keylen + ivlen, rounds)
100
- else
101
- key = '\x00' * (keylen + ivlen)
102
- end
95
+ if kdfname == 'bcrypt'
96
+ salt = kdfopts.read_string
97
+ rounds = kdfopts.read_long
103
98
 
104
- cipher = CipherFactory.get(ciphername, key: key[0...keylen], iv:key[keylen...keylen+ivlen], decrypt: true)
99
+ raise "BCryptPbkdf is not implemented for jruby" if RUBY_PLATFORM == "java"
100
+ key = BCryptPbkdf::key(password, salt, keylen + ivlen, rounds)
101
+ else
102
+ key = '\x00' * (keylen + ivlen)
103
+ end
105
104
 
106
- decoded = cipher.update(buffer.remainder_as_buffer.to_s)
107
- decoded << cipher.final
105
+ cipher = CipherFactory.get(ciphername, key: key[0...keylen], iv:key[keylen...keylen + ivlen], decrypt: true)
108
106
 
109
- decoded = Net::SSH::Buffer.new(decoded)
110
- check1 = decoded.read_long
111
- check2 = decoded.read_long
107
+ decoded = cipher.update(buffer.remainder_as_buffer.to_s)
108
+ decoded << cipher.final
112
109
 
113
- raise ArgumentError, "Decrypt failed on private key" if (check1 != check2)
110
+ decoded = Net::SSH::Buffer.new(decoded)
111
+ check1 = decoded.read_long
112
+ check2 = decoded.read_long
113
+
114
+ raise ArgumentError, "Decrypt failed on private key" if (check1 != check2)
114
115
 
115
- _type_name = decoded.read_string
116
- pk = decoded.read_string
117
- sk = decoded.read_string
118
- _comment = decoded.read_string
116
+ _type_name = decoded.read_string
117
+ pk = decoded.read_string
118
+ sk = decoded.read_string
119
+ _comment = decoded.read_string
119
120
 
120
- @pk = pk
121
- @sign_key = SigningKeyFromFile.new(pk,sk)
122
- end
121
+ @pk = pk
122
+ @sign_key = SigningKeyFromFile.new(pk,sk)
123
+ end
123
124
 
124
- def to_blob
125
- public_key.to_blob
126
- end
125
+ def to_blob
126
+ public_key.to_blob
127
+ end
127
128
 
128
- def ssh_type
129
- "ssh-ed25519"
130
- end
129
+ def ssh_type
130
+ "ssh-ed25519"
131
+ end
131
132
 
132
- def ssh_signature_type
133
- ssh_type
134
- end
133
+ def ssh_signature_type
134
+ ssh_type
135
+ end
135
136
 
136
- def public_key
137
- PubKey.new(@pk)
138
- end
137
+ def public_key
138
+ PubKey.new(@pk)
139
+ end
139
140
 
140
- def ssh_do_sign(data)
141
- @sign_key.sign(data)
142
- end
141
+ def ssh_do_sign(data)
142
+ @sign_key.sign(data)
143
+ end
143
144
 
144
- def self.read(data,password)
145
- self.new(data,password)
145
+ def self.read(data,password)
146
+ self.new(data,password)
147
+ end
148
+ end
149
+ end
146
150
  end
147
151
  end
148
152
  end
149
- end; end; end