sslshake 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37184978da20c58b2649eba4057122bc1bb2b77c785c7af547973fb2b27302e0
4
- data.tar.gz: 3ebe8a2ea46eb69d5d6161ea51afc6593d6a82a2a142d626feb96ed573108f3b
3
+ metadata.gz: 641256e779df0499064eb598aebf58897dc4b9be47c61ec5dc15990a801f3358
4
+ data.tar.gz: 1f92a00e7c0711d9d7329439f3c59081727631c95e5a5166df044990cdb08046
5
5
  SHA512:
6
- metadata.gz: 2722410eeddb50ebd48bd8bce5b2b0cef95b4d7021782c554e218c20f885b7eb8cdc9395da741c5967b4d9e022bf8d489f4ec591cef38bb9a8ef323f589117c3
7
- data.tar.gz: bcda1b5c82930b8f126d24577794d4c33d241b2744613e5826aa9e06a7a25998b9f166ed3203150044f81ce78df7199272afe0fb77de55f8edb4c44db1b7c66b
6
+ metadata.gz: fdca401dc68dd60345f32bcb091bf3df052552cc217d13d537acb3af41d53317146ea30385dc3d93a32dfb6216abdb638f32da5534604d511db0a30acc0da981
7
+ data.tar.gz: 1894127ce300872c215cf2b7c659c1033273fcebef6556fccba8f0496c506ebad06828d71d4d35f519e41ced377b52d2c2df36ec2b90d5a10ca9a83ea4e71dfa
@@ -69,7 +69,6 @@ module SSLShake
69
69
  sprintf('%04x', opts[:servername].length) +
70
70
  opts[:servername].unpack('H*')[0]
71
71
  end
72
-
73
72
  cur_socket.send(ssl.hello(protocol, opts[:ciphers], sni), 0)
74
73
  end
75
74
 
@@ -166,6 +166,12 @@ module SSLShake # rubocop:disable Metrics/ModuleLength
166
166
  '00C4' => 'TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256',
167
167
  '00C5' => 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256',
168
168
  '00FF' => 'TLS_EMPTY_RENEGOTIATION_INFO_SCSV',
169
+ # See https://tools.ietf.org/html/rfc8446#appendix-B.4
170
+ "1301" => "TLS_AES_128_GCM_SHA256",
171
+ "1302" => "TLS_AES_256_GCM_SHA384",
172
+ "1303" => "TLS_CHACHA20_POLY1305_SHA256",
173
+ "1304" => "TLS_AES_128_CCM_SHA256",
174
+ "1305" => "TLS_AES_128_CCM_8_SHA256",
169
175
  'C001' => 'TLS_ECDH_ECDSA_WITH_NULL_SHA',
170
176
  'C002' => 'TLS_ECDH_ECDSA_WITH_RC4_128_SHA',
171
177
  'C003' => 'TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA',
@@ -14,6 +14,16 @@ module SSLShake
14
14
  'tls1.0' => '0301',
15
15
  'tls1.1' => '0302',
16
16
  'tls1.2' => '0303',
17
+ # NOTE(ssd) 2020-03-21: RFC 8446 4.1.2:
18
+ #
19
+ # In TLS 1.3, the client indicates its version preferences in the
20
+ # "supported_versions" extension (Section 4.2.1) and the
21
+ # legacy_version field MUST be set to 0x0303, which is the version
22
+ # number for TLS 1.2. TLS 1.3 ClientHellos are identified as having
23
+ # a legacy_version of 0x0303 and a supported_versions extension
24
+ # present with 0x0304 as the highest version indicated therein.
25
+ #
26
+ 'tls1.3' => '0303',
17
27
  }.freeze
18
28
 
19
29
  CONTENT_TYPES = {
@@ -38,10 +48,54 @@ module SSLShake
38
48
  'Finished' => '20',
39
49
  }.freeze
40
50
 
