hrr_rb_ssh 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/demo/server.rb +5 -97
  3. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/public_key_blob.rb +30 -0
  4. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature.rb +27 -0
  5. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature_blob.rb +33 -0
  6. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb +8 -31
  7. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/public_key_blob.rb +28 -0
  8. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature.rb +27 -0
  9. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature_blob.rb +33 -0
  10. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb +8 -29
  11. data/lib/hrr_rb_ssh/codable.rb +64 -0
  12. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +50 -0
  13. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +33 -0
  14. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type.rb +1 -0
  15. data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +21 -0
  16. data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +28 -0
  17. data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +32 -0
  18. data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +81 -0
  19. data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +21 -0
  20. data/lib/hrr_rb_ssh/connection/request_handler.rb +6 -0
  21. data/lib/hrr_rb_ssh/message/001_ssh_msg_disconnect.rb +1 -1
  22. data/lib/hrr_rb_ssh/message/002_ssh_msg_ignore.rb +1 -1
  23. data/lib/hrr_rb_ssh/message/003_ssh_msg_unimplemented.rb +1 -1
  24. data/lib/hrr_rb_ssh/message/004_ssh_msg_debug.rb +1 -1
  25. data/lib/hrr_rb_ssh/message/005_ssh_msg_service_request.rb +1 -1
  26. data/lib/hrr_rb_ssh/message/006_ssh_msg_service_accept.rb +1 -1
  27. data/lib/hrr_rb_ssh/message/020_ssh_msg_kexinit.rb +1 -1
  28. data/lib/hrr_rb_ssh/message/021_ssh_msg_newkeys.rb +1 -1
  29. data/lib/hrr_rb_ssh/message/030_ssh_msg_kex_dh_gex_request_old.rb +24 -0
  30. data/lib/hrr_rb_ssh/message/030_ssh_msg_kexdh_init.rb +1 -1
  31. data/lib/hrr_rb_ssh/message/031_ssh_msg_kex_dh_gex_group.rb +25 -0
  32. data/lib/hrr_rb_ssh/message/031_ssh_msg_kexdh_reply.rb +1 -1
  33. data/lib/hrr_rb_ssh/message/032_ssh_msg_kex_dh_gex_init.rb +24 -0
  34. data/lib/hrr_rb_ssh/message/033_ssh_msg_kex_dh_gex_reply.rb +26 -0
  35. data/lib/hrr_rb_ssh/message/034_ssh_msg_kex_dh_gex_request.rb +26 -0
  36. data/lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb +1 -1
  37. data/lib/hrr_rb_ssh/message/051_ssh_msg_userauth_failure.rb +1 -1
  38. data/lib/hrr_rb_ssh/message/052_ssh_msg_userauth_success.rb +1 -1
  39. data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok.rb +1 -1
  40. data/lib/hrr_rb_ssh/message/080_ssh_msg_global_request.rb +1 -1
  41. data/lib/hrr_rb_ssh/message/081_ssh_msg_request_success.rb +1 -1
  42. data/lib/hrr_rb_ssh/message/082_ssh_msg_request_failure.rb +1 -1
  43. data/lib/hrr_rb_ssh/message/090_ssh_msg_channel_open.rb +1 -1
  44. data/lib/hrr_rb_ssh/message/091_ssh_msg_channel_open_confirmation.rb +1 -1
  45. data/lib/hrr_rb_ssh/message/092_ssh_msg_channel_open_failure.rb +1 -1
  46. data/lib/hrr_rb_ssh/message/093_ssh_msg_channel_window_adjust.rb +1 -1
  47. data/lib/hrr_rb_ssh/message/094_ssh_msg_channel_data.rb +1 -1
  48. data/lib/hrr_rb_ssh/message/095_ssh_msg_channel_extended_data.rb +1 -1
  49. data/lib/hrr_rb_ssh/message/096_ssh_msg_channel_eof.rb +1 -1
  50. data/lib/hrr_rb_ssh/message/097_ssh_msg_channel_close.rb +1 -1
  51. data/lib/hrr_rb_ssh/message/098_ssh_msg_channel_request.rb +1 -1
  52. data/lib/hrr_rb_ssh/message/099_ssh_msg_channel_success.rb +1 -1
  53. data/lib/hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb +1 -1
  54. data/lib/hrr_rb_ssh/message.rb +5 -0
  55. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman/h0.rb +29 -0
  56. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +28 -18
  57. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group14_sha256.rb +35 -0
  58. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group15_sha512.rb +35 -0
  59. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group16_sha512.rb +41 -0
  60. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group17_sha512.rb +47 -0
  61. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group18_sha512.rb +62 -0
  62. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange/h0.rb +34 -0
  63. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +170 -0
  64. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange_sha1.rb +17 -0
  65. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange_sha256.rb +17 -0
  66. data/lib/hrr_rb_ssh/transport/kex_algorithm.rb +7 -0
  67. data/lib/hrr_rb_ssh/transport/receiver.rb +16 -14
  68. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss/public_key_blob.rb +26 -0
  69. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss/signature.rb +23 -0
  70. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +11 -39
  71. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa/public_key_blob.rb +25 -0
  72. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa/signature.rb +23 -0
  73. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +11 -38
  74. data/lib/hrr_rb_ssh/transport.rb +9 -29
  75. data/lib/hrr_rb_ssh/version.rb +1 -1
  76. metadata +35 -4
  77. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/codable.rb +0 -33
  78. data/lib/hrr_rb_ssh/message/codable.rb +0 -66
