net-ssh 2.7.0 → 7.3.0

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.
Files changed (199) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/config/rubocop_linter_action.yml +4 -0
  6. data/.github/workflows/ci-with-docker.yml +44 -0
  7. data/.github/workflows/ci.yml +94 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +15 -0
  10. data/.rubocop.yml +22 -0
  11. data/.rubocop_todo.yml +1081 -0
  12. data/CHANGES.txt +387 -0
  13. data/DEVELOPMENT.md +23 -0
  14. data/Dockerfile +29 -0
  15. data/Dockerfile.openssl3 +17 -0
  16. data/Gemfile +13 -0
  17. data/Gemfile.noed25519 +12 -0
  18. data/Gemfile.norbnacl +12 -0
  19. data/ISSUE_TEMPLATE.md +30 -0
  20. data/Manifest +4 -5
  21. data/README.md +303 -0
  22. data/Rakefile +174 -40
  23. data/SECURITY.md +4 -0
  24. data/THANKS.txt +25 -0
  25. data/appveyor.yml +58 -0
  26. data/docker-compose.yml +25 -0
  27. data/lib/net/ssh/authentication/agent.rb +279 -18
  28. data/lib/net/ssh/authentication/certificate.rb +183 -0
  29. data/lib/net/ssh/authentication/constants.rb +17 -15
  30. data/lib/net/ssh/authentication/ed25519.rb +184 -0
  31. data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  32. data/lib/net/ssh/authentication/key_manager.rb +125 -54
  33. data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
  34. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  35. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +19 -12
  36. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  37. data/lib/net/ssh/authentication/methods/password.rb +56 -19
  38. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  39. data/lib/net/ssh/authentication/pageant.rb +483 -246
  40. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  41. data/lib/net/ssh/authentication/session.rb +138 -120
  42. data/lib/net/ssh/buffer.rb +399 -300
  43. data/lib/net/ssh/buffered_io.rb +154 -150
  44. data/lib/net/ssh/config.rb +361 -166
  45. data/lib/net/ssh/connection/channel.rb +640 -596
  46. data/lib/net/ssh/connection/constants.rb +29 -29
  47. data/lib/net/ssh/connection/event_loop.rb +123 -0
  48. data/lib/net/ssh/connection/keepalive.rb +59 -0
  49. data/lib/net/ssh/connection/session.rb +628 -548
  50. data/lib/net/ssh/connection/term.rb +125 -123
  51. data/lib/net/ssh/errors.rb +101 -95
  52. data/lib/net/ssh/key_factory.rb +198 -100
  53. data/lib/net/ssh/known_hosts.rb +221 -98
  54. data/lib/net/ssh/loggable.rb +50 -49
  55. data/lib/net/ssh/packet.rb +83 -79
  56. data/lib/net/ssh/prompt.rb +50 -81
  57. data/lib/net/ssh/proxy/command.rb +108 -60
  58. data/lib/net/ssh/proxy/errors.rb +12 -10
  59. data/lib/net/ssh/proxy/http.rb +82 -78
  60. data/lib/net/ssh/proxy/https.rb +50 -0
  61. data/lib/net/ssh/proxy/jump.rb +54 -0
  62. data/lib/net/ssh/proxy/socks4.rb +5 -8
  63. data/lib/net/ssh/proxy/socks5.rb +18 -20
  64. data/lib/net/ssh/service/forward.rb +383 -255
  65. data/lib/net/ssh/test/channel.rb +145 -136
  66. data/lib/net/ssh/test/extensions.rb +131 -110
  67. data/lib/net/ssh/test/kex.rb +34 -32
  68. data/lib/net/ssh/test/local_packet.rb +46 -44
  69. data/lib/net/ssh/test/packet.rb +89 -70
  70. data/lib/net/ssh/test/remote_packet.rb +32 -30
  71. data/lib/net/ssh/test/script.rb +156 -142
  72. data/lib/net/ssh/test/socket.rb +49 -48
  73. data/lib/net/ssh/test.rb +82 -77
  74. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  75. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  76. data/lib/net/ssh/transport/algorithms.rb +472 -348
  77. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  78. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  79. data/lib/net/ssh/transport/cipher_factory.rb +124 -100
  80. data/lib/net/ssh/transport/constants.rb +32 -24
  81. data/lib/net/ssh/transport/ctr.rb +42 -22
  82. data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
  83. data/lib/net/ssh/transport/hmac/abstract.rb +97 -63
  84. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  85. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  86. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  87. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  88. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  89. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  90. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  91. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  92. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  93. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  94. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  95. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  96. data/lib/net/ssh/transport/hmac.rb +14 -12
  97. data/lib/net/ssh/transport/identity_cipher.rb +54 -44
  98. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  99. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  100. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  101. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  102. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  103. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  104. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
  105. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
  106. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  107. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  108. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  109. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  110. data/lib/net/ssh/transport/kex.rb +15 -12
  111. data/lib/net/ssh/transport/key_expander.rb +24 -20
  112. data/lib/net/ssh/transport/openssl.rb +161 -124
  113. data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  114. data/lib/net/ssh/transport/packet_stream.rb +246 -183
  115. data/lib/net/ssh/transport/server_version.rb +57 -51
  116. data/lib/net/ssh/transport/session.rb +307 -235
  117. data/lib/net/ssh/transport/state.rb +178 -176
  118. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  119. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  120. data/lib/net/ssh/verifiers/always.rb +58 -0
  121. data/lib/net/ssh/verifiers/never.rb +19 -0
  122. data/lib/net/ssh/version.rb +57 -51
  123. data/lib/net/ssh.rb +140 -40
  124. data/net-ssh-public_cert.pem +21 -0
  125. data/net-ssh.gemspec +39 -184
  126. data/support/ssh_tunnel_bug.rb +5 -5
  127. data.tar.gz.sig +0 -0
  128. metadata +205 -99
  129. metadata.gz.sig +0 -0
  130. data/README.rdoc +0 -219
  131. data/Rudyfile +0 -96
  132. data/gem-public_cert.pem +0 -20
  133. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  134. data/lib/net/ssh/authentication/agent/socket.rb +0 -170
  135. data/lib/net/ssh/ruby_compat.rb +0 -51
  136. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  137. data/lib/net/ssh/verifiers/null.rb +0 -12
  138. data/lib/net/ssh/verifiers/secure.rb +0 -54
  139. data/lib/net/ssh/verifiers/strict.rb +0 -24
  140. data/setup.rb +0 -1585
  141. data/support/arcfour_check.rb +0 -20
  142. data/test/README.txt +0 -47
  143. data/test/authentication/methods/common.rb +0 -28
  144. data/test/authentication/methods/test_abstract.rb +0 -51
  145. data/test/authentication/methods/test_hostbased.rb +0 -114
  146. data/test/authentication/methods/test_keyboard_interactive.rb +0 -100
  147. data/test/authentication/methods/test_none.rb +0 -41
  148. data/test/authentication/methods/test_password.rb +0 -52
  149. data/test/authentication/methods/test_publickey.rb +0 -148
  150. data/test/authentication/test_agent.rb +0 -205
  151. data/test/authentication/test_key_manager.rb +0 -218
  152. data/test/authentication/test_session.rb +0 -108
  153. data/test/common.rb +0 -108
  154. data/test/configs/eqsign +0 -3
  155. data/test/configs/exact_match +0 -8
  156. data/test/configs/host_plus +0 -10
  157. data/test/configs/multihost +0 -4
  158. data/test/configs/nohost +0 -19
  159. data/test/configs/numeric_host +0 -4
  160. data/test/configs/send_env +0 -2
  161. data/test/configs/substitutes +0 -8
  162. data/test/configs/wild_cards +0 -14
  163. data/test/connection/test_channel.rb +0 -467
  164. data/test/connection/test_session.rb +0 -526
  165. data/test/known_hosts/github +0 -1
  166. data/test/manual/test_forward.rb +0 -223
  167. data/test/start/test_options.rb +0 -36
  168. data/test/start/test_transport.rb +0 -28
  169. data/test/test_all.rb +0 -11
  170. data/test/test_buffer.rb +0 -433
  171. data/test/test_buffered_io.rb +0 -63
  172. data/test/test_config.rb +0 -151
  173. data/test/test_key_factory.rb +0 -173
  174. data/test/test_known_hosts.rb +0 -13
  175. data/test/transport/hmac/test_md5.rb +0 -41
  176. data/test/transport/hmac/test_md5_96.rb +0 -27
  177. data/test/transport/hmac/test_none.rb +0 -34
  178. data/test/transport/hmac/test_ripemd160.rb +0 -36
  179. data/test/transport/hmac/test_sha1.rb +0 -36
  180. data/test/transport/hmac/test_sha1_96.rb +0 -27
  181. data/test/transport/hmac/test_sha2_256.rb +0 -37
  182. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  183. data/test/transport/hmac/test_sha2_512.rb +0 -37
  184. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  185. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  186. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -146
  187. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -92
  188. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -34
  189. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  190. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  191. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  192. data/test/transport/test_algorithms.rb +0 -330
  193. data/test/transport/test_cipher_factory.rb +0 -443
  194. data/test/transport/test_hmac.rb +0 -34
  195. data/test/transport/test_identity_cipher.rb +0 -40
  196. data/test/transport/test_packet_stream.rb +0 -1755
  197. data/test/transport/test_server_version.rb +0 -78
  198. data/test/transport/test_session.rb +0 -319
  199. data/test/transport/test_state.rb +0 -181