51
+ ALERT_SEVERITY = {
52
+ "WARNING" => "01",
53
+ "FATAL" => "02"
54
+ }.freeze
55
+
56
+ # https://tools.ietf.org/html/rfc5246#appendix-A.3
57
+ # https://tools.ietf.org/html/rfc8446#appendix-B.2
58
+ ALERT_DESCRIPTIONS = {
59
+ "CLOSE_NOTIFY" => "00",
60
+ "UNEXPECTED_MESSAGE" => "0A",
61
+ "BAD_RECORD_MAC" => "14",
62
+ "DECRYPTION_FAILED_RESERVED" => "15",
63
+ "RECORD_OVERFLOW" => "16",
64
+ "DECOMPRESSION_FAILURE" => "1E",
65
+ "HANDSHAKE_FAILURE" => "28",
66
+ "NO_CERTIFICATE_RESERVED" => "29",
67
+ "BAD_CERTIFICATE" => "2A",
68
+ "UNSUPPORTED_CERTIFICATE" => "2B",
69
+ "CERTIFICATE_REVOKED" => "2C",
70
+ "CERTIFICATE_EXPIRED" => "2D",
71
+ "CERTIFICATE_UNKNOWN" => "2D",
72
+ "ILLEGAL_PARAMETER" => "2E",
73
+ "UNKNOWN_CA" => "2F",
74
+ "ACCESS_DENIED" => "30",
75
+ "DECODE_ERROR" => "31",
76
+ "DECRYPT_ERROR" => "32",
77
+ "EXPORT_RESTRICTION_RESERVED" => "3C",
78
+ "PROTOCOL_VERSION" => "46",
79
+ "INSUFFICIENT_SECURITY" => "47",
80
+ "INTERNAL_ERROR" => "50",
81
+ "USER_CANCELED" => "5A",
82
+ "NO_RENEGOTIATION" => "64",
83
+ "MISSING_EXTENSION" => "6D",
84
+ "UNSUPPORTED_EXTENSION" => "6E",
85
+ "CERTIFICATE_UNOBTAINABLE_RESERVED" => "6F",
86
+ "UNRECOGNIZED_NAME" => "70",
87
+ "BAD_CERTIFICATE_STATUS_RESPONSE" => "71",
88
+ "BAD_CERTIFICATE_HASH_VALUE_RESERVED" => "72",
89
+ "UNKNOWN_PSK_IDENTITY" => "73",
90
+ "CERTIFICATE_REQUIRED" => "74",
91
+ "NO_APPLICATION_PROTOCOL" => "78",
92
+ }.freeze
93
+
41
94
  # https://tools.ietf.org/html/rfc6101#appendix-A.6
42
95
  SSL3_CIPHERS = ::SSLShake::CIPHERS.select { |_, v| v.length == 4 }
43
96
  TLS_CIPHERS = ::SSLShake::CIPHERS.select { |k, _| k.start_with? 'TLS_' }
44
97
  TLS10_CIPHERS = TLS_CIPHERS.select { |_, v| v[0] == '0' && v[1] == '0' }
98
+ TLS13_CIPHERS = TLS_CIPHERS.select { |_, v| v[0] == '1' && v[1] == '3' }
45
99
 
46
100
  # Additional collection of ciphers used by different apps and versions
47
101
  OPENSSL_1_0_2_TLS10_CIPHERS = 'c014c00ac022c021c02000390038003700360088008700860085c00fc00500350084c013c009c01fc01ec01d00330032008000810082008300310030009a0099009800970045004400430042c00ec004002f009600410007c011c0070066c00cc00200050004c012c008c01cc01bc01a001600130010000dc00dc003000a006300150012000f000c006200090065006400140011000e000b00080006000300ff'.freeze
@@ -77,6 +131,26 @@ module SSLShake
77
131
  extensions << '000d00140012040308040401050308050501080606010201' # add signature_algorithms
78
132
  extensions << '000b00020100' # add ec_points_format
79
133
  extensions << '000a000a0008fafa001d00170018' # add elliptic_curve
134
+ when 'tls1.3'
135
+ ciphers = cipher_string(TLS13_CIPHERS, cipher_search)
136
+ (extensions ||= '') << '002b0003020304' # TLSv1.3 Supported Versions extension
137
+ extensions << '000d00140012040308040401050308050501080606010201' # add signature_algorithms
138
+ extensions << '000a00080006001d00170018' # Supported Groups extension
139
+ # This is a pre-generated public/private key pair using the x25519 curve:
140
+ # It was generated from the command line with:
141
+ #
142
+ # > openssl-1.1.1e/apps/openssl genpkey -algorithm x25519 > pkey
143
+ # > openssl-1.1.1e/apps/openssl pkey -noout -text < pkey
144
+ # priv:
145
+ # 30:90:f3:89:f4:9e:52:59:3c:ba:e9:f4:78:84:a0:
146
+ # 23:86:73:5e:f5:c9:46:6c:3a:c3:4e:ec:56:57:81:
147
+ # 5d:62
148
+ # pub:
149
+ # e7:08:71:36:d0:81:e0:16:19:3a:cb:67:ca:b8:28:
150
+ # d9:45:92:16:ff:36:63:0d:0d:5a:3d:9d:47:ce:3e:
151
+ # cd:7e
152
+ public_key= 'e7087136d081e016193acb67cab828d9459216ff36630d0d5a3d9d47ce3ecd7e'
153
+ extensions << '003300260024001d0020' + public_key
80
154
  else