@@ -9,17 +9,6 @@ module HrrRbSsh
9
9
  class Transport
10
10
  class KexAlgorithm
11
11
  module DiffieHellman
12
- H0_DEFINITION = [
13
- [DataType::String, 'V_C'],
14
- [DataType::String, 'V_S'],
15
- [DataType::String, 'I_C'],
16
- [DataType::String, 'I_S'],
17
- [DataType::String, 'K_S'],
18
- [DataType::Mpint, 'e'],
19
- [DataType::Mpint, 'f'],
20
- [DataType::Mpint, 'k'],
21
- ]
22
-
23
12
  def initialize
24
13
  @logger = HrrRbSsh::Logger.new(self.class.name)
25
14
  @dh = OpenSSL::PKey::DH.new
@@ -32,11 +21,14 @@ module HrrRbSsh
32
21
  @dh.generate_key!
33
22
  end
34
23
 
35
- def encode definition, payload
36
- definition.map{ |data_type, field_name|
37
- field_value = if payload[field_name].instance_of? ::Proc then payload[field_name].call else payload[field_name] end
38
- data_type.encode(field_value)
39
- }.join
24
+ def start transport, mode
25
+ case mode
26
+ when HrrRbSsh::Transport::Mode::SERVER
27
+ receive_kexdh_init transport.receive
28
+ send_kexdh_reply transport
29
+ else
30
+ raise "unsupported mode"
31
+ end
40
32
  end
41
33
 
42
34
  def set_e e
@@ -66,7 +58,7 @@ module HrrRbSsh
66
58
  'f' => f,
67
59
  'k' => k,
68
60
  }
69
- h0 = encode H0_DEFINITION, h0_payload
61
+ h0 = H0.encode h0_payload
70
62
 
71
63
  h = OpenSSL::Digest.digest self.class::DIGEST, h0
72
64
 
@@ -75,7 +67,7 @@ module HrrRbSsh
75
67
 
76
68
  def sign transport
77
69
  h = hash transport
78
- s = transport.server_host_key_algorithm.sign self.class::DIGEST, h
70
+ s = transport.server_host_key_algorithm.sign h
79
71
 
80
72
  s
81
73
  end
@@ -122,7 +114,25 @@ module HrrRbSsh
122
114
  key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_s_to_c_name]::KEY_LENGTH
123
115
  build_key(shared_secret, hash(transport), 'F'.ord, transport.session_id, key_length)
124
116
  end
117
+
118
+ def receive_kexdh_init payload
119
+ message = HrrRbSsh::Message::SSH_MSG_KEXDH_INIT.decode payload
120
+ set_e message['e']
121
+ end
122
+
123
+ def send_kexdh_reply transport
124
+ message = {
125
+ 'message number' => HrrRbSsh::Message::SSH_MSG_KEXDH_REPLY::VALUE,
126
+ 'server public host key and certificates (K_S)' => transport.server_host_key_algorithm.server_public_host_key,
127
+ 'f' => pub_key,
128
+ 'signature of H' => sign(transport),
129
+ }
130
+ payload = HrrRbSsh::Message::SSH_MSG_KEXDH_REPLY.encode message
131
+ transport.send payload
132
+ end
125
133
  end
126
134
  end
127
135
  end
128
136
  end