@@ -1,13 +1,21 @@
1
- module Net; module SSH; module Transport; module Kex
1
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
2
2
 
3
- # A key-exchange service implementing the "ecdh-sha2-nistp521"
4
- # key-exchange algorithm. (defined in RFC 5656)
5
- class EcdhSHA2NistP521 < EcdhSHA2NistP256
6
- def digester
7
- OpenSSL::Digest::SHA512
8
- end
9
- def curve_name
10
- OpenSSL::PKey::EC::CurveNameAlias['nistp521']
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
7
+ # A key-exchange service implementing the "ecdh-sha2-nistp521"
8
+ # key-exchange algorithm. (defined in RFC 5656)
9
+ class EcdhSHA2NistP521 < EcdhSHA2NistP256
10
+ def digester
11
+ OpenSSL::Digest::SHA512
12
+ end
13
+
14
+ def curve_name
15
+ OpenSSL::PKey::EC::CurveNameAlias['nistp521']
16
+ end
17
+ end
18
+ end
11
19
  end
12
20
  end
13
- end; end; end; end
21
+ end
@@ -1,28 +1,31 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
  require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
3
+ require 'net/ssh/transport/kex/diffie_hellman_group14_sha256'
3
4
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
4
5
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
6
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
7
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
8
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
9
+ require 'net/ssh/transport/kex/curve25519_sha256_loader'
5
10
 
