sslshake 1.3.0 → 1.3.1
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/lib/sslshake.rb +0 -1
- data/lib/sslshake/ciphers.rb +6 -0
- data/lib/sslshake/tls.rb +99 -3
- data/lib/sslshake/version.rb +1 -1
- metadata +6 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 641256e779df0499064eb598aebf58897dc4b9be47c61ec5dc15990a801f3358
|
|
4
|
+
data.tar.gz: 1f92a00e7c0711d9d7329439f3c59081727631c95e5a5166df044990cdb08046
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fdca401dc68dd60345f32bcb091bf3df052552cc217d13d537acb3af41d53317146ea30385dc3d93a32dfb6216abdb638f32da5534604d511db0a30acc0da981
|
|
7
|
+
data.tar.gz: 1894127ce300872c215cf2b7c659c1033273fcebef6556fccba8f0496c506ebad06828d71d4d35f519e41ced377b52d2c2df36ec2b90d5a10ca9a83ea4e71dfa
|
data/lib/sslshake.rb
CHANGED
data/lib/sslshake/ciphers.rb
CHANGED
|
@@ -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',
|
data/lib/sslshake/tls.rb
CHANGED
|
@@ -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
|
-
|
|
162
|
+
.unpack('H*')[0].upcase.scan(/../)
|
|
89
163
|
type = raw.shift
|
|
90
164
|
if type == CONTENT_TYPES['Alert']
|
|
91
|
-
|
|
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.' }
|
data/lib/sslshake/version.rb
CHANGED
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.
|
|
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:
|
|
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
|
-
|
|
56
|
-
|
|
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: []
|