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,55 +1,65 @@
1
- module Net; module SSH; module Transport
2
-
3
- # A cipher that does nothing but pass the data through, unchanged. This
4
- # keeps things in the code nice and clean when a cipher has not yet been
5
- # determined (i.e., during key exchange).
6
- class IdentityCipher
7
- class <<self
8
- # A default block size of 8 is required by the SSH2 protocol.
9
- def block_size
10
- 8
11
- end
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+ # A cipher that does nothing but pass the data through, unchanged. This
5
+ # keeps things in the code nice and clean when a cipher has not yet been
6
+ # determined (i.e., during key exchange).
7
+ class IdentityCipher
8
+ class << self
9
+ # A default block size of 8 is required by the SSH2 protocol.
10
+ def block_size
11
+ 8
12
+ end
12
13
 
13
- # Returns an arbitrary integer.
14
- def iv_len
15
- 4
16
- end
14
+ def key_length
15
+ 0
16
+ end
17
17
 
18
- # Does nothing. Returns self.
19
- def encrypt
20
- self
21
- end
18
+ # Returns an arbitrary integer.
19
+ def iv_len
20
+ 4
21
+ end
22
22
 
23
- # Does nothing. Returns self.
24
- def decrypt
25
- self
26
- end
23
+ # Does nothing. Returns self.
24
+ def encrypt
25
+ self
26
+ end
27
27
 
28
- # Passes its single argument through unchanged.
29
- def update(text)
30
- text
31
- end
28
+ # Does nothing. Returns self.
29
+ def decrypt
30
+ self
31
+ end
32
32
 
33
- # Returns the empty string.
34
- def final
35
- ""
36
- end
33
+ # Passes its single argument through unchanged.
34
+ def update(text)
35
+ text
36
+ end
37
37
 
38
- # The name of this cipher, which is "identity".
39
- def name
40
- "identity"
41
- end
38
+ # Returns the empty string.
39
+ def final
40
+ ""
41
+ end
42
42
 
43
- # Does nothing. Returns nil.
44
- def iv=(v)
45
- nil
46
- end
43
+ # The name of this cipher, which is "identity".
44
+ def name
45
+ "identity"
46
+ end
47
+
48
+ # Does nothing. Returns nil.
49
+ def iv=(v)
50
+ nil
51
+ end
47
52
 
48
- # Does nothing. Returns self.
49
- def reset
50
- self
53
+ # Does nothing. Returns self.
54
+ def reset
55
+ self
56
+ end
57
+
58
+ def implicit_mac?
59
+ false
60
+ end
61
+ end
51
62
  end
52
63
  end
53
64
  end