6
11
  module Net::SSH::Transport
7
12
  module Kex
8
13
  # Maps the supported key-exchange algorithms as named by the SSH protocol
9
14
  # to their corresponding implementors.
10
15
  MAP = {
16
+ 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
17
+ 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
18
+ 'diffie-hellman-group14-sha256' => DiffieHellmanGroup14SHA256,
11
19
  'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
12
- 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
13
- 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
20
+ 'diffie-hellman-group-exchange-sha256' => DiffieHellmanGroupExchangeSHA256,
21
+ 'ecdh-sha2-nistp256' => EcdhSHA2NistP256,
22
+ 'ecdh-sha2-nistp384' => EcdhSHA2NistP384,
23
+ 'ecdh-sha2-nistp521' => EcdhSHA2NistP521
14
24
  }
15
- if defined?(DiffieHellmanGroupExchangeSHA256)
16
- MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256
17
- end
18
- if defined?(OpenSSL::PKey::EC)
19
- require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
20
- require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
21
- require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
22
25
 
23
- MAP['ecdh-sha2-nistp256'] = EcdhSHA2NistP256
24
- MAP['ecdh-sha2-nistp384'] = EcdhSHA2NistP384
25
- MAP['ecdh-sha2-nistp521'] = EcdhSHA2NistP521
26
+ if Net::SSH::Transport::Kex::Curve25519Sha256Loader::LOADED
27
+ MAP['curve25519-sha256'] = Curve25519Sha256
28
+ MAP['curve25519-sha256@libssh.org'] = Curve25519Sha256
26
29
  end
