Skip to content

Commit

Permalink
Merge pull request #643 from getlantern/jovis-test-491-combine-tls-re…
Browse files Browse the repository at this point in the history
…cords

#491 concatenate rls records fragments
  • Loading branch information
Jovis7 authored Feb 10, 2025
2 parents 31ed1e8 + d89d360 commit 2dbc90c
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 1 deletion.
56 changes: 55 additions & 1 deletion tlslistener/clienthelloconn.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,55 @@ func (rrc *clientHelloRecordingConn) Read(b []byte) (int, error) {
return rrc.activeReader.Read(b)
}

// This function concatenates TLS record fragments into a single record.
// The output is the concatenation of the payloads of the input records plus a header.
// The input data is expected to be one or multiple TLS records, each with the following format:
// - 1 byte: content type
// - 2 bytes: protocol version
// - 2 bytes: length of the payload
// - N bytes: payload
func concatenateTlsRecordsFragments(data []byte) ([]byte, error) {
const headerLength = 5

if len(data) < headerLength {
return nil, fmt.Errorf("input data is too short to contain even one TLS record header")
}

totalPayload := []byte{}
var contentType byte
var protocolVersion [2]byte

for i := 0; i < len(data); {
if len(data[i:]) < headerLength {
return nil, fmt.Errorf("incomplete TLS record header at position %d", i)
}

header := data[i : i+headerLength]
contentType = header[0]
protocolVersion = [2]byte{header[1], header[2]}
length := int(header[3])<<8 | int(header[4])

if len(data[i+headerLength:]) < length {
return nil, fmt.Errorf("incomplete TLS record payload at position %d", i+headerLength)
}

payload := data[i+headerLength : i+headerLength+length]
totalPayload = append(totalPayload, payload...)

i += headerLength + length
}

// Construct the new single TLS record
totalLength := len(totalPayload)
if totalLength > 0xFFFF {
return nil, fmt.Errorf("concatenated payload length %d exceeds maximum TLS record size", totalLength)
}

header := []byte{contentType, protocolVersion[0], protocolVersion[1], byte(totalLength >> 8), byte(totalLength & 0xFF)}
result := append(header, totalPayload...)
return result, nil
}