137
+
138
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman/h0'
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroup14Sha256 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group14-sha256'
11
+ PREFERENCE = 50
12
+ DIGEST = 'sha256'
13
+ P = \
14
+ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" \
15
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" \
16
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" \
17
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" \
18
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" \
19
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" \
20
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" \
21
+ "49286651" "ECE45B3D" "C2007CB8" "A163BF05" \
22
+ "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" \
23
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" \
24
+ "9ED52907" "7096966D" "670C354E" "4ABC9804" \
25
+ "F1746C08" "CA18217C" "32905E46" "2E36CE3B" \
26
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" \
27
+ "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" \
28
+ "3995497C" "EA956AE5" "15D22618" "98FA0510" \
29
+ "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
30
+ G = 2
31
+ include DiffieHellman
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroup15Sha512 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group15-sha512'
11
+ PREFERENCE = 60
12
+ DIGEST = 'sha512'
13
+ P = \
14
+ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" \
15
+ "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" \
16
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" \
17
+ "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" \
18
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" \
19
+ "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" \
20
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" \
21
+ "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" \
22
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" \
23
+ "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" \
24
+ "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" \
25
+ "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" \
26
+ "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" \
27
+ "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" \
28
+ "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" \
29
+ "43DB5BFC" "E0FD108E" "4B82D120" "A93AD2CA" "FFFFFFFF" "FFFFFFFF"
30
+ G = 2
31
+ include DiffieHellman
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroup16Sha512 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group16-sha512'
11
+ PREFERENCE = 70
12
+ DIGEST = 'sha512'
13
+ P = \
14
+ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" \
15
+ "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" \
16
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" \
17
+ "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" \
18
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" \
19
+ "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" \
20
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" \
21
+ "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" \
22
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" \
23
+ "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" \
24
+ "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" \
25
+ "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" \
26
+ "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" \
27
+ "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" \
28
+ "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" \
29
+ "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" \
30
+ "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" \
31
+ "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" \
32
+ "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" \
33
+ "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" \
34
+ "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" \
35
+ "FFFFFFFF" "FFFFFFFF"
36
+ G = 2
37
+ include DiffieHellman
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroup17Sha512 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group17-sha512'
11
+ PREFERENCE = 80
12
+ DIGEST = 'sha512'
13
+ P = \
14
+ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1 29024E08" \
15
+ "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" "EF9519B3 CD3A431B" \
16
+ "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" "E485B576" "625E7EC6 F44C42E9" \
17
+ "A637ED6B" "0BFF5CB6" "F406B7ED" "EE386BFB" "5A899FA5" "AE9F2411 7C4B1FE6" \
18
+ "49286651" "ECE45B3D" "C2007CB8" "A163BF05" "98DA4836" "1C55D39A 69163FA8" \
19
+ "FD24CF5F" "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907 7096966D" \
20
+ "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B E39E772C" \
21
+ "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" "DE2BCBF6 95581718" \
22
+ "3995497C" "EA956AE5" "15D22618" "98FA0510" "15728E5A" "8AAAC42D AD33170D" \
23
+ "04507A33" "A85521AB" "DF1CBA64" "ECFB8504" "58DBEF0A" "8AEA7157 5D060C7D" \
24
+ "B3970F85" "A6E1E4C7" "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D CEE3D226" \
25
+ "1AD2EE6B" "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18 177B200C" \
26
+ "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31 43DB5BFC" \
27
+ "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" "88719A10 BDBA5B26" \
28
+ "99C32718" "6AF4E23C" "1A946834" "B6150BDA" "2583E9CA" "2AD44CE8 DBBBC2DB" \
29
+ "04DE8EF9" "2E8EFC14" "1FBECAA6" "287C5947" "4E6BC05D" "99B2964F A090C3A2" \
30
+ "233BA186" "515BE7ED" "1F612970" "CEE2D7AF" "B81BDD76" "2170481C D0069127" \
31
+ "D5B05AA9" "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9 34028492" \
32
+ "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD F8FF9406" \
33
+ "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" "179727B0 865A8918" \
34
+ "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" "DB7F1447" "E6CC254B 33205151" \
35
+ "2BD7AF42" "6FB8F401" "378CD2BF" "5983CA01" "C64B92EC" "F032EA15 D1721D03" \
36
+ "F482D7CE" "6E74FEF6" "D55E702F" "46980C82" "B5A84031" "900B1C9E 59E7C97F" \
37
+ "BEC7E8F3" "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2 2B4154AA" \
38
+ "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328 06A1D58B" \
39
+ "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" "DA56C9EC 2EF29632" \
40
+ "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" "12BF2D5B" "0B7474D6 E694F91E" \
41
+ "6DCC4024" "FFFFFFFF" "FFFFFFFF"
42
+ G = 2
43
+ include DiffieHellman
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,62 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroup18Sha512 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group18-sha512'
11
+ PREFERENCE = 90
12
+ DIGEST = 'sha512'
13
+ P = \
14
+ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" \
15
+ "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" \
16
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" \
17
+ "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" \
18
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" \
19
+ "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" \
20
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" \
21
+ "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" \
22
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" \
23
+ "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" \
24
+ "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" \
25
+ "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" \
26
+ "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" \
27
+ "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" \
28
+ "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" \
29
+ "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" \
30
+ "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" \
31
+ "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" \
32
+ "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" \
33
+ "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" \
34
+ "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492" \
35
+ "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" \
36
+ "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" \
37
+ "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" \
38
+ "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF" \
39
+ "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6" \
40
+ "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3" \
41
+ "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA" \
42
+ "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" \
43
+ "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" \
44
+ "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" \
45
+ "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4" \
46
+ "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300" \
47
+ "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568" \
48
+ "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9" \
49
+ "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B" \
50
+ "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A" \
51
+ "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36" \
52
+ "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1" \
53
+ "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92" \
54
+ "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47" \
55
+ "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71" \
56
+ "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF"
57
+ G = 2
58
+ include DiffieHellman
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/data_type'
5
+ require 'hrr_rb_ssh/codable'
6
+
7
+ module HrrRbSsh
8
+ class Transport
9
+ class KexAlgorithm
10
+ module DiffieHellmanGroupExchange
11
+ module H0
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::String, 'V_C'],
17
+ [DataType::String, 'V_S'],
18
+ [DataType::String, 'I_C'],
19
+ [DataType::String, 'I_S'],
20
+ [DataType::String, 'K_S'],
21
+ [DataType::Uint32, 'min'],
22
+ [DataType::Uint32, 'n'],
23
+ [DataType::Uint32, 'max'],
24
+ [DataType::Mpint, 'p'],
25
+ [DataType::Mpint, 'g'],
26
+ [DataType::Mpint, 'e'],
27
+ [DataType::Mpint, 'f'],
28
+ [DataType::Mpint, 'k'],
29
+ ]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,170 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'openssl'
5
+ require 'hrr_rb_ssh/logger'
6
+ require 'hrr_rb_ssh/data_type'
7
+
8
+ module HrrRbSsh
9
+ class Transport
10
+ class KexAlgorithm
11
+ module DiffieHellmanGroupExchange
12
+ def initialize
13
+ @logger = HrrRbSsh::Logger.new(self.class.name)
14
+ end
15
+
16
+ def start transport, mode
17
+ case mode
18
+ when HrrRbSsh::Transport::Mode::SERVER
19
+ receive_kex_dh_gex_request transport.receive
20
+ set_dh
21
+ send_kex_dh_gex_group transport
22
+ receive_kex_dh_gex_init transport.receive
23
+ send_kex_dh_gex_reply transport
24
+ else
25
+ raise "unsupported mode"
26
+ end
27
+ end
28
+
29
+ def set_dh
30
+ 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
31
+ candidate = p_list.find{ |e| e[0] <= @n }
32
+ raise unless (@min .. @max).include?(candidate[0])
33
+ p = candidate[1]
34
+ g = 2
35
+ @dh = OpenSSL::PKey::DH.new
36
+ if @dh.respond_to?(:set_pqg)
37
+ @dh.set_pqg OpenSSL::BN.new(p, 16), nil, OpenSSL::BN.new(g)
38
+ else
39
+ @dh.p = OpenSSL::BN.new(p, 16)
40
+ @dh.g = OpenSSL::BN.new(g)
41
+ end
42
+ @dh.generate_key!
43
+ end
44
+
45
+ def set_e e
46
+ @e = e
47
+ end
48
+
49
+ def shared_secret
50
+ k = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@e)), 2).to_i
51
+ end
52
+
53
+ def pub_key
54
+ f = @dh.pub_key.to_i
55
+ end
56
+
57
+ def hash transport
58
+ e = @e
59
+ k = shared_secret
60
+ f = pub_key
61
+
62
+ h0_payload = {
63
+ 'V_C' => transport.v_c,
64
+ 'V_S' => transport.v_s,
65
+ 'I_C' => transport.i_c,
66
+ 'I_S' => transport.i_s,
67
+ 'K_S' => transport.server_host_key_algorithm.server_public_host_key,
68
+ 'min' => @min,
69
+ 'n' => @n,
70
+ 'max' => @max,
71
+ 'p' => @dh.p.to_i,
72
+ 'g' => @dh.g.to_i,
73
+ 'e' => e,
74
+ 'f' => f,
75
+ 'k' => k,
76
+ }
77
+ h0 = H0.encode h0_payload
78
+
79
+ h = OpenSSL::Digest.digest self.class::DIGEST, h0
80
+
81
+ h
82
+ end
83
+
84
+ def sign transport
85
+ h = hash transport
86
+ s = transport.server_host_key_algorithm.sign h
87
+ s
88
+ end
89
+
90
+ def build_key(_k, h, _x, session_id, key_length)
91
+ k = DataType::Mpint.encode _k
92
+ x = DataType::Byte.encode _x
93
+
94
+ key = OpenSSL::Digest.digest(self.class::DIGEST, k + h + x + session_id)
95
+
96
+ while key.length < key_length
97
+ key = key + OpenSSL::Digest.digest(self.class::DIGEST, k + h + key )
98
+ end
99
+
100
+ key[0, key_length]
101
+ end
102
+
103
+ def iv_c_to_s transport, encryption_algorithm_c_to_s_name
104
+ key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::IV_LENGTH
105
+ build_key(shared_secret, hash(transport), 'A'.ord, transport.session_id, key_length)
106
+ end
107
+
108
+ def iv_s_to_c transport, encryption_algorithm_s_to_c_name
109
+ key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::IV_LENGTH
110
+ build_key(shared_secret, hash(transport), 'B'.ord, transport.session_id, key_length)
111
+ end
112
+
113
+ def key_c_to_s transport, encryption_algorithm_c_to_s_name
114
+ key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::KEY_LENGTH
115
+ build_key(shared_secret, hash(transport), 'C'.ord, transport.session_id, key_length)
116
+ end
117
+
118
+ def key_s_to_c transport, encryption_algorithm_s_to_c_name
119
+ key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::KEY_LENGTH
120
+ build_key(shared_secret, hash(transport), 'D'.ord, transport.session_id, key_length)
121
+ end
122
+
123
+ def mac_c_to_s transport, mac_algorithm_c_to_s_name
124
+ key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_c_to_s_name]::KEY_LENGTH
125
+ build_key(shared_secret, hash(transport), 'E'.ord, transport.session_id, key_length)
126
+ end
127
+
128
+ def mac_s_to_c transport, mac_algorithm_s_to_c_name
129
+ key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_s_to_c_name]::KEY_LENGTH
130
+ build_key(shared_secret, hash(transport), 'F'.ord, transport.session_id, key_length)
131
+ end
132
+
133
+ def receive_kex_dh_gex_request payload
134
+ message = HrrRbSsh::Message::SSH_MSG_KEX_DH_GEX_REQUEST.decode payload
135
+ @min = message['min']
136
+ @n = message['n']
137
+ @max = message['max']
138
+ end
139
+
140
+ def send_kex_dh_gex_group transport
141
+ message = {
142
+ 'message number' => HrrRbSsh::Message::SSH_MSG_KEX_DH_GEX_GROUP::VALUE,
143
+ 'p' => @dh.p.to_i,
144
+ 'g' => @dh.g.to_i,
145
+ }
146
+ payload = HrrRbSsh::Message::SSH_MSG_KEX_DH_GEX_GROUP.encode message
147
+ transport.send payload
148
+ end
149
+
150
+ def receive_kex_dh_gex_init payload
151
+ message = HrrRbSsh::Message::SSH_MSG_KEX_DH_GEX_INIT.decode payload
152
+ set_e message['e']
153
+ end
154
+
155
+ def send_kex_dh_gex_reply transport
156
+ message = {
157
+ 'message number' => HrrRbSsh::Message::SSH_MSG_KEX_DH_GEX_REPLY::VALUE,
158
+ 'server public host key and certificates (K_S)' => transport.server_host_key_algorithm.server_public_host_key,
159
+ 'f' => pub_key,
160
+ 'signature of H' => sign(transport),
161
+ }
162
+ payload = HrrRbSsh::Message::SSH_MSG_KEX_DH_GEX_REPLY.encode message
163
+ transport.send payload
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange/h0'
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroupExchangeSha1 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group-exchange-sha1'
11
+ PREFERENCE = 30
12
+ DIGEST = 'sha1'
13
+ include DiffieHellmanGroupExchange
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange'
5
+
6
+ module HrrRbSsh
7
+ class Transport
8
+ class KexAlgorithm
9
+ class DiffieHellmanGroupExchangeSha256 < KexAlgorithm
10
+ NAME = 'diffie-hellman-group-exchange-sha256'
11
+ PREFERENCE = 40
12
+ DIGEST = 'sha256'
13
+ include DiffieHellmanGroupExchange
14
+ end
15
+ end
16
+ end
17
+ end
@@ -16,3 +16,10 @@ end
16
16
 