27
30
  end
28
31
  end
@@ -1,26 +1,30 @@
1
- module Net; module SSH; module Transport
2
- module KeyExpander
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+ module KeyExpander
5
+ # Generate a key value in accordance with the SSH2 specification.
6
+ # (RFC4253 7.2. "Output from Key Exchange")
7
+ def self.expand_key(bytes, start, options = {})
8
+ if bytes == 0
9
+ return ""
10
+ end
3
11
 
4
- # Generate a key value in accordance with the SSH2 specification.
5
- # (RFC4253 7.2. "Output from Key Exchange")
6
- def self.expand_key(bytes, start, options={})
7
- if bytes == 0
8
- return ""
9
- end
12
+ k = start[0, bytes]
13
+ return k if k.length >= bytes
10
14
 
11
- k = start[0, bytes]
15
+ digester = options[:digester] or raise 'No digester supplied'
16
+ shared = options[:shared] or raise 'No shared secret supplied'
17
+ hash = options[:hash] or raise 'No hash supplied'
12
18
 
13
- digester = options[:digester] or raise 'No digester supplied'
14
- shared = options[:shared] or raise 'No shared secret supplied'
15
- hash = options[:hash] or raise 'No hash supplied'
19
+ while k.length < bytes
20
+ step = digester.digest(shared + hash + k)
21
+ bytes_needed = bytes - k.length
22
+ k << step[0, bytes_needed]
23
+ end
16
24
 
17
- while k.length < bytes
18
- step = digester.digest(shared + hash + k)
19
- bytes_needed = bytes - k.length
20
- k << step[0, bytes_needed]
25
+ return k
26
+ end
27
+ end
21
28
  end
22
-
23
- return k
24
- end
25
29
  end
26
- end; end; end
30
+ end
@@ -1,13 +1,11 @@
1
- # -*- coding: utf-8 -*-
2
1
  require 'openssl'
2
+ require 'net/ssh/authentication/pub_key_fingerprint'
3
3
 
4
4
  module OpenSSL
5
-
6
5
  # This class is originally defined in the OpenSSL module. As needed, methods
7
6
  # have been added to it by the Net::SSH module for convenience in dealing with
8
7
  # SSH functionality.
9
8
  class BN
10
-
11
9
  # Converts a BN object to a string. The format used is that which is
12
10
  # required by the SSH2 protocol.
13
11
  def to_ssh
@@ -16,63 +14,76 @@ module OpenSSL
16
14
  else
17
15
  buf = to_s(2)
18
16
  if buf.getbyte(0)[7] == 1
19
- return [buf.length+1, 0, buf].pack("NCA*")
17
+ return [buf.length + 1, 0, buf].pack("NCA*")
20
18
  else
21
19
  return [buf.length, buf].pack("NA*")
22
20
  end
23
21
  end
24
22
  end
25
-
26
23
  end
27
24
 
28
25
  module PKey
29
-
30
26
  class PKey
31
- def fingerprint
32
- @fingerprint ||= OpenSSL::Digest::MD5.hexdigest(to_blob).scan(/../).join(":")
33
- end
27
+ include Net::SSH::Authentication::PubKeyFingerprint
34
28
  end
35
29
 
36
30
  # This class is originally defined in the OpenSSL module. As needed, methods
