blob: ddb6ff9d290e58e83057377d4973ffb0dc3e1407 [file] [log] [blame]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001// Copyright 2018 The GoPacket Authors. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree.
6
7package layers
8
9import (
10 "encoding/binary"
11 "errors"
12
13 "github.com/google/gopacket"
14)
15
16// TLSType defines the type of data after the TLS Record
17type TLSType uint8
18
19// TLSType known values.
20const (
21 TLSChangeCipherSpec TLSType = 20
22 TLSAlert TLSType = 21
23 TLSHandshake TLSType = 22
24 TLSApplicationData TLSType = 23
25 TLSUnknown TLSType = 255
26)
27
28// String shows the register type nicely formatted
29func (tt TLSType) String() string {
30 switch tt {
31 default:
32 return "Unknown"
33 case TLSChangeCipherSpec:
34 return "Change Cipher Spec"
35 case TLSAlert:
36 return "Alert"
37 case TLSHandshake:
38 return "Handshake"
39 case TLSApplicationData:
40 return "Application Data"
41 }
42}
43
44// TLSVersion represents the TLS version in numeric format
45type TLSVersion uint16
46
47// Strings shows the TLS version nicely formatted
48func (tv TLSVersion) String() string {
49 switch tv {
50 default:
51 return "Unknown"
52 case 0x0200:
53 return "SSL 2.0"
54 case 0x0300:
55 return "SSL 3.0"
56 case 0x0301:
57 return "TLS 1.0"
58 case 0x0302:
59 return "TLS 1.1"
60 case 0x0303:
61 return "TLS 1.2"
62 case 0x0304:
63 return "TLS 1.3"
64 }
65}
66
67// TLS is specified in RFC 5246
68//
69// TLS Record Protocol
70// 0 1 2 3 4 5 6 7 8
71// +--+--+--+--+--+--+--+--+
72// | Content Type |
73// +--+--+--+--+--+--+--+--+
74// | Version (major) |
75// +--+--+--+--+--+--+--+--+
76// | Version (minor) |
77// +--+--+--+--+--+--+--+--+
78// | Length |
79// +--+--+--+--+--+--+--+--+
80// | Length |
81// +--+--+--+--+--+--+--+--+
82
83// TLS is actually a slide of TLSrecord structures
84type TLS struct {
85 BaseLayer
86
87 // TLS Records
88 ChangeCipherSpec []TLSChangeCipherSpecRecord
89 Handshake []TLSHandshakeRecord
90 AppData []TLSAppDataRecord
91 Alert []TLSAlertRecord
92}
93
94// TLSRecordHeader contains all the information that each TLS Record types should have
95type TLSRecordHeader struct {
96 ContentType TLSType
97 Version TLSVersion
98 Length uint16
99}
100
101// LayerType returns gopacket.LayerTypeTLS.
102func (t *TLS) LayerType() gopacket.LayerType { return LayerTypeTLS }
103
104// decodeTLS decodes the byte slice into a TLS type. It also
105// setups the application Layer in PacketBuilder.
106func decodeTLS(data []byte, p gopacket.PacketBuilder) error {
107 t := &TLS{}
108 err := t.DecodeFromBytes(data, p)
109 if err != nil {
110 return err
111 }
112 p.AddLayer(t)
113 p.SetApplicationLayer(t)
114 return nil
115}
116
117// DecodeFromBytes decodes the slice into the TLS struct.
118func (t *TLS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
119 t.BaseLayer.Contents = data
120 t.BaseLayer.Payload = nil
121
122 t.ChangeCipherSpec = t.ChangeCipherSpec[:0]
123 t.Handshake = t.Handshake[:0]
124 t.AppData = t.AppData[:0]
125 t.Alert = t.Alert[:0]
126
127 return t.decodeTLSRecords(data, df)
128}
129
130func (t *TLS) decodeTLSRecords(data []byte, df gopacket.DecodeFeedback) error {
131 if len(data) < 5 {
132 df.SetTruncated()
133 return errors.New("TLS record too short")
134 }
135
136 // since there are no further layers, the baselayer's content is
137 // pointing to this layer
138 t.BaseLayer = BaseLayer{Contents: data[:len(data)]}
139
140 var h TLSRecordHeader
141 h.ContentType = TLSType(data[0])
142 h.Version = TLSVersion(binary.BigEndian.Uint16(data[1:3]))
143 h.Length = binary.BigEndian.Uint16(data[3:5])
144
145 if h.ContentType.String() == "Unknown" {
146 return errors.New("Unknown TLS record type")
147 }
148
149 hl := 5 // header length
150 tl := hl + int(h.Length)
151 if len(data) < tl {
152 df.SetTruncated()
153 return errors.New("TLS packet length mismatch")
154 }
155
156 switch h.ContentType {
157 default:
158 return errors.New("Unknown TLS record type")
159 case TLSChangeCipherSpec:
160 var r TLSChangeCipherSpecRecord
161 e := r.decodeFromBytes(h, data[hl:tl], df)
162 if e != nil {
163 return e
164 }
165 t.ChangeCipherSpec = append(t.ChangeCipherSpec, r)
166 case TLSAlert:
167 var r TLSAlertRecord
168 e := r.decodeFromBytes(h, data[hl:tl], df)
169 if e != nil {
170 return e
171 }
172 t.Alert = append(t.Alert, r)
173 case TLSHandshake:
174 var r TLSHandshakeRecord
175 e := r.decodeFromBytes(h, data[hl:tl], df)
176 if e != nil {
177 return e
178 }
179 t.Handshake = append(t.Handshake, r)
180 case TLSApplicationData:
181 var r TLSAppDataRecord
182 e := r.decodeFromBytes(h, data[hl:tl], df)
183 if e != nil {
184 return e
185 }
186 t.AppData = append(t.AppData, r)
187 }
188
189 if len(data) == tl {
190 return nil
191 }
192 return t.decodeTLSRecords(data[tl:len(data)], df)
193}
194
195// CanDecode implements gopacket.DecodingLayer.
196func (t *TLS) CanDecode() gopacket.LayerClass {
197 return LayerTypeTLS
198}
199
200// NextLayerType implements gopacket.DecodingLayer.
201func (t *TLS) NextLayerType() gopacket.LayerType {
202 return gopacket.LayerTypeZero
203}
204
205// Payload returns nil, since TLS encrypted payload is inside TLSAppDataRecord
206func (t *TLS) Payload() []byte {
207 return nil
208}