func (rrc *clientHelloRecordingConn) processHello(info *tls.ClientHelloInfo) (*tls.Config, error) {
// The hello is read at this point, so switch to no longer write incoming data to a second buffer.
rrc.helloMutex.Lock()
Expand All @@ -183,7 +232,12 @@ func (rrc *clientHelloRecordingConn) processHello(info *tls.ClientHelloInfo) (*t
bufferPool.Put(rrc.dataRead)
}()

hello := rrc.dataRead.Bytes()[5:]
concatenatedRecords, err := concatenateTlsRecordsFragments(rrc.dataRead.Bytes())
if err != nil {
return rrc.helloError("malformed ClientHello: " + err.Error())
}

hello := concatenatedRecords[5:]
// We use uTLS here purely because it exposes more TLS handshake internals, allowing
// us to decrypt the ClientHello and session tickets, for example. We use those functions
// separately without switching to uTLS entirely to allow continued upgrading of the TLS stack
Expand Down
186 changes: 186 additions & 0 deletions tlslistener/clienthelloconn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,189 @@ func TestParseInvalidTicket(t *testing.T) {
uss, _ := utlsConfig.DecryptTicket(ticket, utls.ConnectionState{})
require.Nil(t, uss)
}

func TestConcatenateTlsRecordsOneFragments(t *testing.T) {
// The input consists of 1 TLS records fragments
input := []byte{
// header
0x16, 0x03, 0x01, 0x02, 0xCE,
// payload
0x01, 0x00, 0x02, 0xCA, 0x03, 0x03, 0x22, 0x7A, 0x33, 0xB1,
0x2A, 0xD4, 0x39, 0x1B, 0x85, 0x96, 0xF7, 0x4B, 0xE5, 0x56, 0x54, 0x95, 0x72, 0x3D, 0x95, 0xA1, 0x68, 0x5B, 0x14, 0x83,
0x67, 0xCA, 0x65, 0xEA, 0xD7, 0x3C, 0xCF, 0x71, 0x20, 0x82, 0xEA, 0xB3, 0x93, 0xB0, 0x08, 0x8B, 0x51, 0x0D, 0x6E, 0x13,
0xDE, 0xB2, 0x0A, 0xF0, 0x8F, 0x35, 0xB9, 0x6C, 0xA1, 0x1F, 0x81, 0x09, 0x2D, 0x05, 0x8A, 0xCA, 0x94, 0x46, 0x2B, 0xFF,
0xCB, 0x00, 0x20, 0x8A, 0x8A, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xC0, 0x2B, 0xC0, 0x2F, 0xC0, 0x2C, 0xC0, 0x30, 0xCC,
0xA9, 0xCC, 0xA8, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x2F, 0x00, 0x35, 0x01, 0x00, 0x02, 0x61, 0xEA,
0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x12, 0x6B, 0x61, 0x69, 0x67, 0x61, 0x69, 0x2D, 0x61,
0x6E, 0x74, 0x65, 0x6E, 0x6E, 0x61, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x08, 0x3A, 0x3A, 0x00, 0x1D,
0x00, 0x17, 0x00, 0x18, 0xFE, 0x0D, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x01, 0xED, 0x00, 0x20, 0xF7, 0x1A, 0x41, 0x75,
0xF2, 0x4A, 0xE3, 0x96, 0x59, 0xA2, 0x82, 0x10, 0xD0, 0x14, 0x60, 0x75, 0x95, 0x96, 0xA4, 0x80, 0x55, 0x47, 0x17, 0x7F,
0x19, 0x6F, 0x9C, 0x2A, 0x3B, 0xF3, 0xBD, 0x49, 0x00, 0xF0, 0x63, 0xEC, 0x1C, 0x81, 0xCD, 0x92, 0x45, 0x25, 0x1C, 0x12,
0x2B, 0xD5, 0xED, 0xC9, 0x44, 0xE5, 0xE4, 0x5B, 0x79, 0xA5, 0x02, 0x95, 0x84, 0xE4, 0x40, 0x03, 0xD3, 0x5B, 0x45, 0xA7,
0x02, 0xAF, 0xBD, 0xA3, 0xBB, 0x3A, 0xF4, 0xAB, 0xCF, 0x0B, 0xAD, 0xDD, 0x86, 0x95, 0x70, 0xF5, 0xEC, 0x3C, 0x92, 0x86,
0x7E, 0x01, 0x39, 0xF0, 0x6A, 0x97, 0xAC, 0x38, 0xAA, 0x95, 0x7D, 0xB2, 0x87, 0xE7, 0xDD, 0x14, 0xFA, 0xA4, 0xF6, 0x65,
0xE7, 0xF3, 0x96, 0xFC, 0xD6, 0x4A, 0x57, 0xEF, 0xCA, 0x60, 0x05, 0x69, 0x9D, 0x4F, 0x48, 0x39, 0xF8, 0x11, 0x42, 0x5E,
0x36, 0xA7, 0x1D, 0x4A, 0xA6, 0x19, 0x59, 0x0D, 0x4E, 0x11, 0x26, 0xFC, 0x38, 0x1F, 0xFC, 0x1F, 0x93, 0xFD, 0x08, 0xEF,
0x31, 0x46, 0xB9, 0x2B, 0x9A, 0x38, 0x7D, 0x97, 0x9F, 0xF5, 0xCD, 0x17, 0x7B, 0x54, 0x6F, 0xF0, 0x95, 0x9A, 0x5B, 0x90,
0x38, 0xFF, 0xDD, 0xE9, 0xEC, 0xD8, 0x57, 0x97, 0xB7, 0x3E, 0xC7, 0xDA, 0xFA, 0x2A, 0x4D, 0xBF, 0x47, 0x4F, 0x3C, 0x74,
0x94, 0xD7, 0x5C, 0x38, 0xD4, 0xE0, 0xC6, 0x0C, 0xAC, 0x32, 0x01, 0x26, 0x87, 0x40, 0x3D, 0xA0, 0xE3, 0x63, 0x3D, 0x93,
0x37, 0x49, 0x33, 0x95, 0x67, 0x07, 0xC9, 0x18, 0x4F, 0x69, 0xF4, 0x67, 0x33, 0xAF, 0xB6, 0x5B, 0xF5, 0x0D, 0x85, 0x7A,
0x5A, 0x19, 0xD2, 0xFB, 0xBF, 0xAF, 0xB1, 0xC6, 0x76, 0x4B, 0xD6, 0x36, 0x94, 0xB9, 0x77, 0xDC, 0x85, 0x50, 0x7E, 0xE4,
0x74, 0x4C, 0x27, 0x00, 0x44, 0x06, 0x2B, 0xB0, 0xC6, 0xE6, 0xBA, 0x9C, 0x6B, 0x5E, 0x23, 0x8F, 0x2C, 0xD0, 0xA6, 0x90,
0x0F, 0x75, 0x13, 0x0F, 0x7E, 0x10, 0x8E, 0x69, 0xA5, 0x4A, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x07, 0x06, 0xFA,
0xFA, 0x03, 0x04, 0x03, 0x03, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
0x00, 0x10, 0x00, 0x0E, 0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31, 0xFF, 0x01,
0x00, 0x01, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x02, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04,
0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x23, 0x00, 0x79, 0x87, 0xE8, 0xF7, 0x2A,
0x06, 0x71, 0x97, 0xB1, 0xEE, 0xF2, 0xDE, 0x03, 0xF6, 0xC3, 0x2B, 0xE5, 0xBA, 0xA0, 0xFF, 0xE8, 0xA9, 0xA3, 0x81, 0xCB,
0xFB, 0xC8, 0xAF, 0xFD, 0x40, 0xF8, 0x9F, 0x2C, 0xCA, 0x72, 0xF7, 0x8A, 0x04, 0xDD, 0x42, 0x7E, 0x0A, 0xEB, 0x56, 0x55,
0x87, 0x94, 0x29, 0xB4, 0x67, 0x51, 0xDB, 0xB3, 0x8D, 0x04, 0x2C, 0x3F, 0x1B, 0x8F, 0x40, 0x65, 0x50, 0x7D, 0x73, 0x5B,
0x65, 0x51, 0xAA, 0xF1, 0xF0, 0xD9, 0x7B, 0x6D, 0x6F, 0x83, 0x21, 0x70, 0x55, 0xC3, 0xD1, 0x30, 0xB6, 0x0B, 0x48, 0x76,
0x41, 0x21, 0xE8, 0xBE, 0xD8, 0x76, 0x54, 0x84, 0x63, 0x67, 0x0F, 0x1F, 0x62, 0x62, 0xED, 0x9C, 0x0E, 0x14, 0x3D, 0x93,
0x45, 0x5F, 0x99, 0x87, 0xF6, 0x3A, 0xD7, 0x43, 0xFB, 0x70, 0x14, 0x38, 0xBD, 0x9D, 0x35, 0x9A, 0x71, 0x00, 0x12, 0x00,
0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2B, 0x00, 0x29, 0x3A, 0x3A, 0x00, 0x01,
0x00, 0x00, 0x1D, 0x00, 0x20, 0x91, 0xA6, 0x05, 0x9B, 0xC6, 0x4C, 0xD9, 0xAF, 0x57, 0xDF, 0x92, 0xBB, 0xEF, 0xF3, 0x4C,
0x6B, 0x9B, 0xD2, 0x06, 0xCA, 0xFC, 0x24, 0xBB, 0x90, 0xE7, 0x48, 0x04, 0xA8, 0x0D, 0x61, 0x46, 0x2F, 0x00, 0x2D, 0x00,
0x02, 0x01, 0x01, 0x0A, 0x0A, 0x00, 0x01, 0x00,
}

output, err := concatenateTlsRecordsFragments(input)
require.NoError(t, err)
require.NotEqual(t, output, nil)

hello := output[5:]
helloMsg := utls.UnmarshalClientHello(hello)
require.NotEqual(t, helloMsg, nil)
require.NotEqual(t, len(helloMsg.SessionTicket), 0)
require.Equal(t, helloMsg.ServerName, "kaigai-antenna.com")
require.Equal(t, helloMsg.AlpnProtocols, []string{"h2", "http/1.1"})
}

func TestConcatenateTlsRecordsTwoFragments(t *testing.T) {
// The input consists of 2 TLS records fragments
input := []byte{
// 1st header
0x16, 0x03, 0x01, 0x00, 0x03,
// 1st payload
0x01, 0x00, 0x02,
// 2nd header
0x16, 0x03, 0x01, 0x02, 0xCB,
// 2nd payload
0xCA, 0x03, 0x03, 0x22, 0x7A, 0x33, 0xB1,
0x2A, 0xD4, 0x39, 0x1B, 0x85, 0x96, 0xF7, 0x4B, 0xE5, 0x56, 0x54, 0x95, 0x72, 0x3D, 0x95, 0xA1, 0x68, 0x5B, 0x14, 0x83,
0x67, 0xCA, 0x65, 0xEA, 0xD7, 0x3C, 0xCF, 0x71, 0x20, 0x82, 0xEA, 0xB3, 0x93, 0xB0, 0x08, 0x8B, 0x51, 0x0D, 0x6E, 0x13,
0xDE, 0xB2, 0x0A, 0xF0, 0x8F, 0x35, 0xB9, 0x6C, 0xA1, 0x1F, 0x81, 0x09, 0x2D, 0x05, 0x8A, 0xCA, 0x94, 0x46, 0x2B, 0xFF,
0xCB, 0x00, 0x20, 0x8A, 0x8A, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xC0, 0x2B, 0xC0, 0x2F, 0xC0, 0x2C, 0xC0, 0x30, 0xCC,
0xA9, 0xCC, 0xA8, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x2F, 0x00, 0x35, 0x01, 0x00, 0x02, 0x61, 0xEA,
0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x12, 0x6B, 0x61, 0x69, 0x67, 0x61, 0x69, 0x2D, 0x61,
0x6E, 0x74, 0x65, 0x6E, 0x6E, 0x61, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x08, 0x3A, 0x3A, 0x00, 0x1D,
0x00, 0x17, 0x00, 0x18, 0xFE, 0x0D, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x01, 0xED, 0x00, 0x20, 0xF7, 0x1A, 0x41, 0x75,
0xF2, 0x4A, 0xE3, 0x96, 0x59, 0xA2, 0x82, 0x10, 0xD0, 0x14, 0x60, 0x75, 0x95, 0x96, 0xA4, 0x80, 0x55, 0x47, 0x17, 0x7F,
0x19, 0x6F, 0x9C, 0x2A, 0x3B, 0xF3, 0xBD, 0x49, 0x00, 0xF0, 0x63, 0xEC, 0x1C, 0x81, 0xCD, 0x92, 0x45, 0x25, 0x1C, 0x12,
0x2B, 0xD5, 0xED, 0xC9, 0x44, 0xE5, 0xE4, 0x5B, 0x79, 0xA5, 0x02, 0x95, 0x84, 0xE4, 0x40, 0x03, 0xD3, 0x5B, 0x45, 0xA7,
0x02, 0xAF, 0xBD, 0xA3, 0xBB, 0x3A, 0xF4, 0xAB, 0xCF, 0x0B, 0xAD, 0xDD, 0x86, 0x95, 0x70, 0xF5, 0xEC, 0x3C, 0x92, 0x86,
0x7E, 0x01, 0x39, 0xF0, 0x6A, 0x97, 0xAC, 0x38, 0xAA, 0x95, 0x7D, 0xB2, 0x87, 0xE7, 0xDD, 0x14, 0xFA, 0xA4, 0xF6, 0x65,
0xE7, 0xF3, 0x96, 0xFC, 0xD6, 0x4A, 0x57, 0xEF, 0xCA, 0x60, 0x05, 0x69, 0x9D, 0x4F, 0x48, 0x39, 0xF8, 0x11, 0x42, 0x5E,
0x36, 0xA7, 0x1D, 0x4A, 0xA6, 0x19, 0x59, 0x0D, 0x4E, 0x11, 0x26, 0xFC, 0x38, 0x1F, 0xFC, 0x1F, 0x93, 0xFD, 0x08, 0xEF,
0x31, 0x46, 0xB9, 0x2B, 0x9A, 0x38, 0x7D, 0x97, 0x9F, 0xF5, 0xCD, 0x17, 0x7B, 0x54, 0x6F, 0xF0, 0x95, 0x9A, 0x5B, 0x90,
0x38, 0xFF, 0xDD, 0xE9, 0xEC, 0xD8, 0x57, 0x97, 0xB7, 0x3E, 0xC7, 0xDA, 0xFA, 0x2A, 0x4D, 0xBF, 0x47, 0x4F, 0x3C, 0x74,
0x94, 0xD7, 0x5C, 0x38, 0xD4, 0xE0, 0xC6, 0x0C, 0xAC, 0x32, 0x01, 0x26, 0x87, 0x40, 0x3D, 0xA0, 0xE3, 0x63, 0x3D, 0x93,
0x37, 0x49, 0x33, 0x95, 0x67, 0x07, 0xC9, 0x18, 0x4F, 0x69, 0xF4, 0x67, 0x33, 0xAF, 0xB6, 0x5B, 0xF5, 0x0D, 0x85, 0x7A,
0x5A, 0x19, 0xD2, 0xFB, 0xBF, 0xAF, 0xB1, 0xC6, 0x76, 0x4B, 0xD6, 0x36, 0x94, 0xB9, 0x77, 0xDC, 0x85, 0x50, 0x7E, 0xE4,
0x74, 0x4C, 0x27, 0x00, 0x44, 0x06, 0x2B, 0xB0, 0xC6, 0xE6, 0xBA, 0x9C, 0x6B, 0x5E, 0x23, 0x8F, 0x2C, 0xD0, 0xA6, 0x90,
0x0F, 0x75, 0x13, 0x0F, 0x7E, 0x10, 0x8E, 0x69, 0xA5, 0x4A, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x07, 0x06, 0xFA,
0xFA, 0x03, 0x04, 0x03, 0x03, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
0x00, 0x10, 0x00, 0x0E, 0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31, 0xFF, 0x01,
0x00, 0x01, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x02, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04,
0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x23, 0x00, 0x79, 0x87, 0xE8, 0xF7, 0x2A,
0x06, 0x71, 0x97, 0xB1, 0xEE, 0xF2, 0xDE, 0x03, 0xF6, 0xC3, 0x2B, 0xE5, 0xBA, 0xA0, 0xFF, 0xE8, 0xA9, 0xA3, 0x81, 0xCB,
0xFB, 0xC8, 0xAF, 0xFD, 0x40, 0xF8, 0x9F, 0x2C, 0xCA, 0x72, 0xF7, 0x8A, 0x04, 0xDD, 0x42, 0x7E, 0x0A, 0xEB, 0x56, 0x55,
0x87, 0x94, 0x29, 0xB4, 0x67, 0x51, 0xDB, 0xB3, 0x8D, 0x04, 0x2C, 0x3F, 0x1B, 0x8F, 0x40, 0x65, 0x50, 0x7D, 0x73, 0x5B,
0x65, 0x51, 0xAA, 0xF1, 0xF0, 0xD9, 0x7B, 0x6D, 0x6F, 0x83, 0x21, 0x70, 0x55, 0xC3, 0xD1, 0x30, 0xB6, 0x0B, 0x48, 0x76,
0x41, 0x21, 0xE8, 0xBE, 0xD8, 0x76, 0x54, 0x84, 0x63, 0x67, 0x0F, 0x1F, 0x62, 0x62, 0xED, 0x9C, 0x0E, 0x14, 0x3D, 0x93,
0x45, 0x5F, 0x99, 0x87, 0xF6, 0x3A, 0xD7, 0x43, 0xFB, 0x70, 0x14, 0x38, 0xBD, 0x9D, 0x35, 0x9A, 0x71, 0x00, 0x12, 0x00,
0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2B, 0x00, 0x29, 0x3A, 0x3A, 0x00, 0x01,
0x00, 0x00, 0x1D, 0x00, 0x20, 0x91, 0xA6, 0x05, 0x9B, 0xC6, 0x4C, 0xD9, 0xAF, 0x57, 0xDF, 0x92, 0xBB, 0xEF, 0xF3, 0x4C,
0x6B, 0x9B, 0xD2, 0x06, 0xCA, 0xFC, 0x24, 0xBB, 0x90, 0xE7, 0x48, 0x04, 0xA8, 0x0D, 0x61, 0x46, 0x2F, 0x00, 0x2D, 0x00,
0x02, 0x01, 0x01, 0x0A, 0x0A, 0x00, 0x01, 0x00,
}

output, err := concatenateTlsRecordsFragments(input)
require.NoError(t, err)
require.NotEqual(t, output, nil)

hello := output[5:]
helloMsg := utls.UnmarshalClientHello(hello)
require.NotEqual(t, helloMsg, nil)
require.NotEqual(t, len(helloMsg.SessionTicket), 0)
require.Equal(t, helloMsg.ServerName, "kaigai-antenna.com")
require.Equal(t, helloMsg.AlpnProtocols, []string{"h2", "http/1.1"})
}

func TestConcatenateTlsRecordsFourFragments(t *testing.T) {
// The input consists of 4 TLS records fragments
input := []byte{
// 1st header
0x16, 0x03, 0x01, 0x00, 0x03,
// 1st payload
0x01, 0x00, 0x02,
// 2nd header
0x16, 0x03, 0x01, 0x00, 0x14,
// 2nd payload
0xCA, 0x03, 0x03, 0x22, 0x7A, 0x33, 0xB1, 0x2A, 0xD4, 0x39, 0x1B, 0x85, 0x96, 0xF7, 0x4B, 0xE5, 0x56, 0x54, 0x95, 0x72,
// 3rd header
0x16, 0x03, 0x01, 0x00, 0x2D,
// 3rd payload
0x3D, 0x95, 0xA1, 0x68, 0x5B, 0x14, 0x83,
0x67, 0xCA, 0x65, 0xEA, 0xD7, 0x3C, 0xCF, 0x71, 0x20, 0x82, 0xEA, 0xB3, 0x93, 0xB0, 0x08, 0x8B, 0x51, 0x0D, 0x6E, 0x13,
0xDE, 0xB2, 0x0A, 0xF0, 0x8F, 0x35, 0xB9, 0x6C, 0xA1, 0x1F, 0x81, 0x09, 0x2D, 0x05, 0x8A, 0xCA, 0x94, 0x46,
// 4th header
0x16, 0x03, 0x01, 0x02, 0x8A,
// 4th payload
0x2B, 0xFF,
0xCB, 0x00, 0x20, 0x8A, 0x8A, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xC0, 0x2B, 0xC0, 0x2F, 0xC0, 0x2C, 0xC0, 0x30, 0xCC,
0xA9, 0xCC, 0xA8, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x2F, 0x00, 0x35, 0x01, 0x00, 0x02, 0x61, 0xEA,
0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x12, 0x6B, 0x61, 0x69, 0x67, 0x61, 0x69, 0x2D, 0x61,
0x6E, 0x74, 0x65, 0x6E, 0x6E, 0x61, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x08, 0x3A, 0x3A, 0x00, 0x1D,
0x00, 0x17, 0x00, 0x18, 0xFE, 0x0D, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x01, 0xED, 0x00, 0x20, 0xF7, 0x1A, 0x41, 0x75,
0xF2, 0x4A, 0xE3, 0x96, 0x59, 0xA2, 0x82, 0x10, 0xD0, 0x14, 0x60, 0x75, 0x95, 0x96, 0xA4, 0x80, 0x55, 0x47, 0x17, 0x7F,
0x19, 0x6F, 0x9C, 0x2A, 0x3B, 0xF3, 0xBD, 0x49, 0x00, 0xF0, 0x63, 0xEC, 0x1C, 0x81, 0xCD, 0x92, 0x45, 0x25, 0x1C, 0x12,
0x2B, 0xD5, 0xED, 0xC9, 0x44, 0xE5, 0xE4, 0x5B, 0x79, 0xA5, 0x02, 0x95, 0x84, 0xE4, 0x40, 0x03, 0xD3, 0x5B, 0x45, 0xA7,
0x02, 0xAF, 0xBD, 0xA3, 0xBB, 0x3A, 0xF4, 0xAB, 0xCF, 0x0B, 0xAD, 0xDD, 0x86, 0x95, 0x70, 0xF5, 0xEC, 0x3C, 0x92, 0x86,
0x7E, 0x01, 0x39, 0xF0, 0x6A, 0x97, 0xAC, 0x38, 0xAA, 0x95, 0x7D, 0xB2, 0x87, 0xE7, 0xDD, 0x14, 0xFA, 0xA4, 0xF6, 0x65,
0xE7, 0xF3, 0x96, 0xFC, 0xD6, 0x4A, 0x57, 0xEF, 0xCA, 0x60, 0x05, 0x69, 0x9D, 0x4F, 0x48, 0x39, 0xF8, 0x11, 0x42, 0x5E,
0x36, 0xA7, 0x1D, 0x4A, 0xA6, 0x19, 0x59, 0x0D, 0x4E, 0x11, 0x26, 0xFC, 0x38, 0x1F, 0xFC, 0x1F, 0x93, 0xFD, 0x08, 0xEF,
0x31, 0x46, 0xB9, 0x2B, 0x9A, 0x38, 0x7D, 0x97, 0x9F, 0xF5, 0xCD, 0x17, 0x7B, 0x54, 0x6F, 0xF0, 0x95, 0x9A, 0x5B, 0x90,
0x38, 0xFF, 0xDD, 0xE9, 0xEC, 0xD8, 0x57, 0x97, 0xB7, 0x3E, 0xC7, 0xDA, 0xFA, 0x2A, 0x4D, 0xBF, 0x47, 0x4F, 0x3C, 0x74,
0x94, 0xD7, 0x5C, 0x38, 0xD4, 0xE0, 0xC6, 0x0C, 0xAC, 0x32, 0x01, 0x26, 0x87, 0x40, 0x3D, 0xA0, 0xE3, 0x63, 0x3D, 0x93,
0x37, 0x49, 0x33, 0x95, 0x67, 0x07, 0xC9, 0x18, 0x4F, 0x69, 0xF4, 0x67, 0x33, 0xAF, 0xB6, 0x5B, 0xF5, 0x0D, 0x85, 0x7A,
0x5A, 0x19, 0xD2, 0xFB, 0xBF, 0xAF, 0xB1, 0xC6, 0x76, 0x4B, 0xD6, 0x36, 0x94, 0xB9, 0x77, 0xDC, 0x85, 0x50, 0x7E, 0xE4,
0x74, 0x4C, 0x27, 0x00, 0x44, 0x06, 0x2B, 0xB0, 0xC6, 0xE6, 0xBA, 0x9C, 0x6B, 0x5E, 0x23, 0x8F, 0x2C, 0xD0, 0xA6, 0x90,
0x0F, 0x75, 0x13, 0x0F, 0x7E, 0x10, 0x8E, 0x69, 0xA5, 0x4A, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x07, 0x06, 0xFA,
0xFA, 0x03, 0x04, 0x03, 0x03, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
0x00, 0x10, 0x00, 0x0E, 0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31, 0xFF, 0x01,
0x00, 0x01, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x02, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04,
0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x23, 0x00, 0x79, 0x87, 0xE8, 0xF7, 0x2A,
0x06, 0x71, 0x97, 0xB1, 0xEE, 0xF2, 0xDE, 0x03, 0xF6, 0xC3, 0x2B, 0xE5, 0xBA, 0xA0, 0xFF, 0xE8, 0xA9, 0xA3, 0x81, 0xCB,
0xFB, 0xC8, 0xAF, 0xFD, 0x40, 0xF8, 0x9F, 0x2C, 0xCA, 0x72, 0xF7, 0x8A, 0x04, 0xDD, 0x42, 0x7E, 0x0A, 0xEB, 0x56, 0x55,
0x87, 0x94, 0x29, 0xB4, 0x67, 0x51, 0xDB, 0xB3, 0x8D, 0x04, 0x2C, 0x3F, 0x1B, 0x8F, 0x40, 0x65, 0x50, 0x7D, 0x73, 0x5B,
0x65, 0x51, 0xAA, 0xF1, 0xF0, 0xD9, 0x7B, 0x6D, 0x6F, 0x83, 0x21, 0x70, 0x55, 0xC3, 0xD1, 0x30, 0xB6, 0x0B, 0x48, 0x76,
0x41, 0x21, 0xE8, 0xBE, 0xD8, 0x76, 0x54, 0x84, 0x63, 0x67, 0x0F, 0x1F, 0x62, 0x62, 0xED, 0x9C, 0x0E, 0x14, 0x3D, 0x93,
0x45, 0x5F, 0x99, 0x87, 0xF6, 0x3A, 0xD7, 0x43, 0xFB, 0x70, 0x14, 0x38, 0xBD, 0x9D, 0x35, 0x9A, 0x71, 0x00, 0x12, 0x00,
0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2B, 0x00, 0x29, 0x3A, 0x3A, 0x00, 0x01,
0x00, 0x00, 0x1D, 0x00, 0x20, 0x91, 0xA6, 0x05, 0x9B, 0xC6, 0x4C, 0xD9, 0xAF, 0x57, 0xDF, 0x92, 0xBB, 0xEF, 0xF3, 0x4C,
0x6B, 0x9B, 0xD2, 0x06, 0xCA, 0xFC, 0x24, 0xBB, 0x90, 0xE7, 0x48, 0x04, 0xA8, 0x0D, 0x61, 0x46, 0x2F, 0x00, 0x2D, 0x00,
0x02, 0x01, 0x01, 0x0A, 0x0A, 0x00, 0x01, 0x00,
}

output, err := concatenateTlsRecordsFragments(input)
require.NoError(t, err)
require.NotEqual(t, output, nil)

hello := output[5:]
helloMsg := utls.UnmarshalClientHello(hello)
require.NotEqual(t, helloMsg, nil)
require.NotEqual(t, len(helloMsg.SessionTicket), 0)
require.Equal(t, helloMsg.ServerName, "kaigai-antenna.com")
require.Equal(t, helloMsg.AlpnProtocols, []string{"h2", "http/1.1"})
}

0 comments on commit 2dbc90c

Please sign in to comment.