37
31
  # have been added to it by the Net::SSH module for convenience in dealing
38
32
  # with SSH functionality.
39
33
  class DH
40
-
41
34
  # Determines whether the pub_key for this key is valid. (This algorithm
42
35
  # lifted more-or-less directly from OpenSSH, dh.c, dh_pub_is_valid.)
43
36
  def valid?
44
37
  return false if pub_key.nil? || pub_key < 0
38
+
45
39
  bits_set = 0
46
40
  pub_key.num_bits.times { |i| bits_set += 1 if pub_key.bit_set?(i) }
47
- return ( bits_set > 1 && pub_key < p )
41
+ return (bits_set > 1 && pub_key < p)
48
42
  end
49
-
50
43
  end
51
44
 
52
45
  # This class is originally defined in the OpenSSL module. As needed, methods
53
46
  # have been added to it by the Net::SSH module for convenience in dealing
54
47
  # with SSH functionality.
55
48
  class RSA
56
-
57
49
  # Returns "ssh-rsa", which is the description of this key type used by the
58
50
  # SSH2 protocol.
59
51
  def ssh_type
60
52
  "ssh-rsa"
61
53
  end
62
54
 
55
+ alias ssh_signature_type ssh_type
56
+
63
57
  # Converts the key to a blob, according to the SSH2 protocol.
64
58
  def to_blob
65
59
  @blob ||= Net::SSH::Buffer.from(:string, ssh_type, :bignum, e, :bignum, n).to_s
66
60
  end
67
61
 
68
62
  # Verifies the given signature matches the given data.
69
- def ssh_do_verify(sig, data)
70
- verify(OpenSSL::Digest::SHA1.new, sig, data)
63
+ def ssh_do_verify(sig, data, options = {})
64
+ digester =
65
+ if options[:host_key] == "rsa-sha2-512"
66
+ OpenSSL::Digest::SHA512.new
67
+ elsif options[:host_key] == "rsa-sha2-256"
68
+ OpenSSL::Digest::SHA256.new
69
+ else
70
+ OpenSSL::Digest::SHA1.new
71
+ end
72
+
73
+ verify(digester, sig, data)
71
74
  end
72
75
 
73
76
  # Returns the signature for the given data.
74
- def ssh_do_sign(data)
75
- sign(OpenSSL::Digest::SHA1.new, data)
77
+ def ssh_do_sign(data, sig_alg = nil)
78
+ digester =
79
+ if sig_alg == "rsa-sha2-512"
80
+ OpenSSL::Digest::SHA512.new
81
+ elsif sig_alg == "rsa-sha2-256"
82
+ OpenSSL::Digest::SHA256.new
83
+ else
84
+ OpenSSL::Digest::SHA1.new
85
+ end
86
+ sign(digester, data)
76
87
  end
77
88
  end
78
89
 
@@ -80,158 +91,184 @@ module OpenSSL
80
91
  # have been added to it by the Net::SSH module for convenience in dealing
81
92
  # with SSH functionality.
82
93
  class DSA
83
-
84
94
  # Returns "ssh-dss", which is the description of this key type used by the
85
95
  # SSH2 protocol.
86
96
  def ssh_type
87
97
  "ssh-dss"
88
98
  end
89
99
 
100
+ alias ssh_signature_type ssh_type
101
+
90
102
  # Converts the key to a blob, according to the SSH2 protocol.
91
103
  def to_blob
92
104
  @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
93
- :bignum, p, :bignum, q, :bignum, g, :bignum, pub_key).to_s
105
+ :bignum, p, :bignum, q, :bignum, g, :bignum, pub_key).to_s
94
106
  end
95
107
 
96
108
  # Verifies the given signature matches the given data.