17
17
  require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group1_sha1'
18
18
  require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group14_sha1'
19
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange_sha1'
20
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange_sha256'
21
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group14_sha256'
22
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group15_sha512'
23
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group16_sha512'
24
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group17_sha512'
25
+ require 'hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group18_sha512'
@@ -25,28 +25,30 @@ module HrrRbSsh
25
25
  end
26
26
 
27
27
  def receive_packet transport
28
- packet_length_field_length = 4
29
- minimum_block_size = 8
28
+ packet_length_field_length = 4
29
+ minimum_block_size = 8
30
+
31
+ encrypted_packet = Array.new
32
+ unencrypted_packet = Array.new
30
33
 
31
- block_size = [transport.incoming_encryption_algorithm.block_size, minimum_block_size].max
32
- initial_encrypted_packet = transport.io.read block_size
33
- if (initial_encrypted_packet == nil) || (initial_encrypted_packet.length != block_size)
34
+ block_size = [transport.incoming_encryption_algorithm.block_size, minimum_block_size].max
35
+ encrypted_packet.push transport.io.read(block_size)
36
+ if (encrypted_packet.last == nil) || (encrypted_packet.last.length != block_size)
34
37
  @logger.warn("IO is EOF")
35
38
  raise EOFError
36
39
  end
