1// 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} 209