97
- def ssh_do_verify(sig, data)
98
- sig_r = sig[0,20].unpack("H*")[0].to_i(16)
99
- sig_s = sig[20,20].unpack("H*")[0].to_i(16)
109
+ def ssh_do_verify(sig, data, options = {})
110
+ sig_r = sig[0, 20].unpack("H*")[0].to_i(16)
111
+ sig_s = sig[20, 20].unpack("H*")[0].to_i(16)
100
112
  a1sig = OpenSSL::ASN1::Sequence([
101
- OpenSSL::ASN1::Integer(sig_r),
102
- OpenSSL::ASN1::Integer(sig_s)
103
- ])
104
- return verify(OpenSSL::Digest::DSS1.new, a1sig.to_der, data)
113
+ OpenSSL::ASN1::Integer(sig_r),
114
+ OpenSSL::ASN1::Integer(sig_s)
115
+ ])
116
+ return verify(OpenSSL::Digest::SHA1.new, a1sig.to_der, data)
105
117
  end
106
118
 
107
119
  # Signs the given data.
108
- def ssh_do_sign(data)
109
- sig = sign( OpenSSL::Digest::DSS1.new, data)
110
- a1sig = OpenSSL::ASN1.decode( sig )
120
+ def ssh_do_sign(data, sig_alg = nil)
121
+ sig = sign(OpenSSL::Digest::SHA1.new, data)
122
+ a1sig = OpenSSL::ASN1.decode(sig)
111
123
 
112
124
  sig_r = a1sig.value[0].value.to_s(2)
113
125
  sig_s = a1sig.value[1].value.to_s(2)
114
126
 
115
- if sig_r.length > 20 || sig_s.length > 20
116
- raise OpenSSL::PKey::DSAError, "bad sig size"
117
- end
127
+ sig_size = params["q"].num_bits / 8
128
+ raise OpenSSL::PKey::DSAError, "bad sig size" if sig_r.length > sig_size || sig_s.length > sig_size
118
129
 
119
- sig_r = "\0" * ( 20 - sig_r.length ) + sig_r if sig_r.length < 20
120
- sig_s = "\0" * ( 20 - sig_s.length ) + sig_s if sig_s.length < 20
130
+ sig_r = "\0" * (20 - sig_r.length) + sig_r if sig_r.length < 20
131
+ sig_s = "\0" * (20 - sig_s.length) + sig_s if sig_s.length < 20
121
132
 
122
133
  return sig_r + sig_s
123
134
  end
124
135
  end
125
136
 
126
- if defined?(OpenSSL::PKey::EC)
127
- # This class is originally defined in the OpenSSL module. As needed, methods
128
- # have been added to it by the Net::SSH module for convenience in dealing
129
- # with SSH functionality.
130
- class EC
131
- CurveNameAlias = {
132
- "nistp256" => "prime256v1",
133
- "nistp384" => "secp384r1",
134
- "nistp521" => "secp521r1",
135
- }
136
-
137
- CurveNameAliasInv = {
138
- "prime256v1" => "nistp256",
139
- "secp384r1" => "nistp384",
140
- "secp521r1" => "nistp521",
141
- }
142
-
143
- def self.read_keyblob(curve_name_in_type, buffer)
144
- curve_name_in_key = buffer.read_string
145
- unless curve_name_in_type == curve_name_in_key
146
- raise Net::SSH::Exception, "curve name mismatched (`#{curve_name_in_key}' with `#{curve_name_in_type}')"
147
- end
148
- public_key_oct = buffer.read_string
149
- begin
150
- key = OpenSSL::PKey::EC.new(OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key])
151
- group = key.group
152
- point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
153
- key.public_key = point
154
-
155
- return key
156
- rescue OpenSSL::PKey::ECError
157
- raise NotImplementedError, "unsupported key type `#{type}'"
158
- end
159
-
137
+ # This class is originally defined in the OpenSSL module. As needed, methods
138
+ # have been added to it by the Net::SSH module for convenience in dealing
139
+ # with SSH functionality.
140
+ class EC
141
+ CurveNameAlias = {
142
+ 'nistp256' => 'prime256v1',
143
+ 'nistp384' => 'secp384r1',
144
+ 'nistp521' => 'secp521r1'
145
+ }.freeze
146
+
147
+ CurveNameAliasInv = {
148
+ 'prime256v1' => 'nistp256',
149
+ 'secp384r1' => 'nistp384',
150
+ 'secp521r1' => 'nistp521'
151
+ }.freeze
152
+
153
+ def self.read_keyblob(curve_name_in_type, buffer)
154
+ curve_name_in_key = buffer.read_string
155
+
156
+ unless curve_name_in_type == curve_name_in_key
157
+ raise Net::SSH::Exception, "curve name mismatched (`#{curve_name_in_key}' with `#{curve_name_in_type}')"
160
158
  end