37
- initial_unencrypted_packet = transport.incoming_encryption_algorithm.decrypt initial_encrypted_packet
38
- packet_length = initial_unencrypted_packet[0,4].unpack("N")[0]
39
- last_packet_length = packet_length_field_length + packet_length - block_size
40
- last_encrypted_packet = transport.io.read last_packet_length
41
- if (last_encrypted_packet == nil) || (last_encrypted_packet.length != last_packet_length)
40
+ unencrypted_packet.push transport.incoming_encryption_algorithm.decrypt(encrypted_packet.last)
41
+
42
+ packet_length = unencrypted_packet.last[0,4].unpack("N")[0]
43
+ following_packet_length = packet_length_field_length + packet_length - block_size
44
+ encrypted_packet.push transport.io.read(following_packet_length)
45
+ if (encrypted_packet.last == nil) || (encrypted_packet.last.length != following_packet_length)
42
46
  @logger.warn("IO is EOF")
43
47
  raise EOFError
44
48
  end
45
- last_unencrypted_packet = transport.incoming_encryption_algorithm.decrypt last_encrypted_packet
46
- encrypted_packet = initial_encrypted_packet + last_encrypted_packet
47
- unencrypted_packet = initial_unencrypted_packet + last_unencrypted_packet
49
+ unencrypted_packet.push transport.incoming_encryption_algorithm.decrypt(encrypted_packet.last)
48
50
 
49
- unencrypted_packet
51
+ unencrypted_packet.join
50
52
  end
51
53
 
52
54
  def receive_mac transport
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/data_type'
5
+ require 'hrr_rb_ssh/codable'
6
+
7
+ module HrrRbSsh
8
+ class Transport
9
+ class ServerHostKeyAlgorithm
10
+ class SshDss
11
+ module PublicKeyBlob
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::String, 'ssh-dss'],
17
+ [DataType::Mpint, 'p'],
18
+ [DataType::Mpint, 'q'],
19
+ [DataType::Mpint, 'g'],
20
+ [DataType::Mpint, 'y'],
21
+ ]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/data_type'
5
+ require 'hrr_rb_ssh/codable'
6
+
7
+ module HrrRbSsh
8
+ class Transport
9
+ class ServerHostKeyAlgorithm
10
+ class SshDss
11
+ module Signature
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::String, 'ssh-dss'],
17
+ [DataType::String, 'dss_signature_blob'],
18
+ ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end