Просмотр исходного кода

Small refactoring

tags/v2.2.8^2^2
9seconds 1 месяц назад
Родитель
Сommit
39ab5570a8
1 измененных файлов: 20 добавлений и 9 удалений
  1. 20
    9
      mtglib/internal/tls/fake/client_side.go

+ 20
- 9
mtglib/internal/tls/fake/client_side.go Просмотреть файл

5
 	"crypto/hmac"
5
 	"crypto/hmac"
6
 	"crypto/sha256"
6
 	"crypto/sha256"
7
 	"crypto/subtle"
7
 	"crypto/subtle"
8
+	"crypto/tls"
8
 	"encoding/binary"
9
 	"encoding/binary"
9
 	"fmt"
10
 	"fmt"
10
 	"io"
11
 	"io"
20
 	// record_type(1) + version(2) + size(2) + handshake_type(1) + uint24_length(3) + client_version(2)
21
 	// record_type(1) + version(2) + size(2) + handshake_type(1) + uint24_length(3) + client_version(2)
21
 	RandomOffset = 1 + 2 + 2 + 1 + 3 + 2
22
 	RandomOffset = 1 + 2 + 2 + 1 + 3 + 2
22
 
23
 
24
+	// https://datatracker.ietf.org/doc/html/rfc8701#name-grease-values
25
+	// https://medium.com/asecuritysite-when-bob-met-alice/in-cybersecurity-what-is-grease-9f8850558dea
26
+	GreaseMask      = 0x0f0f
27
+	GreaseValueType = 0x0a0a
28
+	DefaultCipher   = tls.TLS_AES_128_GCM_SHA256
29
+
23
 	sniDNSNamesListType = 0
30
 	sniDNSNamesListType = 0
24
 )
31
 )
25
 
32
 
108
 		return nil, fmt.Errorf("cannot read client version: %w", err)
115
 		return nil, fmt.Errorf("cannot read client version: %w", err)
109
 	}
116
 	}
110
 
117
 
111
-	hello := &ClientHello{}
118
+	hello := &ClientHello{
119
+		CipherSuite: DefaultCipher,
120
+	}
112
 
121
 
113
 	if _, err := io.ReadFull(r, hello.Random[:]); err != nil {
122
 	if _, err := io.ReadFull(r, hello.Random[:]); err != nil {
114
 		return nil, fmt.Errorf("cannot read client random: %w", err)
123
 		return nil, fmt.Errorf("cannot read client random: %w", err)
129
 	}
138
 	}
130
 
139
 
131
 	cipherSuiteLen := int64(binary.BigEndian.Uint16(header[:]))
140
 	cipherSuiteLen := int64(binary.BigEndian.Uint16(header[:]))
141
+	foundCipher := false
132
 
142
 
133
 	// Pick the first non-GREASE cipher suite from the list.
143
 	// Pick the first non-GREASE cipher suite from the list.
134
 	// Real TLS servers never select GREASE values (RFC 8701, pattern 0x?a?a),
144
 	// Real TLS servers never select GREASE values (RFC 8701, pattern 0x?a?a),
135
 	// so echoing them back is a trivial DPI fingerprint.
145
 	// so echoing them back is a trivial DPI fingerprint.
136
-	for remaining := cipherSuiteLen; remaining >= 2; remaining -= 2 {
146
+	// cipherSuiteLen is in bytes; each cipher suite is 2 bytes.
147
+	for range cipherSuiteLen / 2 {
137
 		if _, err := io.ReadFull(r, header[:]); err != nil {
148
 		if _, err := io.ReadFull(r, header[:]); err != nil {
138
 			return nil, fmt.Errorf("cannot read cipher suite: %w", err)
149
 			return nil, fmt.Errorf("cannot read cipher suite: %w", err)
139
 		}
150
 		}
140
 
151
 
141
-		cs := binary.BigEndian.Uint16(header[:])
142
-		if hello.CipherSuite == 0 && cs&0x0f0f != 0x0a0a {
143
-			hello.CipherSuite = cs
152
+		if foundCipher {
153
+			continue
144
 		}
154
 		}
145
-	}
146
 
155
 
147
-	if hello.CipherSuite == 0 {
148
-		hello.CipherSuite = 0x1301 // fallback: TLS_AES_128_GCM_SHA256
156
+		if cs := binary.BigEndian.Uint16(header[:]); cs&GreaseMask != GreaseValueType {
157
+			hello.CipherSuite = cs
158
+			// do not forget we have to scan until the end
159
+			foundCipher = true
160
+		}
149
 	}
161
 	}
150
 
162
 
151
-
152
 	if _, err := io.ReadFull(r, header[:1]); err != nil {
163
 	if _, err := io.ReadFull(r, header[:1]); err != nil {
153
 		return nil, fmt.Errorf("cannot read compression methods length: %w", err)
164
 		return nil, fmt.Errorf("cannot read compression methods length: %w", err)
154
 	}
165
 	}

Загрузка…
Отмена
Сохранить