Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion layers/tls_handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,43 @@ package layers
import (
"encoding/binary"
"errors"

"github.com/gopacket/gopacket"
)

// TLS Extensions http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
type TLSExtension uint16

const (
TLSExtServerName TLSExtension = 0
TLSExtMaxFragLen TLSExtension = 1
TLSExtClientCertURL TLSExtension = 2
TLSExtTrustedCAKeys TLSExtension = 3
TLSExtTruncatedHMAC TLSExtension = 4
TLSExtStatusRequest TLSExtension = 5
TLSExtUserMapping TLSExtension = 6
TLSExtClientAuthz TLSExtension = 7
TLSExtServerAuthz TLSExtension = 8
TLSExtCertType TLSExtension = 9
TLSExtSupportedGroups TLSExtension = 10
TLSExtECPointFormats TLSExtension = 11
TLSExtSRP TLSExtension = 12
TLSExtSignatureAlgs TLSExtension = 13
TLSxtUseSRTP TLSExtension = 14
TLSExtHeartbeat TLSExtension = 15
TLSExtALPN TLSExtension = 16
TLSExtStatusRequestV2 TLSExtension = 17
TLSExtSignedCertTS TLSExtension = 18
TLSExtClientCertType TLSExtension = 19
TLSExtServerCertType TLSExtension = 20
TLSExtPadding TLSExtension = 21
TLSExtEncryptThenMAC TLSExtension = 22
TLSExtExtendedMasterSecret TLSExtension = 23
TLSExtSessionTicket TLSExtension = 35
TLSExtNPN TLSExtension = 13172
TLSExtRenegotiationInfo TLSExtension = 65281
)

