Ver código fonte

Merge pull request #448 from 9seconds/no-default-tls-cipher

Do not use default TLS cipher
tags/v2.2.8^2^2
Sergei Arkhipov 4 semanas atrás
pai
commit
83b43aecc1
Nenhuma conta vinculada ao e-mail do autor do commit

+ 10
- 9
mtglib/internal/tls/fake/client_side.go Ver arquivo

5
 	"crypto/hmac"
5
 	"crypto/hmac"
6
 	"crypto/sha256"
6
 	"crypto/sha256"
7
 	"crypto/subtle"
7
 	"crypto/subtle"
8
-	"crypto/tls"
9
 	"encoding/binary"
8
 	"encoding/binary"
9
+	"errors"
10
 	"fmt"
10
 	"fmt"
11
 	"io"
11
 	"io"
12
 	"net"
12
 	"net"
25
 	// https://medium.com/asecuritysite-when-bob-met-alice/in-cybersecurity-what-is-grease-9f8850558dea
25
 	// https://medium.com/asecuritysite-when-bob-met-alice/in-cybersecurity-what-is-grease-9f8850558dea
26
 	GreaseMask      = 0x0f0f
26
 	GreaseMask      = 0x0f0f
27
 	GreaseValueType = 0x0a0a
27
 	GreaseValueType = 0x0a0a
28
-	DefaultCipher   = tls.TLS_AES_128_GCM_SHA256
29
 
28
 
30
 	sniDNSNamesListType = 0
29
 	sniDNSNamesListType = 0
31
 )
30
 )
33
 var (
32
 var (
34
 	emptyRandom = [RandomLen]byte{}
33
 	emptyRandom = [RandomLen]byte{}
35
 	extTypeSNI  = [2]byte{}
34
 	extTypeSNI  = [2]byte{}
35
+
36
+	ErrCannotFindCipher = errors.New("cannot find a cipher")
36
 )
37
 )
37
 
38
 
38
 type ClientHello struct {
39
 type ClientHello struct {
110
 		return nil, fmt.Errorf("cannot read client version: %w", err)
111
 		return nil, fmt.Errorf("cannot read client version: %w", err)
111
 	}
112
 	}
112
 
113
 
113
-	hello := &ClientHello{
114
-		CipherSuite: DefaultCipher,
115
-	}
114
+	hello := &ClientHello{}
116
 
115
 
117
 	if _, err := io.ReadFull(r, hello.Random[:]); err != nil {
116
 	if _, err := io.ReadFull(r, hello.Random[:]); err != nil {
118
 		return nil, fmt.Errorf("cannot read client random: %w", err)
117
 		return nil, fmt.Errorf("cannot read client random: %w", err)
133
 	}
132
 	}
134
 
133
 
135
 	cipherSuiteLen := int64(binary.BigEndian.Uint16(header[:]))
134
 	cipherSuiteLen := int64(binary.BigEndian.Uint16(header[:]))
136
-	foundCipher := false
137
 
135
 
138
 	// Pick the first non-GREASE cipher suite from the list.
136
 	// Pick the first non-GREASE cipher suite from the list.
139
 	// Real TLS servers never select GREASE values (RFC 8701, pattern 0x?a?a),
137
 	// Real TLS servers never select GREASE values (RFC 8701, pattern 0x?a?a),
144
 			return nil, fmt.Errorf("cannot read cipher suite: %w", err)
142
 			return nil, fmt.Errorf("cannot read cipher suite: %w", err)
145
 		}
143
 		}
146
 
144
 
147
-		if foundCipher {
145
+		if hello.CipherSuite != 0 {
146
+			// do not forget we have to scan until the end
148
 			continue
147
 			continue
149
 		}
148
 		}
150
 
149
 
