github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/tls/handshake_extensions.go (about) 1 package tls 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 type NullExtension struct { 9 } 10 11 func (e *NullExtension) WriteToConfig(c *Config) error { 12 return nil 13 } 14 15 func (e *NullExtension) CheckImplemented() error { 16 return nil 17 } 18 19 func (e *NullExtension) Marshal() []byte { 20 return []byte{} 21 } 22 23 type SNIExtension struct { 24 Domains []string 25 Autopopulate bool 26 } 27 28 func (e *SNIExtension) WriteToConfig(c *Config) error { 29 if e.Autopopulate { 30 for i, ext := range c.ClientFingerprintConfiguration.Extensions { 31 switch ext.(type) { 32 case *SNIExtension: 33 if c.ServerName == "" { 34 c.ClientFingerprintConfiguration.Extensions[i] = &NullExtension{} 35 } else { 36 c.ClientFingerprintConfiguration.Extensions[i] = &SNIExtension{ 37 Domains: []string{c.ServerName}, 38 Autopopulate: true, 39 } 40 } 41 default: 42 continue 43 } 44 } 45 } 46 // If a server name is not specified in the config, but is available in the extensions 47 // we set it for certificate validation later on 48 if c.ServerName == "" && len(e.Domains) > 0 { 49 c.ServerName = e.Domains[0] 50 } 51 return nil 52 } 53 54 func (e *SNIExtension) CheckImplemented() error { 55 return nil 56 } 57 58 func (e *SNIExtension) Marshal() []byte { 59 result := []byte{} 60 for _, domain := range e.Domains { 61 current := make([]byte, 2+len(domain)) 62 copy(current[2:], []byte(domain)) 63 current[0] = uint8(len(domain) >> 8) 64 current[1] = uint8(len(domain)) 65 result = append(result, current...) 66 } 67 sniHeader := make([]byte, 3) 68 sniHeader[0] = uint8((len(result) + 1) >> 8) 69 sniHeader[1] = uint8((len(result) + 1)) 70 sniHeader[2] = 0 71 result = append(sniHeader, result...) 72 73 extHeader := make([]byte, 4) 74 extHeader[0] = 0 75 extHeader[1] = 0 76 extHeader[2] = uint8((len(result)) >> 8) 77 extHeader[3] = uint8((len(result))) 78 result = append(extHeader, result...) 79 80 return result 81 } 82 83 type ALPNExtension struct { 84 Protocols []string 85 } 86 87 func (e *ALPNExtension) WriteToConfig(c *Config) error { 88 c.NextProtos = e.Protocols 89 return nil 90 } 91 92 func (e *ALPNExtension) CheckImplemented() error { 93 return nil 94 } 95 96 func (e *ALPNExtension) Marshal() []byte { 97 result := []byte{} 98 for _, protocol := range e.Protocols { 99 current := make([]byte, 1+len(protocol)) 100 copy(current[1:], []byte(protocol)) 101 current[0] = uint8(len(protocol)) 102 result = append(result, current...) 103 } 104 alpnHeader := make([]byte, 2) 105 alpnHeader[0] = uint8((len(result)) >> 8) 106 alpnHeader[1] = uint8((len(result))) 107 result = append(alpnHeader, result...) 108 109 extHeader := make([]byte, 4) 110 extHeader[0] = byte(extensionALPN >> 8) 111 extHeader[1] = byte(extensionALPN & 0xff) 112 extHeader[2] = uint8((len(result)) >> 8) 113 extHeader[3] = uint8((len(result))) 114 result = append(extHeader, result...) 115 116 return result 117 } 118 119 type SecureRenegotiationExtension struct { 120 } 121 122 func (e *SecureRenegotiationExtension) WriteToConfig(c *Config) error { 123 return nil 124 } 125 126 func (e *SecureRenegotiationExtension) CheckImplemented() error { 127 return nil 128 } 129 130 func (e *SecureRenegotiationExtension) Marshal() []byte { 131 result := make([]byte, 5) 132 result[0] = byte(extensionRenegotiationInfo >> 8) 133 result[1] = byte(extensionRenegotiationInfo & 0xff) 134 result[2] = 0 135 result[3] = 1 136 result[4] = 0 137 return result 138 } 139 140 type ExtendedMasterSecretExtension struct { 141 } 142 143 func (e *ExtendedMasterSecretExtension) WriteToConfig(c *Config) error { 144 c.ExtendedMasterSecret = true 145 return nil 146 } 147 148 func (e *ExtendedMasterSecretExtension) CheckImplemented() error { 149 return nil 150 } 151 152 func (e *ExtendedMasterSecretExtension) Marshal() []byte { 153 result := make([]byte, 4) 154 result[0] = byte(extensionExtendedMasterSecret >> 8) 155 result[1] = byte(extensionExtendedMasterSecret & 0xff) 156 result[2] = 0 157 result[3] = 0 158 return result 159 } 160 161 type NextProtocolNegotiationExtension struct { 162 Protocols []string 163 } 164 165 func (e *NextProtocolNegotiationExtension) WriteToConfig(c *Config) error { 166 c.NextProtos = e.Protocols 167 return nil 168 } 169 170 func (e *NextProtocolNegotiationExtension) CheckImplemented() error { 171 return nil 172 } 173 174 func (e *NextProtocolNegotiationExtension) Marshal() []byte { 175 result := make([]byte, 4) 176 result[0] = byte(extensionNextProtoNeg >> 8) 177 result[1] = byte(extensionNextProtoNeg & 0xff) 178 result[2] = 0 179 result[3] = 0 180 return result 181 } 182 183 type StatusRequestExtension struct { 184 } 185 186 func (e *StatusRequestExtension) WriteToConfig(c *Config) error { 187 return nil 188 } 189 190 func (e *StatusRequestExtension) CheckImplemented() error { 191 return nil 192 } 193 194 func (e *StatusRequestExtension) Marshal() []byte { 195 result := make([]byte, 9) 196 result[0] = byte(extensionStatusRequest >> 8) 197 result[1] = byte(extensionStatusRequest & 0xff) 198 result[2] = 0 199 result[3] = 5 200 result[4] = 1 // OCSP type 201 result[5] = 0 202 result[6] = 0 203 result[7] = 0 204 result[8] = 0 205 return result 206 } 207 208 type SCTExtension struct { 209 } 210 211 func (e *SCTExtension) WriteToConfig(c *Config) error { 212 c.SignedCertificateTimestampExt = true 213 return nil 214 } 215 216 func (e *SCTExtension) CheckImplemented() error { 217 return nil 218 } 219 220 func (e *SCTExtension) Marshal() []byte { 221 result := make([]byte, 4) 222 result[0] = byte(extensionSCT >> 8) 223 result[1] = byte(extensionSCT & 0xff) 224 result[2] = 0 225 result[3] = 0 226 return result 227 } 228 229 type SupportedCurvesExtension struct { 230 Curves []CurveID 231 } 232 233 func (e *SupportedCurvesExtension) WriteToConfig(c *Config) error { 234 c.CurvePreferences = e.Curves 235 return nil 236 } 237 238 func (e *SupportedCurvesExtension) CheckImplemented() error { 239 for _, curve := range e.Curves { 240 found := false 241 for _, supported := range defaultCurvePreferences { 242 if curve == supported { 243 found = true 244 } 245 } 246 if !found { 247 return fmt.Errorf("Unsupported CurveID %d", curve) 248 } 249 } 250 return nil 251 } 252 253 func (e *SupportedCurvesExtension) Marshal() []byte { 254 result := make([]byte, 6+2*len(e.Curves)) 255 result[0] = byte(extensionSupportedCurves >> 8) 256 result[1] = byte(extensionSupportedCurves & 0xff) 257 result[2] = uint8((2 + 2*len(e.Curves)) >> 8) 258 result[3] = uint8((2 + 2*len(e.Curves))) 259 result[4] = uint8((2 * len(e.Curves)) >> 8) 260 result[5] = uint8((2 * len(e.Curves))) 261 for i, curve := range e.Curves { 262 result[6+2*i] = uint8(curve >> 8) 263 result[7+2*i] = uint8(curve) 264 } 265 return result 266 } 267 268 type PointFormatExtension struct { 269 Formats []uint8 270 } 271 272 func (e *PointFormatExtension) WriteToConfig(c *Config) error { 273 return nil 274 } 275 276 func (e *PointFormatExtension) CheckImplemented() error { 277 for _, format := range e.Formats { 278 if format != pointFormatUncompressed { 279 return fmt.Errorf("Unsupported EC Point Format %d", format) 280 } 281 } 282 return nil 283 } 284 285 func (e *PointFormatExtension) Marshal() []byte { 286 result := make([]byte, 5+len(e.Formats)) 287 result[0] = byte(extensionSupportedPoints >> 8) 288 result[1] = byte(extensionSupportedPoints & 0xff) 289 result[2] = uint8((1 + len(e.Formats)) >> 8) 290 result[3] = uint8((1 + len(e.Formats))) 291 result[4] = uint8((len(e.Formats))) 292 for i, format := range e.Formats { 293 result[5+i] = format 294 } 295 return result 296 } 297 298 type SessionTicketExtension struct { 299 Ticket []byte 300 Autopopulate bool 301 } 302 303 func (e *SessionTicketExtension) WriteToConfig(c *Config) error { 304 c.ForceSessionTicketExt = true 305 return nil 306 } 307 308 func (e *SessionTicketExtension) CheckImplemented() error { 309 return nil 310 } 311 312 func (e *SessionTicketExtension) Marshal() []byte { 313 result := make([]byte, 4+len(e.Ticket)) 314 result[0] = byte(extensionSessionTicket >> 8) 315 result[1] = byte(extensionSessionTicket & 0xff) 316 result[2] = uint8(len(e.Ticket) >> 8) 317 result[3] = uint8(len(e.Ticket)) 318 if len(e.Ticket) > 0 { 319 copy(result[4:], e.Ticket) 320 } 321 return result 322 } 323 324 type HeartbeatExtension struct { 325 Mode byte 326 } 327 328 func (e *HeartbeatExtension) WriteToConfig(c *Config) error { 329 return nil 330 } 331 332 func (e *HeartbeatExtension) CheckImplemented() error { 333 return nil 334 } 335 336 func (e *HeartbeatExtension) Marshal() []byte { 337 result := make([]byte, 5) 338 result[0] = byte(extensionHeartbeat >> 8) 339 result[1] = byte(extensionHeartbeat & 0xff) 340 result[2] = uint8(1 >> 8) 341 result[3] = uint8(1) 342 result[4] = e.Mode 343 return result 344 } 345 346 type SignatureAlgorithmExtension struct { 347 SignatureAndHashes []uint16 348 } 349 350 func (e *SignatureAlgorithmExtension) WriteToConfig(c *Config) error { 351 c.SignatureAndHashes = e.getStructuredAlgorithms() 352 return nil 353 } 354 355 func (e *SignatureAlgorithmExtension) CheckImplemented() error { 356 for _, algs := range e.getStructuredAlgorithms() { 357 found := false 358 for _, supported := range supportedSKXSignatureAlgorithms { 359 if algs.Hash == supported.Hash && algs.Signature == supported.Signature { 360 found = true 361 break 362 } 363 } 364 if !found { 365 return errors.New(fmt.Sprintf("Unsupported Hash and Signature Algorithm (%d, %d)", algs.Hash, algs.Signature)) 366 } 367 } 368 return nil 369 } 370 371 func (e *SignatureAlgorithmExtension) getStructuredAlgorithms() []SigAndHash { 372 result := make([]SigAndHash, len(e.SignatureAndHashes)) 373 for i, alg := range e.SignatureAndHashes { 374 result[i].Hash = uint8(alg >> 8) 375 result[i].Signature = uint8(alg) 376 } 377 return result 378 } 379 380 func (e *SignatureAlgorithmExtension) Marshal() []byte { 381 result := make([]byte, 6+2*len(e.SignatureAndHashes)) 382 result[0] = byte(extensionSignatureAlgorithms >> 8) 383 result[1] = byte(extensionSignatureAlgorithms & 0xff) 384 result[2] = uint8((2 + 2*len(e.SignatureAndHashes)) >> 8) 385 result[3] = uint8((2 + 2*len(e.SignatureAndHashes))) 386 result[4] = uint8((2 * len(e.SignatureAndHashes)) >> 8) 387 result[5] = uint8((2 * len(e.SignatureAndHashes))) 388 for i, pair := range e.getStructuredAlgorithms() { 389 result[6+2*i] = uint8(pair.Hash) 390 result[7+2*i] = uint8(pair.Signature) 391 } 392 return result 393 }