/*refer to https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.4*/
const (
TLSHandshakeHelloRequest = 0
Expand Down Expand Up @@ -54,6 +88,7 @@ type TLSHandshakeRecordClientHello struct {
CompressionMethods []uint8
ExtensionsLength uint16
Extensions []uint8
SNI []uint8
}

type TLSHandshakeRecordClientKeyChange struct {
Expand Down Expand Up @@ -82,7 +117,35 @@ func (t *TLSHandshakeRecordClientHello) decodeFromBytes(data []byte, df gopacket
t.CompressionMethodsLength = data[(39 + uint16(t.SessionIDLength) + 2 + t.CipherSuitsLength)]
t.CompressionMethods = data[(39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1 : (39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)]
t.ExtensionsLength = binary.BigEndian.Uint16(data[(39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength) : (39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)+2])
t.Extensions = data[((39 + uint16(t.SessionIDLength) + 2 + t.CipherSuitsLength) + 1 + uint16(t.CompressionMethodsLength) + 2) : ((39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)+2)+t.ExtensionsLength]

// extract extension data
data = data[((39 + uint16(t.SessionIDLength) + 2 + t.CipherSuitsLength) + 1 + uint16(t.CompressionMethodsLength) + 2) : ((39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)+2)+t.ExtensionsLength]
t.Extensions = data
for len(data) > 0 {
if len(data) < 4 {
break
}
extensionType := binary.BigEndian.Uint16(data[:2])
length := binary.BigEndian.Uint16(data[2:4])
if len(data) < 4+int(length) {
break
}
switch TLSExtension(extensionType) {
case TLSExtServerName:
if len(data) > 6 {
serverNameExtensionLength := binary.BigEndian.Uint16(data[4:6])
entryType := data[6]
if serverNameExtensionLength > 0 && entryType == 0 && len(data) > 8 { // 0 = DNS hostname
hostnameLength := binary.BigEndian.Uint16(data[7:9])
if len(data) > int(8+hostnameLength) {
t.SNI = data[9 : 9+hostnameLength]
}
}
}
}
data = data[4+length:]
}

return nil
}
func (t *TLSHandshakeRecordClientKeyChange) decodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
Expand Down
13 changes: 8 additions & 5 deletions layers/tls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,17 @@ var testClientHello = []byte{
0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0xc0, 0x12,
0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x12,
0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01,
0x00, 0x00, 0x49, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00,
0x00, 0x00, 0x60, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00,
0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00,
0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00,
0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00,
0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x01,
0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x13,
0x00, 0x11, 0x00, 0x00, 0x0e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x63, 0x6f, 0x6d,
}
var testClientHelloDecoded = &TLS{
BaseLayer: BaseLayer{
Contents: testClientHello[54:],
Contents: testClientHello[54:268],
Payload: nil,
},
ChangeCipherSpec: nil,
Expand All @@ -58,8 +60,9 @@ var testClientHelloDecoded = &TLS{
CipherSuits: []uint8{0xc0, 0x14, 0xc0, 0xa, 0x0, 0x39, 0x0, 0x38, 0x0, 0x88, 0x0, 0x87, 0xc0, 0xf, 0xc0, 0x5, 0x0, 0x35, 0x0, 0x84, 0xc0, 0x13, 0xc0, 0x9, 0x0, 0x33, 0x0, 0x32, 0x0, 0x9a, 0x0, 0x99, 0x0, 0x45, 0x0, 0x44, 0xc0, 0xe, 0xc0, 0x4, 0x0, 0x2f, 0x0, 0x96, 0x0, 0x41, 0xc0, 0x11, 0xc0, 0x7, 0xc0, 0xc, 0xc0, 0x2, 0x0, 0x5, 0x0, 0x4, 0xc0, 0x12, 0xc0, 0x8, 0x0, 0x16, 0x0, 0x13, 0xc0, 0xd, 0xc0, 0x3, 0x0, 0xa, 0x0, 0x15, 0x0, 0x12, 0x0, 0x9, 0x0, 0x14, 0x0, 0x11, 0x0, 0x8, 0x0, 0x6, 0x0, 0x3, 0x0, 0xff},
CompressionMethodsLength: 0x2,
CompressionMethods: []uint8{0x1, 0x0},
ExtensionsLength: 0x49,
Extensions: []uint8{0x0, 0xb, 0x0, 0x4, 0x3, 0x0, 0x1, 0x2, 0x0, 0xa, 0x0, 0x34, 0x0, 0x32, 0x0, 0xe, 0x0, 0xd, 0x0, 0x19, 0x0, 0xb, 0x0, 0xc, 0x0, 0x18, 0x0, 0x9, 0x0, 0xa, 0x0, 0x16, 0x0, 0x17, 0x0, 0x8, 0x0, 0x6, 0x0, 0x7, 0x0, 0x14, 0x0, 0x15, 0x0, 0x4, 0x0, 0x5, 0x0, 0x12, 0x0, 0x13, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0xf, 0x0, 0x10, 0x0, 0x11, 0x0, 0x23, 0x0, 0x0, 0x0, 0xf, 0x0, 0x1, 0x1},
ExtensionsLength: 0x60,
Extensions: []uint8{0x0, 0xb, 0x0, 0x4, 0x3, 0x0, 0x1, 0x2, 0x0, 0xa, 0x0, 0x34, 0x0, 0x32, 0x0, 0xe, 0x0, 0xd, 0x0, 0x19, 0x0, 0xb, 0x0, 0xc, 0x0, 0x18, 0x0, 0x9, 0x0, 0xa, 0x0, 0x16, 0x0, 0x17, 0x0, 0x8, 0x0, 0x6, 0x0, 0x7, 0x0, 0x14, 0x0, 0x15, 0x0, 0x4, 0x0, 0x5, 0x0, 0x12, 0x0, 0x13, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0xf, 0x0, 0x10, 0x0, 0x11, 0x0, 0x23, 0x0, 0x0, 0x0, 0xf, 0x0, 0x1, 0x1, 0x00, 0x00, 0x00, 0x13, 0x00, 0x11, 0x00, 0x00, 0x0e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d},
SNI: []uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d},
},
},
},
Expand Down