161
159
 
162
- # Returns the description of this key type used by the
163
- # SSH2 protocol, like "ecdsa-sha2-nistp256"
164
- def ssh_type
165
- "ecdsa-sha2-#{CurveNameAliasInv[self.group.curve_name]}"
160
+ public_key_oct = buffer.read_string
161
+ begin
162
+ curvename = OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key]
163
+ group = OpenSSL::PKey::EC::Group.new(curvename)
164
+ point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
165
+ asn1 = OpenSSL::ASN1::Sequence(
166
+ [
167
+ OpenSSL::ASN1::Sequence(
168
+ [
169
+ OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
170
+ OpenSSL::ASN1::ObjectId(curvename)
171
+ ]
172
+ ),
173
+ OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
174
+ ]
175
+ )
176
+
177
+ key = OpenSSL::PKey::EC.new(asn1.to_der)
178
+
179
+ return key
180
+ rescue OpenSSL::PKey::ECError
181
+ raise NotImplementedError, "unsupported key type `#{type}'"
166
182
  end
183
+ end
167
184
 
168
- def digester
169
- if self.group.curve_name =~ /^[a-z]+(\d+)\w*\z/
170
- curve_size = $1.to_i
171
- if curve_size <= 256
172
- OpenSSL::Digest::SHA256.new
173
- elsif curve_size <= 384
174
- OpenSSL::Digest::SHA384.new
175
- else
176
- OpenSSL::Digest::SHA512.new
177
- end
178
- else
185
+ # Returns the description of this key type used by the
186
+ # SSH2 protocol, like "ecdsa-sha2-nistp256"
187
+ def ssh_type
188
+ "ecdsa-sha2-#{CurveNameAliasInv[group.curve_name]}"
189
+ end
190
+
191
+ alias ssh_signature_type ssh_type
192
+
193
+ def digester
194
+ if group.curve_name =~ /^[a-z]+(\d+)\w*\z/
195
+ curve_size = Regexp.last_match(1).to_i
196
+ if curve_size <= 256
179
197
  OpenSSL::Digest::SHA256.new
198
+ elsif curve_size <= 384
199
+ OpenSSL::Digest::SHA384.new
200
+ else
201
+ OpenSSL::Digest::SHA512.new
180
202
  end
203
+ else
204
+ OpenSSL::Digest::SHA256.new
181
205
  end
182
- private :digester
206
+ end
207
+ private :digester
183
208
 
184
- # Converts the key to a blob, according to the SSH2 protocol.
185
- def to_blob
186
- @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
187
- :string, CurveNameAliasInv[self.group.curve_name],
188
- :string, self.public_key.to_bn.to_s(2)).to_s
189
- @blob
209
+ # Converts the key to a blob, according to the SSH2 protocol.
210
+ def to_blob
211
+ @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
212
+ :string, CurveNameAliasInv[group.curve_name],
213
+ :mstring, public_key.to_bn.to_s(2)).to_s
214
+ @blob
215
+ end
216
+
217
+ # Verifies the given signature matches the given data.
218
+ def ssh_do_verify(sig, data, options = {})
219
+ digest = digester.digest(data)
220
+ a1sig = nil
221
+
222
+ begin
223
+ sig_r_len = sig[0, 4].unpack('H*')[0].to_i(16)
224
+ sig_l_len = sig[4 + sig_r_len, 4].unpack('H*')[0].to_i(16)
225
+
226
+ sig_r = sig[4, sig_r_len].unpack('H*')[0]
227
+ sig_s = sig[4 + sig_r_len + 4, sig_l_len].unpack('H*')[0]
228
+
229
+ a1sig = OpenSSL::ASN1::Sequence([
230
+ OpenSSL::ASN1::Integer(sig_r.to_i(16)),
231
+ OpenSSL::ASN1::Integer(sig_s.to_i(16))
232
+ ])
233
+ rescue StandardError
190
234
  end