54
-
55
- end; end; end
65
+ end
@@ -0,0 +1,130 @@
1
+ require 'net/ssh/buffer'
2
+ require 'net/ssh/errors'
3
+ require 'net/ssh/loggable'
4
+ require 'net/ssh/transport/openssl'
5
+ require 'net/ssh/transport/constants'
6
+
7
+ module Net
8
+ module SSH
9
+ module Transport
10
+ module Kex
11
+ # Abstract class that implement Diffie-Hellman Key Exchange
12
+ # See https://tools.ietf.org/html/rfc4253#page-21
13
+ class Abstract
14
+ include Loggable
15
+ include Constants
16
+
17
+ attr_reader :algorithms
18
+ attr_reader :connection
19
+ attr_reader :data
20
+ attr_reader :dh
21
+
22
+ # Create a new instance of the Diffie-Hellman Key Exchange algorithm.
23
+ # The Diffie-Hellman (DH) key exchange provides a shared secret that
24
+ # cannot be determined by either party alone. The key exchange is
25
+ # combined with a signature with the host key to provide host
26
+ # authentication.
27
+ def initialize(algorithms, connection, data)
28
+ @algorithms = algorithms
29
+ @connection = connection
30
+
31
+ @data = data.dup
32
+ @dh = generate_key
33
+ @logger = @data.delete(:logger)
34
+ end
35
+
36
+ # Perform the key-exchange for the given session, with the given
37
+ # data. This method will return a hash consisting of the
38
+ # following keys:
39
+ #
40
+ # * :session_id
41
+ # * :server_key
42
+ # * :shared_secret
43
+ # * :hashing_algorithm
44
+ #
45
+ # The caller is expected to be able to understand how to use these
46
+ # deliverables.
47
+ def exchange_keys
48
+ result = send_kexinit
49
+ verify_server_key(result[:server_key])
50
+ session_id = verify_signature(result)
51
+ confirm_newkeys
52
+
53
+ {
54
+ session_id: session_id,
55
+ server_key: result[:server_key],
56
+ shared_secret: result[:shared_secret],
57
+ hashing_algorithm: digester
58
+ }
59
+ end
60
+
61
+ def digester
62
+ raise NotImplementedError, 'abstract class: digester not implemented'
63
+ end
64
+
65
+ private
66
+
67
+ def matching?(key_ssh_type, host_key_alg)
68
+ return true if key_ssh_type == host_key_alg
69
+ return true if key_ssh_type == 'ssh-rsa' && ['rsa-sha2-512', 'rsa-sha2-256'].include?(host_key_alg)
70
+ end
71
+
72
+ # Verify that the given key is of the expected type, and that it
73
+ # really is the key for the session's host. Raise Net::SSH::Exception
74
+ # if it is not.
75
+ def verify_server_key(key) # :nodoc:
76
+ unless matching?(key.ssh_type, algorithms.host_key)
77
+ raise Net::SSH::Exception, "host key algorithm mismatch '#{key.ssh_type}' != '#{algorithms.host_key}'"
78
+ end
79
+
80
+ blob, fingerprint = generate_key_fingerprint(key)
81
+
82
+ unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
83
+ raise Net::SSH::Exception, 'host key verification failed'
84
+ end
85
+ end
86
+
87
+ def generate_key_fingerprint(key)
88
+ blob = Net::SSH::Buffer.from(:key, key).to_s
89
+
90
+ fingerprint = Net::SSH::Authentication::PubKeyFingerprint.fingerprint(blob, @connection.options[:fingerprint_hash] || 'SHA256')
91
+
92
+ [blob, fingerprint]
93
+ rescue StandardError => e
94
+ [nil, "(could not generate fingerprint: #{e.message})"]
95
+ end
96
+
97
+ # Verify the signature that was received. Raise Net::SSH::Exception
98
+ # if the signature could not be verified. Otherwise, return the new
99
+ # session-id.
100
+ def verify_signature(result) # :nodoc:
101
+ response = build_signature_buffer(result)
102
+
103
+ hash = digester.digest(response.to_s)
104
+
105
+ server_key = result[:server_key]
106
+ server_sig = result[:server_sig]
107
+ unless connection.host_key_verifier.verify_signature { server_key.ssh_do_verify(server_sig, hash, host_key: algorithms.host_key) }
108
+ raise Net::SSH::Exception, 'could not verify server signature'
109
+ end
110
+
111
+ hash
112
+ end
113
+
114
+ # Send the NEWKEYS message, and expect the NEWKEYS message in
115
+ # reply.
116
+ def confirm_newkeys # :nodoc:
117
+ # send own NEWKEYS message first (the wodSSHServer won't send first)
118
+ response = Net::SSH::Buffer.new
119
+ response.write_byte(NEWKEYS)
120
+ connection.send_message(response)
121
+
122
+ # wait for the server's NEWKEYS message
123
+ buffer = connection.next_message
124
+ raise Net::SSH::Exception, 'expected NEWKEYS' unless buffer.type == NEWKEYS
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,72 @@
1
+ require 'net/ssh/transport/kex/abstract'
2
+
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
7
+ # Implement key-exchange algorithm from Elliptic Curve Algorithm Integration
8
+ # in the Secure Shell Transport Layer (RFC 5656)
9
+ class Abstract5656 < Abstract
10
+ alias ecdh dh
11
+
12
+ def curve_name
13
+ raise NotImplementedError, 'abstract class: curve_name not implemented'
14
+ end
15
+
16
+ private
17
+
18
+ def get_message_types
19
+ [KEXECDH_INIT, KEXECDH_REPLY]
20
+ end
21
+
22
+ def build_signature_buffer(result)
23
+ response = Net::SSH::Buffer.new
24
+ response.write_string data[:client_version_string],
25
+ data[:server_version_string],
26
+ data[:client_algorithm_packet],
27
+ data[:server_algorithm_packet],
28
+ result[:key_blob],
29
+ ecdh_public_key_bytes,
30
+ result[:server_ecdh_pubkey]
31
+ response.write_bignum result[:shared_secret]
32
+ response
33
+ end
34
+
35
+ def send_kexinit # :nodoc:
36
+ init, reply = get_message_types
37
+
38
+ # send the KEXECDH_INIT message
39
+ ## byte SSH_MSG_KEX_ECDH_INIT
40
+ ## string Q_C, client's ephemeral public key octet string
41
+ buffer = Net::SSH::Buffer.from(:byte, init, :mstring, ecdh_public_key_bytes)
42
+ connection.send_message(buffer)
43
+
44
+ # expect the following KEXECDH_REPLY message
45
+ ## byte SSH_MSG_KEX_ECDH_REPLY
46
+ ## string K_S, server's public host key
47
+ ## string Q_S, server's ephemeral public key octet string
48
+ ## string the signature on the exchange hash
49
+ buffer = connection.next_message
50
+ raise Net::SSH::Exception, 'expected REPLY' unless buffer.type == reply
51
+
52
+ result = {}
53
+ result[:key_blob] = buffer.read_string
54
+ result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
55
+ result[:server_ecdh_pubkey] = buffer.read_string
56
+ result[:shared_secret] = compute_shared_secret(result[:server_ecdh_pubkey])
57
+
58
+ sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
59
+ sig_type = sig_buffer.read_string
60
+ if sig_type != algorithms.host_key_format
61
+ raise Net::SSH::Exception, "host key algorithm mismatch for signature '#{sig_type}' != '#{algorithms.host_key_format}'"
62
+ end
63
+
64
+ result[:server_sig] = sig_buffer.read_string
65
+
66
+ result
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ gem 'x25519' # raise if the gem x25519 is not installed
2
+
3
+ require 'x25519'
4
+
5
+ require 'net/ssh/transport/constants'
6
+ require 'net/ssh/transport/kex/abstract5656'
7
+
8
+ module Net
9
+ module SSH
10
+ module Transport
11
+ module Kex
12
+ # A key-exchange service implementing the "curve25519-sha256@libssh.org"
13
+ # key-exchange algorithm. (defined in https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-06)
14
+ class Curve25519Sha256 < Abstract5656
15
+ def digester
16
+ OpenSSL::Digest::SHA256
17
+ end
18
+
19
+ private
20
+
21
+ def generate_key # :nodoc:
22
+ ::X25519::Scalar.generate
23
+ end
24
+
25
+ ## string Q_C, client's ephemeral public key octet string
26
+ def ecdh_public_key_bytes
27
+ ecdh.public_key.to_bytes
28
+ end
29
+
30
+ # compute shared secret from server's public key and client's private key
31
+ def compute_shared_secret(server_ecdh_pubkey)
32
+ pk = ::X25519::MontgomeryU.new(server_ecdh_pubkey)
33
+ OpenSSL::BN.new(ecdh.diffie_hellman(pk).to_bytes, 2)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+ module Kex
5
+ # Loads Curve25519Sha256 support which requires optinal dependencies
6
+ module Curve25519Sha256Loader
7
+ begin
8
+ require 'net/ssh/transport/kex/curve25519_sha256'
9
+ LOADED = true
10
+ ERROR = nil
11
+ rescue LoadError => e
12
+ ERROR = e
13
+ LOADED = false
14
+ end
15
+
16
+ def self.raiseUnlessLoaded(message)
17
+ description = ERROR.is_a?(LoadError) ? dependenciesRequiredForX25519 : ''
18
+ description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
19
+ raise NotImplementedError, "#{message}\n#{description}" unless LOADED
20
+ end
21
+
22
+ def self.dependenciesRequiredForX25519
23
+ result = "net-ssh requires the following gems for x25519 support:\n"
24
+ result << " * x25519\n"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,44 +1,37 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
 
