Skip to content

Commit 2dbc90c

Browse files
authored
Merge pull request #643 from getlantern/jovis-test-491-combine-tls-records
#491 concatenate rls records fragments
2 parents 31ed1e8 + d89d360 commit 2dbc90c

File tree

2 files changed

+241
-1
lines changed

2 files changed

+241
-1
lines changed

tlslistener/clienthelloconn.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,55 @@ func (rrc *clientHelloRecordingConn) Read(b []byte) (int, error) {
173173
return rrc.activeReader.Read(b)
174174
}
175175

176+
// This function concatenates TLS record fragments into a single record.
177+
// The output is the concatenation of the payloads of the input records plus a header.
178+
// The input data is expected to be one or multiple TLS records, each with the following format:
179+
// - 1 byte: content type
180+
// - 2 bytes: protocol version
181+
// - 2 bytes: length of the payload
182+
// - N bytes: payload
183+
func concatenateTlsRecordsFragments(data []byte) ([]byte, error) {
184+
const headerLength = 5
185+
186+
if len(data) < headerLength {
187+
return nil, fmt.Errorf("input data is too short to contain even one TLS record header")
188+
}
189+
190+
totalPayload := []byte{}
191+
var contentType byte
192+
var protocolVersion [2]byte
193+
194+
for i := 0; i < len(data); {
195+
if len(data[i:]) < headerLength {
196+
return nil, fmt.Errorf("incomplete TLS record header at position %d", i)
197+
}
198+
199+
header := data[i : i+headerLength]
200+
contentType = header[0]
201+
protocolVersion = [2]byte{header[1], header[2]}
202+
length := int(header[3])<<8 | int(header[4])
203+
204+
if len(data[i+headerLength:]) < length {
205+
return nil, fmt.Errorf("incomplete TLS record payload at position %d", i+headerLength)
206+
}
207+
208+
payload := data[i+headerLength : i+headerLength+length]
209+
totalPayload = append(totalPayload, payload...)
210+
211+
i += headerLength + length
212+
}
213+
214+
// Construct the new single TLS record
215+
totalLength := len(totalPayload)
216+
if totalLength > 0xFFFF {
217+
return nil, fmt.Errorf("concatenated payload length %d exceeds maximum TLS record size", totalLength)
218+
}
219+
220+
header := []byte{contentType, protocolVersion[0], protocolVersion[1], byte(totalLength >> 8), byte(totalLength & 0xFF)}
221+
result := append(header, totalPayload...)
222+
return result, nil
223+
}
224+
176225
func (rrc *clientHelloRecordingConn) processHello(info *tls.ClientHelloInfo) (*tls.Config, error) {
177226
// The hello is read at this point, so switch to no longer write incoming data to a second buffer.
178227
rrc.helloMutex.Lock()
@@ -183,7 +232,12 @@ func (rrc *clientHelloRecordingConn) processHello(info *tls.ClientHelloInfo) (*t
183232
bufferPool.Put(rrc.dataRead)
184233
}()
185234

186-
hello := rrc.dataRead.Bytes()[5:]
235+
concatenatedRecords, err := concatenateTlsRecordsFragments(rrc.dataRead.Bytes())
236+
if err != nil {
237+
return rrc.helloError("malformed ClientHello: " + err.Error())
238+
}
239+
240+
hello := concatenatedRecords[5:]
187241
// We use uTLS here purely because it exposes more TLS handshake internals, allowing
188242
// us to decrypt the ClientHello and session tickets, for example. We use those functions
189243
// separately without switching to uTLS entirely to allow continued upgrading of the TLS stack

tlslistener/clienthelloconn_test.go

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,189 @@ func TestParseInvalidTicket(t *testing.T) {
176176
uss, _ := utlsConfig.DecryptTicket(ticket, utls.ConnectionState{})
177177
require.Nil(t, uss)
178178
}
179+
180+
func TestConcatenateTlsRecordsOneFragments(t *testing.T) {
181+
// The input consists of 1 TLS records fragments
182+
input := []byte{
183+
// header
184+
0x16, 0x03, 0x01, 0x02, 0xCE,
185+
// payload
186+
0x01, 0x00, 0x02, 0xCA, 0x03, 0x03, 0x22, 0x7A, 0x33, 0xB1,
187+
0x2A, 0xD4, 0x39, 0x1B, 0x85, 0x96, 0xF7, 0x4B, 0xE5, 0x56, 0x54, 0x95, 0x72, 0x3D, 0x95, 0xA1, 0x68, 0x5B, 0x14, 0x83,
188+
0x67, 0xCA, 0x65, 0xEA, 0xD7, 0x3C, 0xCF, 0x71, 0x20, 0x82, 0xEA, 0xB3, 0x93, 0xB0, 0x08, 0x8B, 0x51, 0x0D, 0x6E, 0x13,
189+
0xDE, 0xB2, 0x0A, 0xF0, 0x8F, 0x35, 0xB9, 0x6C, 0xA1, 0x1F, 0x81, 0x09, 0x2D, 0x05, 0x8A, 0xCA, 0x94, 0x46, 0x2B, 0xFF,
190+
0xCB, 0x00, 0x20, 0x8A, 0x8A, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xC0, 0x2B, 0xC0, 0x2F, 0xC0, 0x2C, 0xC0, 0x30, 0xCC,
191+
0xA9, 0xCC, 0xA8, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x2F, 0x00, 0x35, 0x01, 0x00, 0x02, 0x61, 0xEA,
192+
0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x12, 0x6B, 0x61, 0x69, 0x67, 0x61, 0x69, 0x2D, 0x61,
193+
0x6E, 0x74, 0x65, 0x6E, 0x6E, 0x61, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x08, 0x3A, 0x3A, 0x00, 0x1D,
194+
0x00, 0x17, 0x00, 0x18, 0xFE, 0x0D, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x01, 0xED, 0x00, 0x20, 0xF7, 0x1A, 0x41, 0x75,
195+
0xF2, 0x4A, 0xE3, 0x96, 0x59, 0xA2, 0x82, 0x10, 0xD0, 0x14, 0x60, 0x75, 0x95, 0x96, 0xA4, 0x80, 0x55, 0x47, 0x17, 0x7F,
196+
0x19, 0x6F, 0x9C, 0x2A, 0x3B, 0xF3, 0xBD, 0x49, 0x00, 0xF0, 0x63, 0xEC, 0x1C, 0x81, 0xCD, 0x92, 0x45, 0x25, 0x1C, 0x12,
197+
0x2B, 0xD5, 0xED, 0xC9, 0x44, 0xE5, 0xE4, 0x5B, 0x79, 0xA5, 0x02, 0x95, 0x84, 0xE4, 0x40, 0x03, 0xD3, 0x5B, 0x45, 0xA7,
198+
0x02, 0xAF, 0xBD, 0xA3, 0xBB, 0x3A, 0xF4, 0xAB, 0xCF, 0x0B, 0xAD, 0xDD, 0x86, 0x95, 0x70, 0xF5, 0xEC, 0x3C, 0x92, 0x86,
199+
0x7E, 0x01, 0x39, 0xF0, 0x6A, 0x97, 0xAC, 0x38, 0xAA, 0x95, 0x7D, 0xB2, 0x87, 0xE7, 0xDD, 0x14, 0xFA, 0xA4, 0xF6, 0x65,
200+
0xE7, 0xF3, 0x96, 0xFC, 0xD6, 0x4A, 0x57, 0xEF, 0xCA, 0x60, 0x05, 0x69, 0x9D, 0x4F, 0x48, 0x39, 0xF8, 0x11, 0x42, 0x5E,
201+
0x36, 0xA7, 0x1D, 0x4A, 0xA6, 0x19, 0x59, 0x0D, 0x4E, 0x11, 0x26, 0xFC, 0x38, 0x1F, 0xFC, 0x1F, 0x93, 0xFD, 0x08, 0xEF,
202+
0x31, 0x46, 0xB9, 0x2B, 0x9A, 0x38, 0x7D, 0x97, 0x9F, 0xF5, 0xCD, 0x17, 0x7B, 0x54, 0x6F, 0xF0, 0x95, 0x9A, 0x5B, 0x90,
203+
0x38, 0xFF, 0xDD, 0xE9, 0xEC, 0xD8, 0x57, 0x97, 0xB7, 0x3E, 0xC7, 0xDA, 0xFA, 0x2A, 0x4D, 0xBF, 0x47, 0x4F, 0x3C, 0x74,
204+
0x94, 0xD7, 0x5C, 0x38, 0xD4, 0xE0, 0xC6, 0x0C, 0xAC, 0x32, 0x01, 0x26, 0x87, 0x40, 0x3D, 0xA0, 0xE3, 0x63, 0x3D, 0x93,
205+
0x37, 0x49, 0x33, 0x95, 0x67, 0x07, 0xC9, 0x18, 0x4F, 0x69, 0xF4, 0x67, 0x33, 0xAF, 0xB6, 0x5B, 0xF5, 0x0D, 0x85, 0x7A,
206+
0x5A, 0x19, 0xD2, 0xFB, 0xBF, 0xAF, 0xB1, 0xC6, 0x76, 0x4B, 0xD6, 0x36, 0x94, 0xB9, 0x77, 0xDC, 0x85, 0x50, 0x7E, 0xE4,
207+
0x74, 0x4C, 0x27, 0x00, 0x44, 0x06, 0x2B, 0xB0, 0xC6, 0xE6, 0xBA, 0x9C, 0x6B, 0x5E, 0x23, 0x8F, 0x2C, 0xD0, 0xA6, 0x90,
208+
0x0F, 0x75, 0x13, 0x0F, 0x7E, 0x10, 0x8E, 0x69, 0xA5, 0x4A, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x07, 0x06, 0xFA,
209+
0xFA, 0x03, 0x04, 0x03, 0x03, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
210+
0x00, 0x10, 0x00, 0x0E, 0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31, 0xFF, 0x01,
211+
0x00, 0x01, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x02, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04,
212+
0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x23, 0x00, 0x79, 0x87, 0xE8, 0xF7, 0x2A,
213+
0x06, 0x71, 0x97, 0xB1, 0xEE, 0xF2, 0xDE, 0x03, 0xF6, 0xC3, 0x2B, 0xE5, 0xBA, 0xA0, 0xFF, 0xE8, 0xA9, 0xA3, 0x81, 0xCB,
214+
0xFB, 0xC8, 0xAF, 0xFD, 0x40, 0xF8, 0x9F, 0x2C, 0xCA, 0x72, 0xF7, 0x8A, 0x04, 0xDD, 0x42, 0x7E, 0x0A, 0xEB, 0x56, 0x55,
215+
0x87, 0x94, 0x29, 0xB4, 0x67, 0x51, 0xDB, 0xB3, 0x8D, 0x04, 0x2C, 0x3F, 0x1B, 0x8F, 0x40, 0x65, 0x50, 0x7D, 0x73, 0x5B,
216+
0x65, 0x51, 0xAA, 0xF1, 0xF0, 0xD9, 0x7B, 0x6D, 0x6F, 0x83, 0x21, 0x70, 0x55, 0xC3, 0xD1, 0x30, 0xB6, 0x0B, 0x48, 0x76,
217+
0x41, 0x21, 0xE8, 0xBE, 0xD8, 0x76, 0x54, 0x84, 0x63, 0x67, 0x0F, 0x1F, 0x62, 0x62, 0xED, 0x9C, 0x0E, 0x14, 0x3D, 0x93,
218+
0x45, 0x5F, 0x99, 0x87, 0xF6, 0x3A, 0xD7, 0x43, 0xFB, 0x70, 0x14, 0x38, 0xBD, 0x9D, 0x35, 0x9A, 0x71, 0x00, 0x12, 0x00,
219+
0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2B, 0x00, 0x29, 0x3A, 0x3A, 0x00, 0x01,
220+
0x00, 0x00, 0x1D, 0x00, 0x20, 0x91, 0xA6, 0x05, 0x9B, 0xC6, 0x4C, 0xD9, 0xAF, 0x57, 0xDF, 0x92, 0xBB, 0xEF, 0xF3, 0x4C,
221+
0x6B, 0x9B, 0xD2, 0x06, 0xCA, 0xFC, 0x24, 0xBB, 0x90, 0xE7, 0x48, 0x04, 0xA8, 0x0D, 0x61, 0x46, 0x2F, 0x00, 0x2D, 0x00,
222+
0x02, 0x01, 0x01, 0x0A, 0x0A, 0x00, 0x01, 0x00,
223+
}
224+
225+
output, err := concatenateTlsRecordsFragments(input)
226+
require.NoError(t, err)
227+
require.NotEqual(t, output, nil)
228+
229+
hello := output[5:]
230+
helloMsg := utls.UnmarshalClientHello(hello)
231+
require.NotEqual(t, helloMsg, nil)
232+
require.NotEqual(t, len(helloMsg.SessionTicket), 0)
233+
require.Equal(t, helloMsg.ServerName, "kaigai-antenna.com")
234+
require.Equal(t, helloMsg.AlpnProtocols, []string{"h2", "http/1.1"})
235+
}
236+
237+
func TestConcatenateTlsRecordsTwoFragments(t *testing.T) {
238+
// The input consists of 2 TLS records fragments
239+
input := []byte{
240+
// 1st header
241+
0x16, 0x03, 0x01, 0x00, 0x03,
242+
// 1st payload
243+
0x01, 0x00, 0x02,
244+
// 2nd header
245+
0x16, 0x03, 0x01, 0x02, 0xCB,
246+
// 2nd payload
247+
0xCA, 0x03, 0x03, 0x22, 0x7A, 0x33, 0xB1,
248+
0x2A, 0xD4, 0x39, 0x1B, 0x85, 0x96, 0xF7, 0x4B, 0xE5, 0x56, 0x54, 0x95, 0x72, 0x3D, 0x95, 0xA1, 0x68, 0x5B, 0x14, 0x83,
249+
0x67, 0xCA, 0x65, 0xEA, 0xD7, 0x3C, 0xCF, 0x71, 0x20, 0x82, 0xEA, 0xB3, 0x93, 0xB0, 0x08, 0x8B, 0x51, 0x0D, 0x6E, 0x13,
250+
0xDE, 0xB2, 0x0A, 0xF0, 0x8F, 0x35, 0xB9, 0x6C, 0xA1, 0x1F, 0x81, 0x09, 0x2D, 0x05, 0x8A, 0xCA, 0x94, 0x46, 0x2B, 0xFF,
251+
0xCB, 0x00, 0x20, 0x8A, 0x8A, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xC0, 0x2B, 0xC0, 0x2F, 0xC0, 0x2C, 0xC0, 0x30, 0xCC,
252+
0xA9, 0xCC, 0xA8, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x2F, 0x00, 0x35, 0x01, 0x00, 0x02, 0x61, 0xEA,
253+
0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x12, 0x6B, 0x61, 0x69, 0x67, 0x61, 0x69, 0x2D, 0x61,
254+
0x6E, 0x74, 0x65, 0x6E, 0x6E, 0x61, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x08, 0x3A, 0x3A, 0x00, 0x1D,
255+
0x00, 0x17, 0x00, 0x18, 0xFE, 0x0D, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x01, 0xED, 0x00, 0x20, 0xF7, 0x1A, 0x41, 0x75,
256+
0xF2, 0x4A, 0xE3, 0x96, 0x59, 0xA2, 0x82, 0x10, 0xD0, 0x14, 0x60, 0x75, 0x95, 0x96, 0xA4, 0x80, 0x55, 0x47, 0x17, 0x7F,
257+
0x19, 0x6F, 0x9C, 0x2A, 0x3B, 0xF3, 0xBD, 0x49, 0x00, 0xF0, 0x63, 0xEC, 0x1C, 0x81, 0xCD, 0x92, 0x45, 0x25, 0x1C, 0x12,
258+
0x2B, 0xD5, 0xED, 0xC9, 0x44, 0xE5, 0xE4, 0x5B, 0x79, 0xA5, 0x02, 0x95, 0x84, 0xE4, 0x40, 0x03, 0xD3, 0x5B, 0x45, 0xA7,
259+
0x02, 0xAF, 0xBD, 0xA3, 0xBB, 0x3A, 0xF4, 0xAB, 0xCF, 0x0B, 0xAD, 0xDD, 0x86, 0x95, 0x70, 0xF5, 0xEC, 0x3C, 0x92, 0x86,
260+
0x7E, 0x01, 0x39, 0xF0, 0x6A, 0x97, 0xAC, 0x38, 0xAA, 0x95, 0x7D, 0xB2, 0x87, 0xE7, 0xDD, 0x14, 0xFA, 0xA4, 0xF6, 0x65,
261+
0xE7, 0xF3, 0x96, 0xFC, 0xD6, 0x4A, 0x57, 0xEF, 0xCA, 0x60, 0x05, 0x69, 0x9D, 0x4F, 0x48, 0x39, 0xF8, 0x11, 0x42, 0x5E,
262+
0x36, 0xA7, 0x1D, 0x4A, 0xA6, 0x19, 0x59, 0x0D, 0x4E, 0x11, 0x26, 0xFC, 0x38, 0x1F, 0xFC, 0x1F, 0x93, 0xFD, 0x08, 0xEF,
263+
0x31, 0x46, 0xB9, 0x2B, 0x9A, 0x38, 0x7D, 0x97, 0x9F, 0xF5, 0xCD, 0x17, 0x7B, 0x54, 0x6F, 0xF0, 0x95, 0x9A, 0x5B, 0x90,
264+
0x38, 0xFF, 0xDD, 0xE9, 0xEC, 0xD8, 0x57, 0x97, 0xB7, 0x3E, 0xC7, 0xDA, 0xFA, 0x2A, 0x4D, 0xBF, 0x47, 0x4F, 0x3C, 0x74,
265+
0x94, 0xD7, 0x5C, 0x38, 0xD4, 0xE0, 0xC6, 0x0C, 0xAC, 0x32, 0x01, 0x26, 0x87, 0x40, 0x3D, 0xA0, 0xE3, 0x63, 0x3D, 0x93,
266+
0x37, 0x49, 0x33, 0x95, 0x67, 0x07, 0xC9, 0x18, 0x4F, 0x69, 0xF4, 0x67, 0x33, 0xAF, 0xB6, 0x5B, 0xF5, 0x0D, 0x85, 0x7A,
267+
0x5A, 0x19, 0xD2, 0xFB, 0xBF, 0xAF, 0xB1, 0xC6, 0x76, 0x4B, 0xD6, 0x36, 0x94, 0xB9, 0x77, 0xDC, 0x85, 0x50, 0x7E, 0xE4,
268+
0x74, 0x4C, 0x27, 0x00, 0x44, 0x06, 0x2B, 0xB0, 0xC6, 0xE6, 0xBA, 0x9C, 0x6B, 0x5E, 0x23, 0x8F, 0x2C, 0xD0, 0xA6, 0x90,
269+
0x0F, 0x75, 0x13, 0x0F, 0x7E, 0x10, 0x8E, 0x69, 0xA5, 0x4A, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x07, 0x06, 0xFA,
270+
0xFA, 0x03, 0x04, 0x03, 0x03, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
271+
0x00, 0x10, 0x00, 0x0E, 0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31, 0xFF, 0x01,
272+
0x00, 0x01, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x02, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04,
273+
0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x23, 0x00, 0x79, 0x87, 0xE8, 0xF7, 0x2A,
274+
0x06, 0x71, 0x97, 0xB1, 0xEE, 0xF2, 0xDE, 0x03, 0xF6, 0xC3, 0x2B, 0xE5, 0xBA, 0xA0, 0xFF, 0xE8, 0xA9, 0xA3, 0x81, 0xCB,
275+
0xFB, 0xC8, 0xAF, 0xFD, 0x40, 0xF8, 0x9F, 0x2C, 0xCA, 0x72, 0xF7, 0x8A, 0x04, 0xDD, 0x42, 0x7E, 0x0A, 0xEB, 0x56, 0x55,
276+
0x87, 0x94, 0x29, 0xB4, 0x67, 0x51, 0xDB, 0xB3, 0x8D, 0x04, 0x2C, 0x3F, 0x1B, 0x8F, 0x40, 0x65, 0x50, 0x7D, 0x73, 0x5B,
277+
0x65, 0x51, 0xAA, 0xF1, 0xF0, 0xD9, 0x7B, 0x6D, 0x6F, 0x83, 0x21, 0x70, 0x55, 0xC3, 0xD1, 0x30, 0xB6, 0x0B, 0x48, 0x76,
278+
0x41, 0x21, 0xE8, 0xBE, 0xD8, 0x76, 0x54, 0x84, 0x63, 0x67, 0x0F, 0x1F, 0x62, 0x62, 0xED, 0x9C, 0x0E, 0x14, 0x3D, 0x93,
279+
0x45, 0x5F, 0x99, 0x87, 0xF6, 0x3A, 0xD7, 0x43, 0xFB, 0x70, 0x14, 0x38, 0xBD, 0x9D, 0x35, 0x9A, 0x71, 0x00, 0x12, 0x00,
280+
0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2B, 0x00, 0x29, 0x3A, 0x3A, 0x00, 0x01,
281+
0x00, 0x00, 0x1D, 0x00, 0x20, 0x91, 0xA6, 0x05, 0x9B, 0xC6, 0x4C, 0xD9, 0xAF, 0x57, 0xDF, 0x92, 0xBB, 0xEF, 0xF3, 0x4C,
282+
0x6B, 0x9B, 0xD2, 0x06, 0xCA, 0xFC, 0x24, 0xBB, 0x90, 0xE7, 0x48, 0x04, 0xA8, 0x0D, 0x61, 0x46, 0x2F, 0x00, 0x2D, 0x00,
283+
0x02, 0x01, 0x01, 0x0A, 0x0A, 0x00, 0x01, 0x00,
284+
}
285+
286+
output, err := concatenateTlsRecordsFragments(input)
287+
require.NoError(t, err)
288+
require.NotEqual(t, output, nil)
289+
290+
hello := output[5:]
291+
helloMsg := utls.UnmarshalClientHello(hello)
292+
require.NotEqual(t, helloMsg, nil)
293+
require.NotEqual(t, len(helloMsg.SessionTicket), 0)
294+
require.Equal(t, helloMsg.ServerName, "kaigai-antenna.com")
295+
require.Equal(t, helloMsg.AlpnProtocols, []string{"h2", "http/1.1"})
296+
}
297+
298+
func TestConcatenateTlsRecordsFourFragments(t *testing.T) {
299+
// The input consists of 4 TLS records fragments
300+
input := []byte{
301+
// 1st header
302+
0x16, 0x03, 0x01, 0x00, 0x03,
303+
// 1st payload
304+
0x01, 0x00, 0x02,
305+
// 2nd header
306+
0x16, 0x03, 0x01, 0x00, 0x14,
307+
// 2nd payload
308+
0xCA, 0x03, 0x03, 0x22, 0x7A, 0x33, 0xB1, 0x2A, 0xD4, 0x39, 0x1B, 0x85, 0x96, 0xF7, 0x4B, 0xE5, 0x56, 0x54, 0x95, 0x72,
309+
// 3rd header
310+
0x16, 0x03, 0x01, 0x00, 0x2D,
311+
// 3rd payload
312+
0x3D, 0x95, 0xA1, 0x68, 0x5B, 0x14, 0x83,
313+
0x67, 0xCA, 0x65, 0xEA, 0xD7, 0x3C, 0xCF, 0x71, 0x20, 0x82, 0xEA, 0xB3, 0x93, 0xB0, 0x08, 0x8B, 0x51, 0x0D, 0x6E, 0x13,
314+
0xDE, 0xB2, 0x0A, 0xF0, 0x8F, 0x35, 0xB9, 0x6C, 0xA1, 0x1F, 0x81, 0x09, 0x2D, 0x05, 0x8A, 0xCA, 0x94, 0x46,
315+
// 4th header
316+
0x16, 0x03, 0x01, 0x02, 0x8A,
317+
// 4th payload
318+
0x2B, 0xFF,
319+
0xCB, 0x00, 0x20, 0x8A, 0x8A, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xC0, 0x2B, 0xC0, 0x2F, 0xC0, 0x2C, 0xC0, 0x30, 0xCC,
320+
0xA9, 0xCC, 0xA8, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x2F, 0x00, 0x35, 0x01, 0x00, 0x02, 0x61, 0xEA,
321+
0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x12, 0x6B, 0x61, 0x69, 0x67, 0x61, 0x69, 0x2D, 0x61,
322+
0x6E, 0x74, 0x65, 0x6E, 0x6E, 0x61, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x08, 0x3A, 0x3A, 0x00, 0x1D,
323+
0x00, 0x17, 0x00, 0x18, 0xFE, 0x0D, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x01, 0xED, 0x00, 0x20, 0xF7, 0x1A, 0x41, 0x75,
324+
0xF2, 0x4A, 0xE3, 0x96, 0x59, 0xA2, 0x82, 0x10, 0xD0, 0x14, 0x60, 0x75, 0x95, 0x96, 0xA4, 0x80, 0x55, 0x47, 0x17, 0x7F,
325+
0x19, 0x6F, 0x9C, 0x2A, 0x3B, 0xF3, 0xBD, 0x49, 0x00, 0xF0, 0x63, 0xEC, 0x1C, 0x81, 0xCD, 0x92, 0x45, 0x25, 0x1C, 0x12,
326+
0x2B, 0xD5, 0xED, 0xC9, 0x44, 0xE5, 0xE4, 0x5B, 0x79, 0xA5, 0x02, 0x95, 0x84, 0xE4, 0x40, 0x03, 0xD3, 0x5B, 0x45, 0xA7,
327+
0x02, 0xAF, 0xBD, 0xA3, 0xBB, 0x3A, 0xF4, 0xAB, 0xCF, 0x0B, 0xAD, 0xDD, 0x86, 0x95, 0x70, 0xF5, 0xEC, 0x3C, 0x92, 0x86,
328+
0x7E, 0x01, 0x39, 0xF0, 0x6A, 0x97, 0xAC, 0x38, 0xAA, 0x95, 0x7D, 0xB2, 0x87, 0xE7, 0xDD, 0x14, 0xFA, 0xA4, 0xF6, 0x65,
329+
0xE7, 0xF3, 0x96, 0xFC, 0xD6, 0x4A, 0x57, 0xEF, 0xCA, 0x60, 0x05, 0x69, 0x9D, 0x4F, 0x48, 0x39, 0xF8, 0x11, 0x42, 0x5E,
330+
0x36, 0xA7, 0x1D, 0x4A, 0xA6, 0x19, 0x59, 0x0D, 0x4E, 0x11, 0x26, 0xFC, 0x38, 0x1F, 0xFC, 0x1F, 0x93, 0xFD, 0x08, 0xEF,
331+
0x31, 0x46, 0xB9, 0x2B, 0x9A, 0x38, 0x7D, 0x97, 0x9F, 0xF5, 0xCD, 0x17, 0x7B, 0x54, 0x6F, 0xF0, 0x95, 0x9A, 0x5B, 0x90,
332+
0x38, 0xFF, 0xDD, 0xE9, 0xEC, 0xD8, 0x57, 0x97, 0xB7, 0x3E, 0xC7, 0xDA, 0xFA, 0x2A, 0x4D, 0xBF, 0x47, 0x4F, 0x3C, 0x74,
333+
0x94, 0xD7, 0x5C, 0x38, 0xD4, 0xE0, 0xC6, 0x0C, 0xAC, 0x32, 0x01, 0x26, 0x87, 0x40, 0x3D, 0xA0, 0xE3, 0x63, 0x3D, 0x93,
334+
0x37, 0x49, 0x33, 0x95, 0x67, 0x07, 0xC9, 0x18, 0x4F, 0x69, 0xF4, 0x67, 0x33, 0xAF, 0xB6, 0x5B, 0xF5, 0x0D, 0x85, 0x7A,
335+
0x5A, 0x19, 0xD2, 0xFB, 0xBF, 0xAF, 0xB1, 0xC6, 0x76, 0x4B, 0xD6, 0x36, 0x94, 0xB9, 0x77, 0xDC, 0x85, 0x50, 0x7E, 0xE4,
336+
0x74, 0x4C, 0x27, 0x00, 0x44, 0x06, 0x2B, 0xB0, 0xC6, 0xE6, 0xBA, 0x9C, 0x6B, 0x5E, 0x23, 0x8F, 0x2C, 0xD0, 0xA6, 0x90,
337+
0x0F, 0x75, 0x13, 0x0F, 0x7E, 0x10, 0x8E, 0x69, 0xA5, 0x4A, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x07, 0x06, 0xFA,
338+
0xFA, 0x03, 0x04, 0x03, 0x03, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
339+
0x00, 0x10, 0x00, 0x0E, 0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31, 0xFF, 0x01,
340+
0x00, 0x01, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x02, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04,
341+
0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x23, 0x00, 0x79, 0x87, 0xE8, 0xF7, 0x2A,
342+
0x06, 0x71, 0x97, 0xB1, 0xEE, 0xF2, 0xDE, 0x03, 0xF6, 0xC3, 0x2B, 0xE5, 0xBA, 0xA0, 0xFF, 0xE8, 0xA9, 0xA3, 0x81, 0xCB,
343+
0xFB, 0xC8, 0xAF, 0xFD, 0x40, 0xF8, 0x9F, 0x2C, 0xCA, 0x72, 0xF7, 0x8A, 0x04, 0xDD, 0x42, 0x7E, 0x0A, 0xEB, 0x56, 0x55,
344+
0x87, 0x94, 0x29, 0xB4, 0x67, 0x51, 0xDB, 0xB3, 0x8D, 0x04, 0x2C, 0x3F, 0x1B, 0x8F, 0x40, 0x65, 0x50, 0x7D, 0x73, 0x5B,
345+
0x65, 0x51, 0xAA, 0xF1, 0xF0, 0xD9, 0x7B, 0x6D, 0x6F, 0x83, 0x21, 0x70, 0x55, 0xC3, 0xD1, 0x30, 0xB6, 0x0B, 0x48, 0x76,
346+
0x41, 0x21, 0xE8, 0xBE, 0xD8, 0x76, 0x54, 0x84, 0x63, 0x67, 0x0F, 0x1F, 0x62, 0x62, 0xED, 0x9C, 0x0E, 0x14, 0x3D, 0x93,
347+
0x45, 0x5F, 0x99, 0x87, 0xF6, 0x3A, 0xD7, 0x43, 0xFB, 0x70, 0x14, 0x38, 0xBD, 0x9D, 0x35, 0x9A, 0x71, 0x00, 0x12, 0x00,
348+
0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2B, 0x00, 0x29, 0x3A, 0x3A, 0x00, 0x01,
349+
0x00, 0x00, 0x1D, 0x00, 0x20, 0x91, 0xA6, 0x05, 0x9B, 0xC6, 0x4C, 0xD9, 0xAF, 0x57, 0xDF, 0x92, 0xBB, 0xEF, 0xF3, 0x4C,
350+
0x6B, 0x9B, 0xD2, 0x06, 0xCA, 0xFC, 0x24, 0xBB, 0x90, 0xE7, 0x48, 0x04, 0xA8, 0x0D, 0x61, 0x46, 0x2F, 0x00, 0x2D, 0x00,
351+
0x02, 0x01, 0x01, 0x0A, 0x0A, 0x00, 0x01, 0x00,
352+
}
353+
354+
output, err := concatenateTlsRecordsFragments(input)
355+
require.NoError(t, err)
356+
require.NotEqual(t, output, nil)
357+
358+
hello := output[5:]
359+
helloMsg := utls.UnmarshalClientHello(hello)
360+
require.NotEqual(t, helloMsg, nil)
361+
require.NotEqual(t, len(helloMsg.SessionTicket), 0)
362+
require.Equal(t, helloMsg.ServerName, "kaigai-antenna.com")
363+
require.Equal(t, helloMsg.AlpnProtocols, []string{"h2", "http/1.1"})
364+
}

0 commit comments

Comments
 (0)