151
 		if cs := binary.BigEndian.Uint16(header[:]); cs&GreaseMask != GreaseValueType {
150
 		if cs := binary.BigEndian.Uint16(header[:]); cs&GreaseMask != GreaseValueType {
152
 			hello.CipherSuite = cs
151
 			hello.CipherSuite = cs
153
-			// do not forget we have to scan until the end
154
-			foundCipher = true
155
 		}
152
 		}
156
 	}
153
 	}
157
 
154
 
155
+	if hello.CipherSuite == 0 {
156
+		return nil, ErrCannotFindCipher
157
+	}
158
+
158
 	if _, err := io.ReadFull(r, header[:1]); err != nil {
159
 	if _, err := io.ReadFull(r, header[:1]); err != nil {
159
 		return nil, fmt.Errorf("cannot read compression methods length: %w", err)
160
 		return nil, fmt.Errorf("cannot read compression methods length: %w", err)
160
 	}
161
 	}

+ 18
- 0
mtglib/internal/tls/fake/client_side_test.go Ver arquivo

2
 
2
 
3
 import (
3
 import (
4
 	"bytes"
4
 	"bytes"
5
+	cryptotls "crypto/tls"
5
 	"encoding/binary"
6
 	"encoding/binary"
6
 	"encoding/json"
7
 	"encoding/json"
7
 	"io"
8
 	"io"
234
 	suite.ErrorContains(err, "cannot read cipher suite")
235
 	suite.ErrorContains(err, "cannot read cipher suite")
235
 }
236
 }
236
 
237
 
238
+func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotFindCipher() {
239
+	// All cipher suites are GREASE values — must return ErrCannotFindCipher.
240
+	body := make([]byte, 2+fake.RandomLen+1+2+4+1)
241
+	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 4)
242
+	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1+2:], 0x0a0a)
243
+	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1+2+2:], 0x1a1a)
244
+	body[2+fake.RandomLen+1+2+4] = 1
245
+
246
+	suite.writeBody(body)
247
+
248
+	_, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
249
+	suite.ErrorIs(err, fake.ErrCannotFindCipher)
250
+}
251
+
237
 func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadCompressionMethodsLength() {
252
 func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadCompressionMethodsLength() {
238
 	body := make([]byte, 2+fake.RandomLen+1+2+2)
253
 	body := make([]byte, 2+fake.RandomLen+1+2+2)
239
 	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 2)
254
 	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 2)
255
+	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1+2:], cryptotls.TLS_AES_128_GCM_SHA256)
240
 
256
 
241
 	suite.writeBody(body)
257
 	suite.writeBody(body)
242
 
258
 
247
 func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotSkipCompressionMethods() {
263
 func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotSkipCompressionMethods() {
248
 	body := make([]byte, 2+fake.RandomLen+1+2+2+1)
264
 	body := make([]byte, 2+fake.RandomLen+1+2+2+1)
249
 	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 2)
265
 	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 2)
266
+	binary.BigEndian.PutUint16(body[2+fake.RandomLen+1+2:], cryptotls.TLS_AES_128_GCM_SHA256)
250
 	body[2+fake.RandomLen+1+2+2] = 1
267
 	body[2+fake.RandomLen+1+2+2] = 1
251
 
268
 
252
 	suite.writeBody(body)
269
 	suite.writeBody(body)
282
 	// cipherSuite(2) + compressionLen(1) + compression(1) = 41
299
 	// cipherSuite(2) + compressionLen(1) + compression(1) = 41
283
 	body := make([]byte, 41)
300
 	body := make([]byte, 41)
284
 	binary.BigEndian.PutUint16(body[35:], 2)
301
 	binary.BigEndian.PutUint16(body[35:], 2)
302
+	binary.BigEndian.PutUint16(body[37:], cryptotls.TLS_AES_128_GCM_SHA256)
285
 	body[39] = 1
303
 	body[39] = 1
286
 
304
 
287
 	suite.readBuf.Write(body)
305
 	suite.readBuf.Write(body)

Carregando…
Cancelar
Salvar