3
- module Net; module SSH; module Transport; module Kex
4
-
5
- # A key-exchange service implementing the "diffie-hellman-group14-sha1"
6
- # key-exchange algorithm. (defined in RFC 4253)
7
- class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
8
- include Constants, Loggable
9
-
10
- # The value of 'P', as a string, in hexadecimal
11
- P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
12
- "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
13
- "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
14
- "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
15
- "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
16
- "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
17
- "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
18
- "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
19
- "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
20
- "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
21
- "9ED52907" "7096966D" "670C354E" "4ABC9804" +
22
- "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
23
- "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
24
- "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
25
- "3995497C" "EA956AE5" "15D22618" "98FA0510" +
26
- "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
27
-
28
- # The radix in which P_s represents the value of P
29
- P_r = 16
30
-
31
- # The group constant
32
- G = 2
33
-
34
- private
35
-
36
- def get_p
37
- OpenSSL::BN.new(P_s, P_r)
38
- end
39
-
40
- def get_g
41
- G
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
7
+ # A key-exchange service implementing the "diffie-hellman-group14-sha1"
8
+ # key-exchange algorithm. (defined in RFC 4253)
9
+ class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
10
+ # The value of 'P', as a string, in hexadecimal
11
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
12
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
13
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
14
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
15
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
16
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
17
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
18
+ "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
19
+ "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
20
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
21
+ "9ED52907" "7096966D" "670C354E" "4ABC9804" +
22
+ "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
23
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
24
+ "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
25
+ "3995497C" "EA956AE5" "15D22618" "98FA0510" +
26
+ "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
27
+
28
+ # The radix in which P_s represents the value of P
29
+ P_r = 16
30
+
31
+ # The group constant
32
+ G = 2
33
+ end
34
+ end
42
35
  end
43
36
  end
44
- end; end; end; end
37
+ end
@@ -0,0 +1,11 @@
1
+ require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
2
+
3
+ module Net::SSH::Transport::Kex
4
+ # A key-exchange service implementing the "diffie-hellman-group14-sha256"
5
+ # key-exchange algorithm.
6
+ class DiffieHellmanGroup14SHA256 < DiffieHellmanGroup14SHA1
7
+ def digester
8
+ OpenSSL::Digest::SHA256
9
+ end
10
+ end
11
+ end