github.com/gopacket/gopacket@v1.1.0/layers/tls.go (about) 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 7 package layers 8 9 import ( 10 "encoding/binary" 11 "errors" 12 13 "github.com/gopacket/gopacket" 14 ) 15 16 // TLSType defines the type of data after the TLS Record 17 type TLSType uint8 18 19 // TLSType known values. 20 const ( 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 29 func (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 45 type TLSVersion uint16 46 47 // Strings shows the TLS version nicely formatted 48 func (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 84 type 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 95 type TLSRecordHeader struct { 96 ContentType TLSType 97 Version TLSVersion 98 Length uint16 99 } 100 101 // LayerType returns gopacket.LayerTypeTLS. 102 func (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. 106 func 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. 118 func (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 130 func (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 // TODO: Consider removing this 139 t.BaseLayer = BaseLayer{Contents: data[:len(data)]} 140 141 var h TLSRecordHeader 142 h.ContentType = TLSType(data[0]) 143 h.Version = TLSVersion(binary.BigEndian.Uint16(data[1:3])) 144 h.Length = binary.BigEndian.Uint16(data[3:5]) 145 146 if h.ContentType.String() == "Unknown" { 147 return errors.New("Unknown TLS record type") 148 } 149 150 hl := 5 // header length 151 tl := hl + int(h.Length) 152 if len(data) < tl { 153 df.SetTruncated() 154 return errors.New("TLS packet length mismatch") 155 } 156 157 switch h.ContentType { 158 default: 159 return errors.New("Unknown TLS record type") 160 case TLSChangeCipherSpec: 161 var r TLSChangeCipherSpecRecord 162 e := r.decodeFromBytes(h, data[hl:tl], df) 163 if e != nil { 164 return e 165 } 166 t.ChangeCipherSpec = append(t.ChangeCipherSpec, r) 167 case TLSAlert: 168 var r TLSAlertRecord 169 e := r.decodeFromBytes(h, data[hl:tl], df) 170 if e != nil { 171 return e 172 } 173 t.Alert = append(t.Alert, r) 174 case TLSHandshake: 175 var r TLSHandshakeRecord 176 e := r.decodeFromBytes(h, data[hl:tl], df) 177 if e != nil { 178 return e 179 } 180 t.Handshake = append(t.Handshake, r) 181 case TLSApplicationData: 182 var r TLSAppDataRecord 183 e := r.decodeFromBytes(h, data[hl:tl], df) 184 if e != nil { 185 return e 186 } 187 t.AppData = append(t.AppData, r) 188 } 189 190 if len(data) == tl { 191 return nil 192 } 193 return t.decodeTLSRecords(data[tl:len(data)], df) 194 } 195 196 // CanDecode implements gopacket.DecodingLayer. 197 func (t *TLS) CanDecode() gopacket.LayerClass { 198 return LayerTypeTLS 199 } 200 201 // NextLayerType implements gopacket.DecodingLayer. 202 func (t *TLS) NextLayerType() gopacket.LayerType { 203 return gopacket.LayerTypeZero 204 } 205 206 // Payload returns nil, since TLS encrypted payload is inside TLSAppDataRecord 207 func (t *TLS) Payload() []byte { 208 return nil 209 } 210 211 // SerializeTo writes the serialized form of this layer into the 212 // SerializationBuffer, implementing gopacket.SerializableLayer. 213 func (t *TLS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 214 totalLength := 0 215 for _, record := range t.ChangeCipherSpec { 216 if opts.FixLengths { 217 record.Length = 1 218 } 219 totalLength += 5 + 1 // length of header + record 220 } 221 for range t.Handshake { 222 totalLength += 5 223 // TODO 224 } 225 for _, record := range t.AppData { 226 if opts.FixLengths { 227 record.Length = uint16(len(record.Payload)) 228 } 229 totalLength += 5 + len(record.Payload) 230 } 231 for _, record := range t.Alert { 232 if len(record.EncryptedMsg) == 0 { 233 if opts.FixLengths { 234 record.Length = 2 235 } 236 totalLength += 5 + 2 237 } else { 238 if opts.FixLengths { 239 record.Length = uint16(len(record.EncryptedMsg)) 240 } 241 totalLength += 5 + len(record.EncryptedMsg) 242 } 243 } 244 data, err := b.PrependBytes(totalLength) 245 if err != nil { 246 return err 247 } 248 off := 0 249 for _, record := range t.ChangeCipherSpec { 250 off = encodeHeader(record.TLSRecordHeader, data, off) 251 data[off] = byte(record.Message) 252 off++ 253 } 254 for _, record := range t.Handshake { 255 off = encodeHeader(record.TLSRecordHeader, data, off) 256 // TODO 257 } 258 for _, record := range t.AppData { 259 off = encodeHeader(record.TLSRecordHeader, data, off) 260 copy(data[off:], record.Payload) 261 off += len(record.Payload) 262 } 263 for _, record := range t.Alert { 264 off = encodeHeader(record.TLSRecordHeader, data, off) 265 if len(record.EncryptedMsg) == 0 { 266 data[off] = byte(record.Level) 267 data[off+1] = byte(record.Description) 268 off += 2 269 } else { 270 copy(data[off:], record.EncryptedMsg) 271 off += len(record.EncryptedMsg) 272 } 273 } 274 return nil 275 } 276 277 func encodeHeader(header TLSRecordHeader, data []byte, offset int) int { 278 data[offset] = byte(header.ContentType) 279 binary.BigEndian.PutUint16(data[offset+1:], uint16(header.Version)) 280 binary.BigEndian.PutUint16(data[offset+3:], header.Length) 281 282 return offset + 5 283 }