81
155
  fail UserError, "This version is not supported: #{version.inspect}"
82
156
  end
@@ -85,10 +159,17 @@ module SSLShake
85
159
 
86
160
  def parse_hello(socket, opts) # rubocop:disable Meterics/AbcSize
87
161
  raw = socket_read(socket, 5, opts[:timeout], opts[:retries])
88
- .unpack('H*')[0].upcase.scan(/../)
162
+ .unpack('H*')[0].upcase.scan(/../)
89
163
  type = raw.shift
90
164
  if type == CONTENT_TYPES['Alert']
91
- return { 'error' => 'SSL Alert.' }
165
+ raw.shift(2) # Shift off version
166
+ len = raw.shift(2).join.to_i(16)
167
+ raw_alert = socket_read(socket, len, opts[:timeout], opts[:retries])
168
+ .unpack('H*')[0].upcase.scan(/../)
169
+ severity = ALERT_SEVERITY.key(raw_alert.shift)
170
+ desc_raw = raw_alert.shift
171
+ description = ALERT_DESCRIPTIONS.key(desc_raw)
172
+ return { 'error' => "SSL Alert: #{severity} #{description || desc_raw}" }
92
173
  end
93
174
  unless type == CONTENT_TYPES['Handshake']
94
175
  return { 'error' => 'Failed to parse response. It is not an SSL handshake.' }
@@ -119,9 +200,24 @@ module SSLShake
119
200
  end
120
201
  res['cipher_suite'] = ciphers.key(raw.shift(2).join(''))
121
202
  res['compression_method'] = raw.shift
203
+
204
+ #
205
+ # TLS 1.3 pretends to be TLS 1.2 in the preceeding headers for
206
+ # compatibility. To correctly identify it, we have to look at
207
+ # any Supported Versions extensions that the server sent us.
208
+ #
209
+ all_ext_len = raw.shift(2).join.to_i(16)
210
+ all_ext_data = raw.shift(all_ext_len)
211
+ while all_ext_data.length > 0
212
+ ext_type = all_ext_data.shift(2).join
213
+ ext_len = all_ext_data.shift(2).join.to_i(16)
214
+ ext_data = all_ext_data.shift(ext_len)
215
+ if ext_type == '002B' && ext_data.join == '0304' # Supported Versions
216
+ res['version'] = 'tls1.3'
217
+ end
218
+ end
122
219
  res['success'] = true
123
220
  res['success'] = (res['version'] == opts[:protocol]) unless opts[:protocol].nil?
124
-
125
221
  res
126
222
  rescue SystemCallError, Alert => _
127
223
  return { 'error' => 'Failed to parse response. The connection was terminated.' }
@@ -3,5 +3,5 @@
3
3
  # license: MPLv2
4
4
 
5
5
  module SSLShake
6
- VERSION = '1.3.0'.freeze
6
+ VERSION = '1.3.1'.freeze
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sslshake
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-21 00:00:00.000000000 Z
11
+ date: 2020-06-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This is a library to simulate SSL and TLS handshake from SSLv2, SSLv3,
14
14
  to TLS 1.0-1.2. It does not rely on OpenSSL and is not designed as a replacement
@@ -37,7 +37,7 @@ homepage: https://github.com/arlimus/sslshake
37
37
  licenses:
38
38
  - MPL-2.0
39
39
  metadata: {}
40
- post_install_message:
40
+ post_install_message:
41
41
  rdoc_options: []
42
42
  require_paths:
43
43
  - lib
@@ -52,9 +52,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  requirements: []
55
- rubyforge_project:
56
- rubygems_version: 2.7.7
57
- signing_key:
55
+ rubygems_version: 3.1.3
56
+ signing_key:
58
57
  specification_version: 4
59
58
  summary: Ruby library for pure SSL/TLS handshake testing.
60
59
  test_files: []