hrr_rb_ssh 0.3.0.pre1 → 0.4.2
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.
- checksums.yaml +4 -4
- data/.gitignore +0 -3
- data/.travis.yml +1 -0
- data/README.md +208 -46
- data/demo/client.rb +71 -0
- data/demo/echo_server.rb +8 -3
- data/demo/more_flexible_auth.rb +105 -0
- data/demo/multi_step_auth.rb +99 -0
- data/demo/server.rb +10 -4
- data/demo/subsystem_echo_server.rb +8 -3
- data/hrr_rb_ssh.gemspec +6 -6
- data/lib/hrr_rb_ssh.rb +1 -1
- data/lib/hrr_rb_ssh/algorithm/publickey.rb +0 -1
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +12 -9
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/ecdsa_signature_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/public_key_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/signature.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +10 -7
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss/public_key_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss/signature.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +9 -6
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa/public_key_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa/signature.rb +2 -4
- data/lib/hrr_rb_ssh/authentication.rb +103 -22
- data/lib/hrr_rb_ssh/authentication/constant.rb +14 -0
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive.rb +44 -7
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/context.rb +16 -9
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_request.rb +7 -6
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_response.rb +5 -2
- data/lib/hrr_rb_ssh/authentication/method/none.rb +23 -7
- data/lib/hrr_rb_ssh/authentication/method/none/context.rb +15 -7
- data/lib/hrr_rb_ssh/authentication/method/password.rb +28 -7
- data/lib/hrr_rb_ssh/authentication/method/password/context.rb +16 -7
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +63 -10
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm.rb +0 -1
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +32 -8
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/signature_blob.rb +2 -4
- data/lib/hrr_rb_ssh/authentication/method/publickey/context.rb +11 -2
- data/lib/hrr_rb_ssh/client.rb +234 -0
- data/lib/hrr_rb_ssh/codable.rb +15 -13
- data/lib/hrr_rb_ssh/compat/ruby.rb +0 -1
- data/lib/hrr_rb_ssh/connection.rb +145 -75
- data/lib/hrr_rb_ssh/connection/channel.rb +342 -109
- data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +24 -19
- data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +24 -19
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +19 -12
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +0 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +0 -3
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/global_request_handler.rb +14 -12
- data/lib/hrr_rb_ssh/connection/request_handler.rb +1 -3
- data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +0 -2
- data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +4 -6
- data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +10 -12
- data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +4 -6
- data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +0 -2
- data/lib/hrr_rb_ssh/error/closed_authentication.rb +1 -1
- data/lib/hrr_rb_ssh/error/closed_connection.rb +1 -1
- data/lib/hrr_rb_ssh/error/closed_transport.rb +1 -1
- data/lib/hrr_rb_ssh/loggable.rb +42 -0
- data/lib/hrr_rb_ssh/message/001_ssh_msg_disconnect.rb +2 -4
- data/lib/hrr_rb_ssh/message/002_ssh_msg_ignore.rb +2 -4
- data/lib/hrr_rb_ssh/message/003_ssh_msg_unimplemented.rb +2 -4
- data/lib/hrr_rb_ssh/message/004_ssh_msg_debug.rb +2 -4
- data/lib/hrr_rb_ssh/message/005_ssh_msg_service_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/006_ssh_msg_service_accept.rb +2 -4
- data/lib/hrr_rb_ssh/message/020_ssh_msg_kexinit.rb +2 -4
- data/lib/hrr_rb_ssh/message/021_ssh_msg_newkeys.rb +2 -4
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kex_dh_gex_request_old.rb +2 -4
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexdh_init.rb +2 -4
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexecdh_init.rb +2 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kex_dh_gex_group.rb +2 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexdh_reply.rb +2 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexecdh_reply.rb +2 -4
- data/lib/hrr_rb_ssh/message/032_ssh_msg_kex_dh_gex_init.rb +2 -4
- data/lib/hrr_rb_ssh/message/033_ssh_msg_kex_dh_gex_reply.rb +2 -4
- data/lib/hrr_rb_ssh/message/034_ssh_msg_kex_dh_gex_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/051_ssh_msg_userauth_failure.rb +2 -4
- data/lib/hrr_rb_ssh/message/052_ssh_msg_userauth_success.rb +2 -4
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_info_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok.rb +2 -4
- data/lib/hrr_rb_ssh/message/061_ssh_msg_userauth_info_response.rb +2 -4
- data/lib/hrr_rb_ssh/message/080_ssh_msg_global_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/081_ssh_msg_request_success.rb +2 -4
- data/lib/hrr_rb_ssh/message/082_ssh_msg_request_failure.rb +2 -4
- data/lib/hrr_rb_ssh/message/090_ssh_msg_channel_open.rb +2 -4
- data/lib/hrr_rb_ssh/message/091_ssh_msg_channel_open_confirmation.rb +2 -4
- data/lib/hrr_rb_ssh/message/092_ssh_msg_channel_open_failure.rb +2 -4
- data/lib/hrr_rb_ssh/message/093_ssh_msg_channel_window_adjust.rb +2 -4
- data/lib/hrr_rb_ssh/message/094_ssh_msg_channel_data.rb +2 -4
- data/lib/hrr_rb_ssh/message/095_ssh_msg_channel_extended_data.rb +2 -4
- data/lib/hrr_rb_ssh/message/096_ssh_msg_channel_eof.rb +2 -4
- data/lib/hrr_rb_ssh/message/097_ssh_msg_channel_close.rb +2 -4
- data/lib/hrr_rb_ssh/message/098_ssh_msg_channel_request.rb +3 -5
- data/lib/hrr_rb_ssh/message/099_ssh_msg_channel_success.rb +2 -4
- data/lib/hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb +2 -4
- data/lib/hrr_rb_ssh/server.rb +16 -10
- data/lib/hrr_rb_ssh/transport.rb +113 -77
- data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +43 -37
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman/h0.rb +2 -4
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +87 -52
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange/h0.rb +2 -4
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +43 -37
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman/h0.rb +2 -4
- data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/receiver.rb +8 -7
- data/lib/hrr_rb_ssh/transport/sender.rb +5 -3
- data/lib/hrr_rb_ssh/transport/sequence_number.rb +0 -4
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm.rb +0 -1
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/version.rb +1 -1
- metadata +18 -51
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519.rb +0 -61
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key.rb +0 -29
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key_content.rb +0 -26
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/pkey.rb +0 -158
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/public_key_blob.rb +0 -23
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/signature.rb +0 -23
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_ed25519.rb +0 -21
- data/lib/hrr_rb_ssh/compat/ruby/array.rb +0 -14
- data/lib/hrr_rb_ssh/logger.rb +0 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_ed25519.rb +0 -20
@@ -2,14 +2,16 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'zlib'
|
5
|
-
require 'hrr_rb_ssh/
|
5
|
+
require 'hrr_rb_ssh/loggable'
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
8
|
class Transport
|
9
9
|
class CompressionAlgorithm
|
10
10
|
module Functionable
|
11
|
-
|
12
|
-
|
11
|
+
include Loggable
|
12
|
+
|
13
|
+
def initialize direction, logger: nil
|
14
|
+
self.logger = logger
|
13
15
|
case direction
|
14
16
|
when Direction::OUTGOING
|
15
17
|
@deflator = ::Zlib::Deflate.new
|
@@ -1,14 +1,16 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
-
require 'hrr_rb_ssh/
|
4
|
+
require 'hrr_rb_ssh/loggable'
|
5
5
|
|
6
6
|
module HrrRbSsh
|
7
7
|
class Transport
|
8
8
|
class CompressionAlgorithm
|
9
9
|
module Unfunctionable
|
10
|
-
|
11
|
-
|
10
|
+
include Loggable
|
11
|
+
|
12
|
+
def initialize direction=nil, logger: nil
|
13
|
+
self.logger = logger
|
12
14
|
end
|
13
15
|
|
14
16
|
def deflate data
|
@@ -1,20 +1,22 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
-
require 'hrr_rb_ssh/
|
4
|
+
require 'hrr_rb_ssh/loggable'
|
5
5
|
|
6
6
|
module HrrRbSsh
|
7
7
|
class Transport
|
8
8
|
class EncryptionAlgorithm
|
9
9
|
module Functionable
|
10
|
+
include Loggable
|
11
|
+
|
10
12
|
def self.included klass
|
11
13
|
cipher = OpenSSL::Cipher.new(klass::CIPHER_NAME)
|
12
14
|
klass.const_set(:IV_LENGTH, cipher.iv_len)
|
13
15
|
klass.const_set(:KEY_LENGTH, cipher.key_len)
|
14
16
|
end
|
15
17
|
|
16
|
-
def initialize direction, iv, key
|
17
|
-
|
18
|
+
def initialize direction, iv, key, logger: nil
|
19
|
+
self.logger = logger
|
18
20
|
@cipher = OpenSSL::Cipher.new(self.class::CIPHER_NAME)
|
19
21
|
case direction
|
20
22
|
when Direction::OUTGOING
|
@@ -1,19 +1,21 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
-
require 'hrr_rb_ssh/
|
4
|
+
require 'hrr_rb_ssh/loggable'
|
5
5
|
|
6
6
|
module HrrRbSsh
|
7
7
|
class Transport
|
8
8
|
class EncryptionAlgorithm
|
9
9
|
module Unfunctionable
|
10
|
+
include Loggable
|
11
|
+
|
10
12
|
def self.included klass
|
11
13
|
klass.const_set(:IV_LENGTH, 0)
|
12
14
|
klass.const_set(:KEY_LENGTH, 0)
|
13
15
|
end
|
14
16
|
|
15
|
-
def initialize direction=nil, iv=nil, key=nil
|
16
|
-
|
17
|
+
def initialize direction=nil, iv=nil, key=nil, logger: nil
|
18
|
+
self.logger = logger
|
17
19
|
end
|
18
20
|
|
19
21
|
def block_size
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'openssl'
|
5
|
-
require 'hrr_rb_ssh/
|
5
|
+
require 'hrr_rb_ssh/loggable'
|
6
6
|
require 'hrr_rb_ssh/data_type'
|
7
7
|
require 'hrr_rb_ssh/transport/kex_algorithm/iv_computable'
|
8
8
|
|
@@ -10,10 +10,11 @@ module HrrRbSsh
|
|
10
10
|
class Transport
|
11
11
|
class KexAlgorithm
|
12
12
|
module DiffieHellman
|
13
|
+
include Loggable
|
13
14
|
include IvComputable
|
14
15
|
|
15
|
-
def initialize
|
16
|
-
|
16
|
+
def initialize logger: nil
|
17
|
+
self.logger = logger
|
17
18
|
@dh = OpenSSL::PKey::DH.new
|
18
19
|
if @dh.respond_to?(:set_pqg)
|
19
20
|
@dh.set_pqg OpenSSL::BN.new(self.class::P, 16), nil, OpenSSL::BN.new(self.class::G)
|
@@ -22,74 +23,79 @@ module HrrRbSsh
|
|
22
23
|
@dh.g = OpenSSL::BN.new(self.class::G)
|
23
24
|
end
|
24
25
|
@dh.generate_key!
|
26
|
+
@public_key = @dh.pub_key.to_i
|
25
27
|
end
|
26
28
|
|
27
|
-
def start transport
|
28
|
-
case mode
|
29
|
+
def start transport
|
30
|
+
case transport.mode
|
29
31
|
when Mode::SERVER
|
30
|
-
|
32
|
+
@k_s = transport.server_host_key_algorithm.server_public_host_key
|
33
|
+
@f = @public_key
|
34
|
+
message = receive_kexdh_init transport.receive
|
35
|
+
@e = message[:'e']
|
36
|
+
@shared_secret = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@e)), 2).to_i
|
31
37
|
send_kexdh_reply transport
|
32
|
-
|
33
|
-
|
38
|
+
when Mode::CLIENT
|
39
|
+
@e = @public_key
|
40
|
+
send_kexdh_init transport
|
41
|
+
message = receive_kexdh_reply transport.receive
|
42
|
+
@k_s = message[:'server public host key and certificates (K_S)']
|
43
|
+
@f = message[:'f']
|
44
|
+
@shared_secret = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@f)), 2).to_i
|
34
45
|
end
|
35
46
|
end
|
36
47
|
|
37
|
-
def set_e e
|
38
|
-
@e = e
|
39
|
-
end
|
40
|
-
|
41
48
|
def shared_secret
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def pub_key
|
46
|
-
f = @dh.pub_key.to_i
|
49
|
+
@shared_secret
|
47
50
|
end
|
48
51
|
|
49
52
|
def hash transport
|
50
|
-
e = @e
|
51
|
-
k = shared_secret
|
52
|
-
f = pub_key
|
53
|
-
|
54
53
|
h0_payload = {
|
55
54
|
:'V_C' => transport.v_c,
|
56
55
|
:'V_S' => transport.v_s,
|
57
56
|
:'I_C' => transport.i_c,
|
58
57
|
:'I_S' => transport.i_s,
|
59
|
-
:'K_S' =>
|
60
|
-
:'e' => e,
|
61
|
-
:'f' => f,
|
62
|
-
:'k' =>
|
58
|
+
:'K_S' => @k_s,
|
59
|
+
:'e' => @e,
|
60
|
+
:'f' => @f,
|
61
|
+
:'k' => @shared_secret,
|
63
62
|
}
|
64
|
-
h0 = H0.encode h0_payload
|
65
|
-
|
66
|
-
h = OpenSSL::Digest.digest self.class::DIGEST, h0
|
67
|
-
|
68
|
-
h
|
63
|
+
h0 = H0.new(logger: logger).encode h0_payload
|
64
|
+
h = OpenSSL::Digest.digest self.class::DIGEST, h0
|
69
65
|
end
|
70
66
|
|
71
67
|
def sign transport
|
72
68
|
h = hash transport
|
73
69
|
s = transport.server_host_key_algorithm.sign h
|
74
|
-
|
75
|
-
s
|
76
70
|
end
|
77
71
|
|
78
72
|
def receive_kexdh_init payload
|
79
|
-
|
80
|
-
set_e message[:'e']
|
73
|
+
Message::SSH_MSG_KEXDH_INIT.new(logger: logger).decode payload
|
81
74
|
end
|
82
75
|
|
83
76
|
def send_kexdh_reply transport
|
84
77
|
message = {
|
85
78
|
:'message number' => Message::SSH_MSG_KEXDH_REPLY::VALUE,
|
86
|
-
:'server public host key and certificates (K_S)' =>
|
87
|
-
:'f' =>
|
79
|
+
:'server public host key and certificates (K_S)' => @k_s,
|
80
|
+
:'f' => @f,
|
88
81
|
:'signature of H' => sign(transport),
|
89
82
|
}
|
90
|
-
payload = Message::SSH_MSG_KEXDH_REPLY.encode message
|
83
|
+
payload = Message::SSH_MSG_KEXDH_REPLY.new(logger: logger).encode message
|
84
|
+
transport.send payload
|
85
|
+
end
|
86
|
+
|
87
|
+
def send_kexdh_init transport
|
88
|
+
message = {
|
89
|
+
:'message number' => Message::SSH_MSG_KEXDH_INIT::VALUE,
|
90
|
+
:'e' => @e,
|
91
|
+
}
|
92
|
+
payload = Message::SSH_MSG_KEXDH_INIT.new(logger: logger).encode message
|
91
93
|
transport.send payload
|
92
94
|
end
|
95
|
+
|
96
|
+
def receive_kexdh_reply payload
|
97
|
+
Message::SSH_MSG_KEXDH_REPLY.new(logger: logger).decode payload
|
98
|
+
end
|
93
99
|
end
|
94
100
|
end
|
95
101
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'openssl'
|
5
|
-
require 'hrr_rb_ssh/
|
5
|
+
require 'hrr_rb_ssh/loggable'
|
6
6
|
require 'hrr_rb_ssh/data_type'
|
7
7
|
require 'hrr_rb_ssh/transport/kex_algorithm/iv_computable'
|
8
8
|
|
@@ -10,31 +10,57 @@ module HrrRbSsh
|
|
10
10
|
class Transport
|
11
11
|
class KexAlgorithm
|
12
12
|
module DiffieHellmanGroupExchange
|
13
|
+
include Loggable
|
13
14
|
include IvComputable
|
14
15
|
|
15
|
-
def initialize
|
16
|
-
|
16
|
+
def initialize logger: nil
|
17
|
+
self.logger = logger
|
17
18
|
end
|
18
19
|
|
19
|
-
def start transport
|
20
|
-
case mode
|
20
|
+
def start transport
|
21
|
+
case transport.mode
|
21
22
|
when Mode::SERVER
|
22
|
-
receive_kex_dh_gex_request transport.receive
|
23
|
-
|
23
|
+
message = receive_kex_dh_gex_request transport.receive
|
24
|
+
@min = message[:'min']
|
25
|
+
@n = message[:'n']
|
26
|
+
@max = message[:'max']
|
27
|
+
initialize_dh
|
28
|
+
@p = @dh.p.to_i
|
29
|
+
@g = @dh.g.to_i
|
24
30
|
send_kex_dh_gex_group transport
|
25
|
-
|
31
|
+
@k_s = transport.server_host_key_algorithm.server_public_host_key
|
32
|
+
@f = @public_key
|
33
|
+
message = receive_kex_dh_gex_init transport.receive
|
34
|
+
@e = message[:'e']
|
35
|
+
@shared_secret = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@e)), 2).to_i
|
26
36
|
send_kex_dh_gex_reply transport
|
27
|
-
|
28
|
-
|
37
|
+
when Mode::CLIENT
|
38
|
+
@min = 1024
|
39
|
+
@n = 2048
|
40
|
+
@max = 8192
|
41
|
+
send_kex_dh_gex_request transport
|
42
|
+
message = receive_kex_dh_gex_group transport.receive
|
43
|
+
@p = message[:'p']
|
44
|
+
@g = message[:'g']
|
45
|
+
initialize_dh [@p, @g]
|
46
|
+
@e = @public_key
|
47
|
+
send_kex_dh_gex_init transport
|
48
|
+
message = receive_kex_dh_gex_reply transport.receive
|
49
|
+
@k_s = message[:'server public host key and certificates (K_S)']
|
50
|
+
@f = message[:'f']
|
51
|
+
@shared_secret = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@f)), 2).to_i
|
29
52
|
end
|
30
53
|
end
|
31
54
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
55
|
+
def initialize_dh pg=nil
|
56
|
+
unless pg
|
57
|
+
p_list = KexAlgorithm.list_supported.map{ |e| KexAlgorithm[e] }.select{ |e| e.const_defined?(:P) }.map{ |e| [OpenSSL::BN.new(e::P,16).num_bits, e::P] }.sort_by{ |e| e[0] }.reverse
|
58
|
+
candidate = p_list.find{ |e| e[0] <= @n }
|
59
|
+
raise unless (@min .. @max).include?(candidate[0])
|
60
|
+
p, g = candidate[1], 2
|
61
|
+
else
|
62
|
+
p, g = pg
|
63
|
+
end
|
38
64
|
@dh = OpenSSL::PKey::DH.new
|
39
65
|
if @dh.respond_to?(:set_pqg)
|
40
66
|
@dh.set_pqg OpenSSL::BN.new(p, 16), nil, OpenSSL::BN.new(g)
|
@@ -43,85 +69,94 @@ module HrrRbSsh
|
|
43
69
|
@dh.g = OpenSSL::BN.new(g)
|
44
70
|
end
|
45
71
|
@dh.generate_key!
|
46
|
-
|
47
|
-
|
48
|
-
def set_e e
|
49
|
-
@e = e
|
72
|
+
@public_key = @dh.pub_key.to_i
|
50
73
|
end
|
51
74
|
|
52
75
|
def shared_secret
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
def pub_key
|
57
|
-
f = @dh.pub_key.to_i
|
76
|
+
@shared_secret
|
58
77
|
end
|
59
78
|
|
60
79
|
def hash transport
|
61
|
-
e = @e
|
62
|
-
k = shared_secret
|
63
|
-
f = pub_key
|
64
|
-
|
65
80
|
h0_payload = {
|
66
81
|
:'V_C' => transport.v_c,
|
67
82
|
:'V_S' => transport.v_s,
|
68
83
|
:'I_C' => transport.i_c,
|
69
84
|
:'I_S' => transport.i_s,
|
70
|
-
:'K_S' =>
|
85
|
+
:'K_S' => @k_s,
|
71
86
|
:'min' => @min,
|
72
87
|
:'n' => @n,
|
73
88
|
:'max' => @max,
|
74
|
-
:'p' => @
|
75
|
-
:'g' => @
|
76
|
-
:'e' => e,
|
77
|
-
:'f' => f,
|
78
|
-
:'k' =>
|
89
|
+
:'p' => @p,
|
90
|
+
:'g' => @g,
|
91
|
+
:'e' => @e,
|
92
|
+
:'f' => @f,
|
93
|
+
:'k' => @shared_secret,
|
79
94
|
}
|
80
|
-
h0 = H0.encode h0_payload
|
81
|
-
|
95
|
+
h0 = H0.new(logger: logger).encode h0_payload
|
82
96
|
h = OpenSSL::Digest.digest self.class::DIGEST, h0
|
83
|
-
|
84
|
-
h
|
85
97
|
end
|
86
98
|
|
87
99
|
def sign transport
|
88
100
|
h = hash transport
|
89
101
|
s = transport.server_host_key_algorithm.sign h
|
90
|
-
s
|
91
102
|
end
|
92
103
|
|
93
104
|
def receive_kex_dh_gex_request payload
|
94
|
-
|
95
|
-
@min = message[:'min']
|
96
|
-
@n = message[:'n']
|
97
|
-
@max = message[:'max']
|
105
|
+
Message::SSH_MSG_KEX_DH_GEX_REQUEST.new(logger: logger).decode payload
|
98
106
|
end
|
99
107
|
|
100
108
|
def send_kex_dh_gex_group transport
|
101
109
|
message = {
|
102
110
|
:'message number' => Message::SSH_MSG_KEX_DH_GEX_GROUP::VALUE,
|
103
|
-
:'p' => @
|
104
|
-
:'g' => @
|
111
|
+
:'p' => @p,
|
112
|
+
:'g' => @g,
|
105
113
|
}
|
106
|
-
payload = Message::SSH_MSG_KEX_DH_GEX_GROUP.encode message
|
114
|
+
payload = Message::SSH_MSG_KEX_DH_GEX_GROUP.new(logger: logger).encode message
|
107
115
|
transport.send payload
|
108
116
|
end
|
109
117
|
|
110
118
|
def receive_kex_dh_gex_init payload
|
111
|
-
|
112
|
-
set_e message[:'e']
|
119
|
+
Message::SSH_MSG_KEX_DH_GEX_INIT.new(logger: logger).decode payload
|
113
120
|
end
|
114
121
|
|
115
122
|
def send_kex_dh_gex_reply transport
|
116
123
|
message = {
|
117
124
|
:'message number' => Message::SSH_MSG_KEX_DH_GEX_REPLY::VALUE,
|
118
|
-
:'server public host key and certificates (K_S)' =>
|
119
|
-
:'f' =>
|
125
|
+
:'server public host key and certificates (K_S)' => @k_s,
|
126
|
+
:'f' => @f,
|
120
127
|
:'signature of H' => sign(transport),
|
121
128
|
}
|
122
|
-
payload = Message::SSH_MSG_KEX_DH_GEX_REPLY.encode message
|
129
|
+
payload = Message::SSH_MSG_KEX_DH_GEX_REPLY.new(logger: logger).encode message
|
130
|
+
transport.send payload
|
131
|
+
end
|
132
|
+
|
133
|
+
def send_kex_dh_gex_request transport
|
134
|
+
message = {
|
135
|
+
:'message number' => Message::SSH_MSG_KEX_DH_GEX_REQUEST::VALUE,
|
136
|
+
:'min' => @min,
|
137
|
+
:'n' => @n,
|
138
|
+
:'max' => @max,
|
139
|
+
}
|
140
|
+
payload = Message::SSH_MSG_KEX_DH_GEX_REQUEST.new(logger: logger).encode message
|
141
|
+
transport.send payload
|
142
|
+
end
|
143
|
+
|
144
|
+
def receive_kex_dh_gex_group payload
|
145
|
+
Message::SSH_MSG_KEX_DH_GEX_GROUP.new(logger: logger).decode payload
|
146
|
+
end
|
147
|
+
|
148
|
+
def send_kex_dh_gex_init transport
|
149
|
+
message = {
|
150
|
+
:'message number' => Message::SSH_MSG_KEX_DH_GEX_INIT::VALUE,
|
151
|
+
:'e' => @e,
|
152
|
+
}
|
153
|
+
payload = Message::SSH_MSG_KEX_DH_GEX_INIT.new(logger: logger).encode message
|
123
154
|
transport.send payload
|
124
155
|
end
|
156
|
+
|
157
|
+
def receive_kex_dh_gex_reply payload
|
158
|
+
Message::SSH_MSG_KEX_DH_GEX_REPLY.new(logger: logger).decode payload
|
159
|
+
end
|
125
160
|
end
|
126
161
|
end
|
127
162
|
end
|