191
235
 
192
- # Verifies the given signature matches the given data.
193
- def ssh_do_verify(sig, data)
194
- digest = digester.digest(data)
195
- a1sig = nil
236
+ if a1sig.nil?
237
+ return false
238
+ else
239
+ dsa_verify_asn1(digest, a1sig.to_der)
240
+ end
241
+ end
196
242
 
197
- begin
198
- sig_r_len = sig[0,4].unpack("H*")[0].to_i(16)
199
- sig_l_len = sig[4+sig_r_len,4].unpack("H*")[0].to_i(16)
243
+ # Returns the signature for the given data.
244
+ def ssh_do_sign(data, sig_alg = nil)
245
+ digest = digester.digest(data)
246
+ sig = dsa_sign_asn1(digest)
247
+ a1sig = OpenSSL::ASN1.decode(sig)
200
248
 
201
- sig_r = sig[4,sig_r_len].unpack("H*")[0]
202
- sig_s = sig[4+sig_r_len+4,sig_l_len].unpack("H*")[0]
249
+ sig_r = a1sig.value[0].value
250
+ sig_s = a1sig.value[1].value
203
251
 
204
- a1sig = OpenSSL::ASN1::Sequence([
205
- OpenSSL::ASN1::Integer(sig_r.to_i(16)),
206
- OpenSSL::ASN1::Integer(sig_s.to_i(16)),
207
- ])
208
- rescue
209
- end
252
+ Net::SSH::Buffer.from(:bignum, sig_r, :bignum, sig_s).to_s
253
+ end
210
254
 
211
- if a1sig == nil
212
- return false
213
- else
214
- dsa_verify_asn1(digest, a1sig.to_der)
215
- end
255
+ class Point
256
+ # Returns the description of this key type used by the
257
+ # SSH2 protocol, like "ecdsa-sha2-nistp256"
258
+ def ssh_type
259
+ "ecdsa-sha2-#{CurveNameAliasInv[group.curve_name]}"
216
260
  end
217
261
 
218
- # Returns the signature for the given data.
219
- def ssh_do_sign(data)
220
- digest = digester.digest(data)
221
- sig = dsa_sign_asn1(digest)
222
- a1sig = OpenSSL::ASN1.decode( sig )
262
+ alias ssh_signature_type ssh_type
223
263
 
224
- sig_r = a1sig.value[0].value
225
- sig_s = a1sig.value[1].value
226
-
227
- return Net::SSH::Buffer.from(:bignum, sig_r, :bignum, sig_s).to_s
264
+ # Converts the key to a blob, according to the SSH2 protocol.
265
+ def to_blob
266
+ @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
267
+ :string, CurveNameAliasInv[group.curve_name],
268
+ :mstring, to_bn.to_s(2)).to_s
269
+ @blob
228
270
  end
229
271
  end
230
- else
231
- class OpenSSL::PKey::ECError < RuntimeError
232
- # for compatibility with interpreters
233
- # without EC support (i.e. JRuby)
234
- end
235
272
  end
236
273
  end
237
274
  end
@@ -0,0 +1,8 @@
1
+ module Net::SSH::Transport
2
+ # we add those mehtods to OpenSSL::Chipher instances
3
+ module OpenSSLCipherExtensions
4
+ def implicit_mac?
5
+ false
6
+ end
7
+ end
8
+ end