github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/crypto/tls/common.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "container/list" 9 "crypto" 10 "crypto/rand" 11 "crypto/x509" 12 "fmt" 13 "io" 14 "math/big" 15 "strings" 16 "sync" 17 "time" 18 ) 19 20 const ( 21 VersionSSL30 = 0x0300 22 VersionTLS10 = 0x0301 23 VersionTLS11 = 0x0302 24 VersionTLS12 = 0x0303 25 ) 26 27 const ( 28 maxPlaintext = 16384 // maximum plaintext payload length 29 maxCiphertext = 16384 + 2048 // maximum ciphertext payload length 30 recordHeaderLen = 5 // record header length 31 maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) 32 33 minVersion = VersionSSL30 34 maxVersion = VersionTLS12 35 ) 36 37 // TLS record types. 38 type recordType uint8 39 40 const ( 41 recordTypeChangeCipherSpec recordType = 20 42 recordTypeAlert recordType = 21 43 recordTypeHandshake recordType = 22 44 recordTypeApplicationData recordType = 23 45 ) 46 47 // TLS handshake message types. 48 const ( 49 typeClientHello uint8 = 1 50 typeServerHello uint8 = 2 51 typeNewSessionTicket uint8 = 4 52 typeCertificate uint8 = 11 53 typeServerKeyExchange uint8 = 12 54 typeCertificateRequest uint8 = 13 55 typeServerHelloDone uint8 = 14 56 typeCertificateVerify uint8 = 15 57 typeClientKeyExchange uint8 = 16 58 typeFinished uint8 = 20 59 typeCertificateStatus uint8 = 22 60 typeNextProtocol uint8 = 67 // Not IANA assigned 61 ) 62 63 // TLS compression types. 64 const ( 65 compressionNone uint8 = 0 66 ) 67 68 // TLS extension numbers 69 const ( 70 extensionServerName uint16 = 0 71 extensionStatusRequest uint16 = 5 72 extensionSupportedCurves uint16 = 10 73 extensionSupportedPoints uint16 = 11 74 extensionSignatureAlgorithms uint16 = 13 75 extensionALPN uint16 = 16 76 extensionSessionTicket uint16 = 35 77 extensionNextProtoNeg uint16 = 13172 // not IANA assigned 78 extensionRenegotiationInfo uint16 = 0xff01 79 ) 80 81 // TLS signaling cipher suite values 82 const ( 83 scsvRenegotiation uint16 = 0x00ff 84 ) 85 86 // CurveID is the type of a TLS identifier for an elliptic curve. See 87 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 88 type CurveID uint16 89 90 const ( 91 CurveP256 CurveID = 23 92 CurveP384 CurveID = 24 93 CurveP521 CurveID = 25 94 ) 95 96 // TLS Elliptic Curve Point Formats 97 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 98 const ( 99 pointFormatUncompressed uint8 = 0 100 ) 101 102 // TLS CertificateStatusType (RFC 3546) 103 const ( 104 statusTypeOCSP uint8 = 1 105 ) 106 107 // Certificate types (for certificateRequestMsg) 108 const ( 109 certTypeRSASign = 1 // A certificate containing an RSA key 110 certTypeDSSSign = 2 // A certificate containing a DSA key 111 certTypeRSAFixedDH = 3 // A certificate containing a static DH key 112 certTypeDSSFixedDH = 4 // A certificate containing a static DH key 113 114 // See RFC4492 sections 3 and 5.5. 115 certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. 116 certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. 117 certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. 118 119 // Rest of these are reserved by the TLS spec 120 ) 121 122 // Hash functions for TLS 1.2 (See RFC 5246, section A.4.1) 123 const ( 124 hashSHA1 uint8 = 2 125 hashSHA256 uint8 = 4 126 ) 127 128 // Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1) 129 const ( 130 signatureRSA uint8 = 1 131 signatureECDSA uint8 = 3 132 ) 133 134 // signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See 135 // RFC 5246, section A.4.1. 136 type signatureAndHash struct { 137 hash, signature uint8 138 } 139 140 // supportedSKXSignatureAlgorithms contains the signature and hash algorithms 141 // that the code advertises as supported in a TLS 1.2 ClientHello. 142 var supportedSKXSignatureAlgorithms = []signatureAndHash{ 143 {hashSHA256, signatureRSA}, 144 {hashSHA256, signatureECDSA}, 145 {hashSHA1, signatureRSA}, 146 {hashSHA1, signatureECDSA}, 147 } 148 149 // supportedClientCertSignatureAlgorithms contains the signature and hash 150 // algorithms that the code advertises as supported in a TLS 1.2 151 // CertificateRequest. 152 var supportedClientCertSignatureAlgorithms = []signatureAndHash{ 153 {hashSHA256, signatureRSA}, 154 {hashSHA256, signatureECDSA}, 155 } 156 157 // ConnectionState records basic TLS details about the connection. 158 type ConnectionState struct { 159 Version uint16 // TLS version used by the connection (e.g. VersionTLS12) 160 HandshakeComplete bool // TLS handshake is complete 161 DidResume bool // connection resumes a previous TLS connection 162 CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...) 163 NegotiatedProtocol string // negotiated next protocol (from Config.NextProtos) 164 NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server 165 ServerName string // server name requested by client, if any (server side only) 166 PeerCertificates []*x509.Certificate // certificate chain presented by remote peer 167 VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates 168 169 // TLSUnique contains the "tls-unique" channel binding value (see RFC 170 // 5929, section 3). For resumed sessions this value will be nil 171 // because resumption does not include enough context (see 172 // https://secure-resumption.com/#channelbindings). This will change in 173 // future versions of Go once the TLS master-secret fix has been 174 // standardized and implemented. 175 TLSUnique []byte 176 } 177 178 // ClientAuthType declares the policy the server will follow for 179 // TLS Client Authentication. 180 type ClientAuthType int 181 182 const ( 183 NoClientCert ClientAuthType = iota 184 RequestClientCert 185 RequireAnyClientCert 186 VerifyClientCertIfGiven 187 RequireAndVerifyClientCert 188 ) 189 190 // ClientSessionState contains the state needed by clients to resume TLS 191 // sessions. 192 type ClientSessionState struct { 193 sessionTicket []uint8 // Encrypted ticket used for session resumption with server 194 vers uint16 // SSL/TLS version negotiated for the session 195 cipherSuite uint16 // Ciphersuite negotiated for the session 196 masterSecret []byte // MasterSecret generated by client on a full handshake 197 serverCertificates []*x509.Certificate // Certificate chain presented by the server 198 } 199 200 // ClientSessionCache is a cache of ClientSessionState objects that can be used 201 // by a client to resume a TLS session with a given server. ClientSessionCache 202 // implementations should expect to be called concurrently from different 203 // goroutines. 204 type ClientSessionCache interface { 205 // Get searches for a ClientSessionState associated with the given key. 206 // On return, ok is true if one was found. 207 Get(sessionKey string) (session *ClientSessionState, ok bool) 208 209 // Put adds the ClientSessionState to the cache with the given key. 210 Put(sessionKey string, cs *ClientSessionState) 211 } 212 213 // ClientHelloInfo contains information from a ClientHello message in order to 214 // guide certificate selection in the GetCertificate callback. 215 type ClientHelloInfo struct { 216 // CipherSuites lists the CipherSuites supported by the client (e.g. 217 // TLS_RSA_WITH_RC4_128_SHA). 218 CipherSuites []uint16 219 220 // ServerName indicates the name of the server requested by the client 221 // in order to support virtual hosting. ServerName is only set if the 222 // client is using SNI (see 223 // http://tools.ietf.org/html/rfc4366#section-3.1). 224 ServerName string 225 226 // SupportedCurves lists the elliptic curves supported by the client. 227 // SupportedCurves is set only if the Supported Elliptic Curves 228 // Extension is being used (see 229 // http://tools.ietf.org/html/rfc4492#section-5.1.1). 230 SupportedCurves []CurveID 231 232 // SupportedPoints lists the point formats supported by the client. 233 // SupportedPoints is set only if the Supported Point Formats Extension 234 // is being used (see 235 // http://tools.ietf.org/html/rfc4492#section-5.1.2). 236 SupportedPoints []uint8 237 } 238 239 // A Config structure is used to configure a TLS client or server. 240 // After one has been passed to a TLS function it must not be 241 // modified. A Config may be reused; the tls package will also not 242 // modify it. 243 type Config struct { 244 // Rand provides the source of entropy for nonces and RSA blinding. 245 // If Rand is nil, TLS uses the cryptographic random reader in package 246 // crypto/rand. 247 // The Reader must be safe for use by multiple goroutines. 248 Rand io.Reader 249 250 // Time returns the current time as the number of seconds since the epoch. 251 // If Time is nil, TLS uses time.Now. 252 Time func() time.Time 253 254 // Certificates contains one or more certificate chains 255 // to present to the other side of the connection. 256 // Server configurations must include at least one certificate. 257 Certificates []Certificate 258 259 // NameToCertificate maps from a certificate name to an element of 260 // Certificates. Note that a certificate name can be of the form 261 // '*.example.com' and so doesn't have to be a domain name as such. 262 // See Config.BuildNameToCertificate 263 // The nil value causes the first element of Certificates to be used 264 // for all connections. 265 NameToCertificate map[string]*Certificate 266 267 // GetCertificate returns a Certificate based on the given 268 // ClientHelloInfo. If GetCertificate is nil or returns nil, then the 269 // certificate is retrieved from NameToCertificate. If 270 // NameToCertificate is nil, the first element of Certificates will be 271 // used. 272 GetCertificate func(clientHello *ClientHelloInfo) (*Certificate, error) 273 274 // RootCAs defines the set of root certificate authorities 275 // that clients use when verifying server certificates. 276 // If RootCAs is nil, TLS uses the host's root CA set. 277 RootCAs *x509.CertPool 278 279 // NextProtos is a list of supported, application level protocols. 280 NextProtos []string 281 282 // ServerName is used to verify the hostname on the returned 283 // certificates unless InsecureSkipVerify is given. It is also included 284 // in the client's handshake to support virtual hosting. 285 ServerName string 286 287 // ClientAuth determines the server's policy for 288 // TLS Client Authentication. The default is NoClientCert. 289 ClientAuth ClientAuthType 290 291 // ClientCAs defines the set of root certificate authorities 292 // that servers use if required to verify a client certificate 293 // by the policy in ClientAuth. 294 ClientCAs *x509.CertPool 295 296 // InsecureSkipVerify controls whether a client verifies the 297 // server's certificate chain and host name. 298 // If InsecureSkipVerify is true, TLS accepts any certificate 299 // presented by the server and any host name in that certificate. 300 // In this mode, TLS is susceptible to man-in-the-middle attacks. 301 // This should be used only for testing. 302 InsecureSkipVerify bool 303 304 // CipherSuites is a list of supported cipher suites. If CipherSuites 305 // is nil, TLS uses a list of suites supported by the implementation. 306 CipherSuites []uint16 307 308 // PreferServerCipherSuites controls whether the server selects the 309 // client's most preferred ciphersuite, or the server's most preferred 310 // ciphersuite. If true then the server's preference, as expressed in 311 // the order of elements in CipherSuites, is used. 312 PreferServerCipherSuites bool 313 314 // SessionTicketsDisabled may be set to true to disable session ticket 315 // (resumption) support. 316 SessionTicketsDisabled bool 317 318 // SessionTicketKey is used by TLS servers to provide session 319 // resumption. See RFC 5077. If zero, it will be filled with 320 // random data before the first server handshake. 321 // 322 // If multiple servers are terminating connections for the same host 323 // they should all have the same SessionTicketKey. If the 324 // SessionTicketKey leaks, previously recorded and future TLS 325 // connections using that key are compromised. 326 SessionTicketKey [32]byte 327 328 // SessionCache is a cache of ClientSessionState entries for TLS session 329 // resumption. 330 ClientSessionCache ClientSessionCache 331 332 // MinVersion contains the minimum SSL/TLS version that is acceptable. 333 // If zero, then SSLv3 is taken as the minimum. 334 MinVersion uint16 335 336 // MaxVersion contains the maximum SSL/TLS version that is acceptable. 337 // If zero, then the maximum version supported by this package is used, 338 // which is currently TLS 1.2. 339 MaxVersion uint16 340 341 // CurvePreferences contains the elliptic curves that will be used in 342 // an ECDHE handshake, in preference order. If empty, the default will 343 // be used. 344 CurvePreferences []CurveID 345 346 serverInitOnce sync.Once // guards calling (*Config).serverInit 347 } 348 349 func (c *Config) serverInit() { 350 if c.SessionTicketsDisabled { 351 return 352 } 353 354 // If the key has already been set then we have nothing to do. 355 for _, b := range c.SessionTicketKey { 356 if b != 0 { 357 return 358 } 359 } 360 361 if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { 362 c.SessionTicketsDisabled = true 363 } 364 } 365 366 func (c *Config) rand() io.Reader { 367 r := c.Rand 368 if r == nil { 369 return rand.Reader 370 } 371 return r 372 } 373 374 func (c *Config) time() time.Time { 375 t := c.Time 376 if t == nil { 377 t = time.Now 378 } 379 return t() 380 } 381 382 func (c *Config) cipherSuites() []uint16 { 383 s := c.CipherSuites 384 if s == nil { 385 s = defaultCipherSuites() 386 } 387 return s 388 } 389 390 func (c *Config) minVersion() uint16 { 391 if c == nil || c.MinVersion == 0 { 392 return minVersion 393 } 394 return c.MinVersion 395 } 396 397 func (c *Config) maxVersion() uint16 { 398 if c == nil || c.MaxVersion == 0 { 399 return maxVersion 400 } 401 return c.MaxVersion 402 } 403 404 var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521} 405 406 func (c *Config) curvePreferences() []CurveID { 407 if c == nil || len(c.CurvePreferences) == 0 { 408 return defaultCurvePreferences 409 } 410 return c.CurvePreferences 411 } 412 413 // mutualVersion returns the protocol version to use given the advertised 414 // version of the peer. 415 func (c *Config) mutualVersion(vers uint16) (uint16, bool) { 416 minVersion := c.minVersion() 417 maxVersion := c.maxVersion() 418 419 if vers < minVersion { 420 return 0, false 421 } 422 if vers > maxVersion { 423 vers = maxVersion 424 } 425 return vers, true 426 } 427 428 // getCertificate returns the best certificate for the given ClientHelloInfo, 429 // defaulting to the first element of c.Certificates. 430 func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { 431 if c.GetCertificate != nil { 432 cert, err := c.GetCertificate(clientHello) 433 if cert != nil || err != nil { 434 return cert, err 435 } 436 } 437 438 if len(c.Certificates) == 1 || c.NameToCertificate == nil { 439 // There's only one choice, so no point doing any work. 440 return &c.Certificates[0], nil 441 } 442 443 name := strings.ToLower(clientHello.ServerName) 444 for len(name) > 0 && name[len(name)-1] == '.' { 445 name = name[:len(name)-1] 446 } 447 448 if cert, ok := c.NameToCertificate[name]; ok { 449 return cert, nil 450 } 451 452 // try replacing labels in the name with wildcards until we get a 453 // match. 454 labels := strings.Split(name, ".") 455 for i := range labels { 456 labels[i] = "*" 457 candidate := strings.Join(labels, ".") 458 if cert, ok := c.NameToCertificate[candidate]; ok { 459 return cert, nil 460 } 461 } 462 463 // If nothing matches, return the first certificate. 464 return &c.Certificates[0], nil 465 } 466 467 // BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate 468 // from the CommonName and SubjectAlternateName fields of each of the leaf 469 // certificates. 470 func (c *Config) BuildNameToCertificate() { 471 c.NameToCertificate = make(map[string]*Certificate) 472 for i := range c.Certificates { 473 cert := &c.Certificates[i] 474 x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) 475 if err != nil { 476 continue 477 } 478 if len(x509Cert.Subject.CommonName) > 0 { 479 c.NameToCertificate[x509Cert.Subject.CommonName] = cert 480 } 481 for _, san := range x509Cert.DNSNames { 482 c.NameToCertificate[san] = cert 483 } 484 } 485 } 486 487 // A Certificate is a chain of one or more certificates, leaf first. 488 type Certificate struct { 489 Certificate [][]byte 490 // PrivateKey contains the private key corresponding to the public key 491 // in Leaf. For a server, this must be a *rsa.PrivateKey or 492 // *ecdsa.PrivateKey. For a client doing client authentication, this 493 // can be any type that implements crypto.Signer (which includes RSA 494 // and ECDSA private keys). 495 PrivateKey crypto.PrivateKey 496 // OCSPStaple contains an optional OCSP response which will be served 497 // to clients that request it. 498 OCSPStaple []byte 499 // Leaf is the parsed form of the leaf certificate, which may be 500 // initialized using x509.ParseCertificate to reduce per-handshake 501 // processing for TLS clients doing client authentication. If nil, the 502 // leaf certificate will be parsed as needed. 503 Leaf *x509.Certificate 504 } 505 506 // A TLS record. 507 type record struct { 508 contentType recordType 509 major, minor uint8 510 payload []byte 511 } 512 513 type handshakeMessage interface { 514 marshal() []byte 515 unmarshal([]byte) bool 516 } 517 518 // lruSessionCache is a ClientSessionCache implementation that uses an LRU 519 // caching strategy. 520 type lruSessionCache struct { 521 sync.Mutex 522 523 m map[string]*list.Element 524 q *list.List 525 capacity int 526 } 527 528 type lruSessionCacheEntry struct { 529 sessionKey string 530 state *ClientSessionState 531 } 532 533 // NewLRUClientSessionCache returns a ClientSessionCache with the given 534 // capacity that uses an LRU strategy. If capacity is < 1, a default capacity 535 // is used instead. 536 func NewLRUClientSessionCache(capacity int) ClientSessionCache { 537 const defaultSessionCacheCapacity = 64 538 539 if capacity < 1 { 540 capacity = defaultSessionCacheCapacity 541 } 542 return &lruSessionCache{ 543 m: make(map[string]*list.Element), 544 q: list.New(), 545 capacity: capacity, 546 } 547 } 548 549 // Put adds the provided (sessionKey, cs) pair to the cache. 550 func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) { 551 c.Lock() 552 defer c.Unlock() 553 554 if elem, ok := c.m[sessionKey]; ok { 555 entry := elem.Value.(*lruSessionCacheEntry) 556 entry.state = cs 557 c.q.MoveToFront(elem) 558 return 559 } 560 561 if c.q.Len() < c.capacity { 562 entry := &lruSessionCacheEntry{sessionKey, cs} 563 c.m[sessionKey] = c.q.PushFront(entry) 564 return 565 } 566 567 elem := c.q.Back() 568 entry := elem.Value.(*lruSessionCacheEntry) 569 delete(c.m, entry.sessionKey) 570 entry.sessionKey = sessionKey 571 entry.state = cs 572 c.q.MoveToFront(elem) 573 c.m[sessionKey] = elem 574 } 575 576 // Get returns the ClientSessionState value associated with a given key. It 577 // returns (nil, false) if no value is found. 578 func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { 579 c.Lock() 580 defer c.Unlock() 581 582 if elem, ok := c.m[sessionKey]; ok { 583 c.q.MoveToFront(elem) 584 return elem.Value.(*lruSessionCacheEntry).state, true 585 } 586 return nil, false 587 } 588 589 // TODO(jsing): Make these available to both crypto/x509 and crypto/tls. 590 type dsaSignature struct { 591 R, S *big.Int 592 } 593 594 type ecdsaSignature dsaSignature 595 596 var emptyConfig Config 597 598 func defaultConfig() *Config { 599 return &emptyConfig 600 } 601 602 var ( 603 once sync.Once 604 varDefaultCipherSuites []uint16 605 ) 606 607 func defaultCipherSuites() []uint16 { 608 once.Do(initDefaultCipherSuites) 609 return varDefaultCipherSuites 610 } 611 612 func initDefaultCipherSuites() { 613 varDefaultCipherSuites = make([]uint16, len(cipherSuites)) 614 for i, suite := range cipherSuites { 615 varDefaultCipherSuites[i] = suite.id 616 } 617 } 618 619 func unexpectedMessageError(wanted, got interface{}) error { 620 return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted) 621 }