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 5package main 6 7import ( 8 "container/list" 9 "crypto" 10 "crypto/ecdsa" 11 "crypto/rand" 12 "crypto/x509" 13 "fmt" 14 "io" 15 "math/big" 16 "strings" 17 "sync" 18 "time" 19) 20 21const ( 22 VersionSSL30 = 0x0300 23 VersionTLS10 = 0x0301 24 VersionTLS11 = 0x0302 25 VersionTLS12 = 0x0303 26) 27 28const ( 29 maxPlaintext = 16384 // maximum plaintext payload length 30 maxCiphertext = 16384 + 2048 // maximum ciphertext payload length 31 tlsRecordHeaderLen = 5 // record header length 32 dtlsRecordHeaderLen = 13 33 maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) 34 35 minVersion = VersionSSL30 36 maxVersion = VersionTLS12 37) 38 39// TLS record types. 40type recordType uint8 41 42const ( 43 recordTypeChangeCipherSpec recordType = 20 44 recordTypeAlert recordType = 21 45 recordTypeHandshake recordType = 22 46 recordTypeApplicationData recordType = 23 47) 48 49// TLS handshake message types. 50const ( 51 typeClientHello uint8 = 1 52 typeServerHello uint8 = 2 53 typeHelloVerifyRequest uint8 = 3 54 typeNewSessionTicket uint8 = 4 55 typeCertificate uint8 = 11 56 typeServerKeyExchange uint8 = 12 57 typeCertificateRequest uint8 = 13 58 typeServerHelloDone uint8 = 14 59 typeCertificateVerify uint8 = 15 60 typeClientKeyExchange uint8 = 16 61 typeFinished uint8 = 20 62 typeCertificateStatus uint8 = 22 63 typeNextProtocol uint8 = 67 // Not IANA assigned 64 typeEncryptedExtensions uint8 = 203 // Not IANA assigned 65) 66 67// TLS compression types. 68const ( 69 compressionNone uint8 = 0 70) 71 72// TLS extension numbers 73const ( 74 extensionServerName uint16 = 0 75 extensionStatusRequest uint16 = 5 76 extensionSupportedCurves uint16 = 10 77 extensionSupportedPoints uint16 = 11 78 extensionSignatureAlgorithms uint16 = 13 79 extensionALPN uint16 = 16 80 extensionSessionTicket uint16 = 35 81 extensionNextProtoNeg uint16 = 13172 // not IANA assigned 82 extensionRenegotiationInfo uint16 = 0xff01 83 extensionChannelID uint16 = 30032 // not IANA assigned 84) 85 86// TLS signaling cipher suite values 87const ( 88 scsvRenegotiation uint16 = 0x00ff 89) 90 91// CurveID is the type of a TLS identifier for an elliptic curve. See 92// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 93type CurveID uint16 94 95const ( 96 CurveP256 CurveID = 23 97 CurveP384 CurveID = 24 98 CurveP521 CurveID = 25 99) 100 101// TLS Elliptic Curve Point Formats 102// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 103const ( 104 pointFormatUncompressed uint8 = 0 105) 106 107// TLS CertificateStatusType (RFC 3546) 108const ( 109 statusTypeOCSP uint8 = 1 110) 111 112// Certificate types (for certificateRequestMsg) 113const ( 114 CertTypeRSASign = 1 // A certificate containing an RSA key 115 CertTypeDSSSign = 2 // A certificate containing a DSA key 116 CertTypeRSAFixedDH = 3 // A certificate containing a static DH key 117 CertTypeDSSFixedDH = 4 // A certificate containing a static DH key 118 119 // See RFC4492 sections 3 and 5.5. 120 CertTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. 121 CertTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. 122 CertTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. 123 124 // Rest of these are reserved by the TLS spec 125) 126 127// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1) 128const ( 129 hashSHA1 uint8 = 2 130 hashSHA256 uint8 = 4 131) 132 133// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1) 134const ( 135 signatureRSA uint8 = 1 136 signatureECDSA uint8 = 3 137) 138 139// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See 140// RFC 5246, section A.4.1. 141type signatureAndHash struct { 142 signature, hash uint8 143} 144 145// supportedSKXSignatureAlgorithms contains the signature and hash algorithms 146// that the code advertises as supported in a TLS 1.2 ClientHello. 147var supportedSKXSignatureAlgorithms = []signatureAndHash{ 148 {signatureRSA, hashSHA256}, 149 {signatureECDSA, hashSHA256}, 150 {signatureRSA, hashSHA1}, 151 {signatureECDSA, hashSHA1}, 152} 153 154// supportedClientCertSignatureAlgorithms contains the signature and hash 155// algorithms that the code advertises as supported in a TLS 1.2 156// CertificateRequest. 157var supportedClientCertSignatureAlgorithms = []signatureAndHash{ 158 {signatureRSA, hashSHA256}, 159 {signatureECDSA, hashSHA256}, 160} 161 162// ConnectionState records basic TLS details about the connection. 163type ConnectionState struct { 164 Version uint16 // TLS version used by the connection (e.g. VersionTLS12) 165 HandshakeComplete bool // TLS handshake is complete 166 DidResume bool // connection resumes a previous TLS connection 167 CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...) 168 NegotiatedProtocol string // negotiated next protocol (from Config.NextProtos) 169 NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server 170 NegotiatedProtocolFromALPN bool // protocol negotiated with ALPN 171 ServerName string // server name requested by client, if any (server side only) 172 PeerCertificates []*x509.Certificate // certificate chain presented by remote peer 173 VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates 174 ChannelID *ecdsa.PublicKey // the channel ID for this connection 175} 176 177// ClientAuthType declares the policy the server will follow for 178// TLS Client Authentication. 179type ClientAuthType int 180 181const ( 182 NoClientCert ClientAuthType = iota 183 RequestClientCert 184 RequireAnyClientCert 185 VerifyClientCertIfGiven 186 RequireAndVerifyClientCert 187) 188 189// ClientSessionState contains the state needed by clients to resume TLS 190// sessions. 191type ClientSessionState struct { 192 sessionTicket []uint8 // Encrypted ticket used for session resumption with server 193 vers uint16 // SSL/TLS version negotiated for the session 194 cipherSuite uint16 // Ciphersuite negotiated for the session 195 masterSecret []byte // MasterSecret generated by client on a full handshake 196 handshakeHash []byte // Handshake hash for Channel ID purposes. 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. 204type 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// A Config structure is used to configure a TLS client or server. 214// After one has been passed to a TLS function it must not be 215// modified. A Config may be reused; the tls package will also not 216// modify it. 217type Config struct { 218 // Rand provides the source of entropy for nonces and RSA blinding. 219 // If Rand is nil, TLS uses the cryptographic random reader in package 220 // crypto/rand. 221 // The Reader must be safe for use by multiple goroutines. 222 Rand io.Reader 223 224 // Time returns the current time as the number of seconds since the epoch. 225 // If Time is nil, TLS uses time.Now. 226 Time func() time.Time 227 228 // Certificates contains one or more certificate chains 229 // to present to the other side of the connection. 230 // Server configurations must include at least one certificate. 231 Certificates []Certificate 232 233 // NameToCertificate maps from a certificate name to an element of 234 // Certificates. Note that a certificate name can be of the form 235 // '*.example.com' and so doesn't have to be a domain name as such. 236 // See Config.BuildNameToCertificate 237 // The nil value causes the first element of Certificates to be used 238 // for all connections. 239 NameToCertificate map[string]*Certificate 240 241 // RootCAs defines the set of root certificate authorities 242 // that clients use when verifying server certificates. 243 // If RootCAs is nil, TLS uses the host's root CA set. 244 RootCAs *x509.CertPool 245 246 // NextProtos is a list of supported, application level protocols. 247 NextProtos []string 248 249 // ServerName is used to verify the hostname on the returned 250 // certificates unless InsecureSkipVerify is given. It is also included 251 // in the client's handshake to support virtual hosting. 252 ServerName string 253 254 // ClientAuth determines the server's policy for 255 // TLS Client Authentication. The default is NoClientCert. 256 ClientAuth ClientAuthType 257 258 // ClientCAs defines the set of root certificate authorities 259 // that servers use if required to verify a client certificate 260 // by the policy in ClientAuth. 261 ClientCAs *x509.CertPool 262 263 // ClientCertificateTypes defines the set of allowed client certificate 264 // types. The default is CertTypeRSASign and CertTypeECDSASign. 265 ClientCertificateTypes []byte 266 267 // InsecureSkipVerify controls whether a client verifies the 268 // server's certificate chain and host name. 269 // If InsecureSkipVerify is true, TLS accepts any certificate 270 // presented by the server and any host name in that certificate. 271 // In this mode, TLS is susceptible to man-in-the-middle attacks. 272 // This should be used only for testing. 273 InsecureSkipVerify bool 274 275 // CipherSuites is a list of supported cipher suites. If CipherSuites 276 // is nil, TLS uses a list of suites supported by the implementation. 277 CipherSuites []uint16 278 279 // PreferServerCipherSuites controls whether the server selects the 280 // client's most preferred ciphersuite, or the server's most preferred 281 // ciphersuite. If true then the server's preference, as expressed in 282 // the order of elements in CipherSuites, is used. 283 PreferServerCipherSuites bool 284 285 // SessionTicketsDisabled may be set to true to disable session ticket 286 // (resumption) support. 287 SessionTicketsDisabled bool 288 289 // SessionTicketKey is used by TLS servers to provide session 290 // resumption. See RFC 5077. If zero, it will be filled with 291 // random data before the first server handshake. 292 // 293 // If multiple servers are terminating connections for the same host 294 // they should all have the same SessionTicketKey. If the 295 // SessionTicketKey leaks, previously recorded and future TLS 296 // connections using that key are compromised. 297 SessionTicketKey [32]byte 298 299 // SessionCache is a cache of ClientSessionState entries for TLS session 300 // resumption. 301 ClientSessionCache ClientSessionCache 302 303 // MinVersion contains the minimum SSL/TLS version that is acceptable. 304 // If zero, then SSLv3 is taken as the minimum. 305 MinVersion uint16 306 307 // MaxVersion contains the maximum SSL/TLS version that is acceptable. 308 // If zero, then the maximum version supported by this package is used, 309 // which is currently TLS 1.2. 310 MaxVersion uint16 311 312 // CurvePreferences contains the elliptic curves that will be used in 313 // an ECDHE handshake, in preference order. If empty, the default will 314 // be used. 315 CurvePreferences []CurveID 316 317 // ChannelID contains the ECDSA key for the client to use as 318 // its TLS Channel ID. 319 ChannelID *ecdsa.PrivateKey 320 321 // RequestChannelID controls whether the server requests a TLS 322 // Channel ID. If negotiated, the client's public key is 323 // returned in the ConnectionState. 324 RequestChannelID bool 325 326 // Bugs specifies optional misbehaviour to be used for testing other 327 // implementations. 328 Bugs ProtocolBugs 329 330 serverInitOnce sync.Once // guards calling (*Config).serverInit 331} 332 333type BadValue int 334 335const ( 336 BadValueNone BadValue = iota 337 BadValueNegative 338 BadValueZero 339 BadValueLimit 340 BadValueLarge 341 NumBadValues 342) 343 344type ProtocolBugs struct { 345 // InvalidSKXSignature specifies that the signature in a 346 // ServerKeyExchange message should be invalid. 347 InvalidSKXSignature bool 348 349 // InvalidSKXCurve causes the curve ID in the ServerKeyExchange message 350 // to be wrong. 351 InvalidSKXCurve bool 352 353 // BadECDSAR controls ways in which the 'r' value of an ECDSA signature 354 // can be invalid. 355 BadECDSAR BadValue 356 BadECDSAS BadValue 357 358 // MaxPadding causes CBC records to have the maximum possible padding. 359 MaxPadding bool 360 // PaddingFirstByteBad causes the first byte of the padding to be 361 // incorrect. 362 PaddingFirstByteBad bool 363 // PaddingFirstByteBadIf255 causes the first byte of padding to be 364 // incorrect if there's a maximum amount of padding (i.e. 255 bytes). 365 PaddingFirstByteBadIf255 bool 366 367 // FailIfNotFallbackSCSV causes a server handshake to fail if the 368 // client doesn't send the fallback SCSV value. 369 FailIfNotFallbackSCSV bool 370 371 // DuplicateExtension causes an extra empty extension of bogus type to 372 // be emitted in either the ClientHello or the ServerHello. 373 DuplicateExtension bool 374 375 // UnauthenticatedECDH causes the server to pretend ECDHE_RSA 376 // and ECDHE_ECDSA cipher suites are actually ECDH_anon. No 377 // Certificate message is sent and no signature is added to 378 // ServerKeyExchange. 379 UnauthenticatedECDH bool 380 381 // SkipServerKeyExchange causes the server to skip sending 382 // ServerKeyExchange messages. 383 SkipServerKeyExchange bool 384 385 // SkipChangeCipherSpec causes the implementation to skip 386 // sending the ChangeCipherSpec message (and adjusting cipher 387 // state accordingly for the Finished message). 388 SkipChangeCipherSpec bool 389 390 // EarlyChangeCipherSpec causes the client to send an early 391 // ChangeCipherSpec message before the ClientKeyExchange. A value of 392 // zero disables this behavior. One and two configure variants for 0.9.8 393 // and 1.0.1 modes, respectively. 394 EarlyChangeCipherSpec int 395 396 // FragmentAcrossChangeCipherSpec causes the implementation to fragment 397 // the Finished (or NextProto) message around the ChangeCipherSpec 398 // messages. 399 FragmentAcrossChangeCipherSpec bool 400 401 // SkipNewSessionTicket causes the server to skip sending the 402 // NewSessionTicket message despite promising to in ServerHello. 403 SkipNewSessionTicket bool 404 405 // SendV2ClientHello causes the client to send a V2ClientHello 406 // instead of a normal ClientHello. 407 SendV2ClientHello bool 408 409 // SendFallbackSCSV causes the client to include 410 // TLS_FALLBACK_SCSV in the ClientHello. 411 SendFallbackSCSV bool 412 413 // MaxHandshakeRecordLength, if non-zero, is the maximum size of a 414 // handshake record. Handshake messages will be split into multiple 415 // records at the specified size, except that the client_version will 416 // never be fragmented. 417 MaxHandshakeRecordLength int 418 419 // FragmentClientVersion will allow MaxHandshakeRecordLength to apply to 420 // the first 6 bytes of the ClientHello. 421 FragmentClientVersion bool 422 423 // RsaClientKeyExchangeVersion, if non-zero, causes the client to send a 424 // ClientKeyExchange with the specified version rather than the 425 // client_version when performing the RSA key exchange. 426 RsaClientKeyExchangeVersion uint16 427 428 // RenewTicketOnResume causes the server to renew the session ticket and 429 // send a NewSessionTicket message during an abbreviated handshake. 430 RenewTicketOnResume bool 431 432 // SendClientVersion, if non-zero, causes the client to send a different 433 // TLS version in the ClientHello than the maximum supported version. 434 SendClientVersion uint16 435 436 // SkipHelloVerifyRequest causes a DTLS server to skip the 437 // HelloVerifyRequest message. 438 SkipHelloVerifyRequest bool 439 440 // ExpectFalseStart causes the server to, on full handshakes, 441 // expect the peer to False Start; the server Finished message 442 // isn't sent until we receive an application data record 443 // from the peer. 444 ExpectFalseStart bool 445 446 // SSL3RSAKeyExchange causes the client to always send an RSA 447 // ClientKeyExchange message without the two-byte length 448 // prefix, as if it were SSL3. 449 SSL3RSAKeyExchange bool 450 451 // SkipCipherVersionCheck causes the server to negotiate 452 // TLS 1.2 ciphers in earlier versions of TLS. 453 SkipCipherVersionCheck bool 454 455 // ExpectServerName, if not empty, is the hostname the client 456 // must specify in the server_name extension. 457 ExpectServerName string 458 459 // SwapNPNAndALPN switches the relative order between NPN and 460 // ALPN on the server. This is to test that server preference 461 // of ALPN works regardless of their relative order. 462 SwapNPNAndALPN bool 463 464 // AllowSessionVersionMismatch causes the server to resume sessions 465 // regardless of the version associated with the session. 466 AllowSessionVersionMismatch bool 467} 468 469func (c *Config) serverInit() { 470 if c.SessionTicketsDisabled { 471 return 472 } 473 474 // If the key has already been set then we have nothing to do. 475 for _, b := range c.SessionTicketKey { 476 if b != 0 { 477 return 478 } 479 } 480 481 if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { 482 c.SessionTicketsDisabled = true 483 } 484} 485 486func (c *Config) rand() io.Reader { 487 r := c.Rand 488 if r == nil { 489 return rand.Reader 490 } 491 return r 492} 493 494func (c *Config) time() time.Time { 495 t := c.Time 496 if t == nil { 497 t = time.Now 498 } 499 return t() 500} 501 502func (c *Config) cipherSuites() []uint16 { 503 s := c.CipherSuites 504 if s == nil { 505 s = defaultCipherSuites() 506 } 507 return s 508} 509 510func (c *Config) minVersion() uint16 { 511 if c == nil || c.MinVersion == 0 { 512 return minVersion 513 } 514 return c.MinVersion 515} 516 517func (c *Config) maxVersion() uint16 { 518 if c == nil || c.MaxVersion == 0 { 519 return maxVersion 520 } 521 return c.MaxVersion 522} 523 524var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521} 525 526func (c *Config) curvePreferences() []CurveID { 527 if c == nil || len(c.CurvePreferences) == 0 { 528 return defaultCurvePreferences 529 } 530 return c.CurvePreferences 531} 532 533// mutualVersion returns the protocol version to use given the advertised 534// version of the peer. 535func (c *Config) mutualVersion(vers uint16) (uint16, bool) { 536 minVersion := c.minVersion() 537 maxVersion := c.maxVersion() 538 539 if vers < minVersion { 540 return 0, false 541 } 542 if vers > maxVersion { 543 vers = maxVersion 544 } 545 return vers, true 546} 547 548// getCertificateForName returns the best certificate for the given name, 549// defaulting to the first element of c.Certificates if there are no good 550// options. 551func (c *Config) getCertificateForName(name string) *Certificate { 552 if len(c.Certificates) == 1 || c.NameToCertificate == nil { 553 // There's only one choice, so no point doing any work. 554 return &c.Certificates[0] 555 } 556 557 name = strings.ToLower(name) 558 for len(name) > 0 && name[len(name)-1] == '.' { 559 name = name[:len(name)-1] 560 } 561 562 if cert, ok := c.NameToCertificate[name]; ok { 563 return cert 564 } 565 566 // try replacing labels in the name with wildcards until we get a 567 // match. 568 labels := strings.Split(name, ".") 569 for i := range labels { 570 labels[i] = "*" 571 candidate := strings.Join(labels, ".") 572 if cert, ok := c.NameToCertificate[candidate]; ok { 573 return cert 574 } 575 } 576 577 // If nothing matches, return the first certificate. 578 return &c.Certificates[0] 579} 580 581// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate 582// from the CommonName and SubjectAlternateName fields of each of the leaf 583// certificates. 584func (c *Config) BuildNameToCertificate() { 585 c.NameToCertificate = make(map[string]*Certificate) 586 for i := range c.Certificates { 587 cert := &c.Certificates[i] 588 x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) 589 if err != nil { 590 continue 591 } 592 if len(x509Cert.Subject.CommonName) > 0 { 593 c.NameToCertificate[x509Cert.Subject.CommonName] = cert 594 } 595 for _, san := range x509Cert.DNSNames { 596 c.NameToCertificate[san] = cert 597 } 598 } 599} 600 601// A Certificate is a chain of one or more certificates, leaf first. 602type Certificate struct { 603 Certificate [][]byte 604 PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey 605 // OCSPStaple contains an optional OCSP response which will be served 606 // to clients that request it. 607 OCSPStaple []byte 608 // Leaf is the parsed form of the leaf certificate, which may be 609 // initialized using x509.ParseCertificate to reduce per-handshake 610 // processing for TLS clients doing client authentication. If nil, the 611 // leaf certificate will be parsed as needed. 612 Leaf *x509.Certificate 613} 614 615// A TLS record. 616type record struct { 617 contentType recordType 618 major, minor uint8 619 payload []byte 620} 621 622type handshakeMessage interface { 623 marshal() []byte 624 unmarshal([]byte) bool 625} 626 627// lruSessionCache is a ClientSessionCache implementation that uses an LRU 628// caching strategy. 629type lruSessionCache struct { 630 sync.Mutex 631 632 m map[string]*list.Element 633 q *list.List 634 capacity int 635} 636 637type lruSessionCacheEntry struct { 638 sessionKey string 639 state *ClientSessionState 640} 641 642// NewLRUClientSessionCache returns a ClientSessionCache with the given 643// capacity that uses an LRU strategy. If capacity is < 1, a default capacity 644// is used instead. 645func NewLRUClientSessionCache(capacity int) ClientSessionCache { 646 const defaultSessionCacheCapacity = 64 647 648 if capacity < 1 { 649 capacity = defaultSessionCacheCapacity 650 } 651 return &lruSessionCache{ 652 m: make(map[string]*list.Element), 653 q: list.New(), 654 capacity: capacity, 655 } 656} 657 658// Put adds the provided (sessionKey, cs) pair to the cache. 659func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) { 660 c.Lock() 661 defer c.Unlock() 662 663 if elem, ok := c.m[sessionKey]; ok { 664 entry := elem.Value.(*lruSessionCacheEntry) 665 entry.state = cs 666 c.q.MoveToFront(elem) 667 return 668 } 669 670 if c.q.Len() < c.capacity { 671 entry := &lruSessionCacheEntry{sessionKey, cs} 672 c.m[sessionKey] = c.q.PushFront(entry) 673 return 674 } 675 676 elem := c.q.Back() 677 entry := elem.Value.(*lruSessionCacheEntry) 678 delete(c.m, entry.sessionKey) 679 entry.sessionKey = sessionKey 680 entry.state = cs 681 c.q.MoveToFront(elem) 682 c.m[sessionKey] = elem 683} 684 685// Get returns the ClientSessionState value associated with a given key. It 686// returns (nil, false) if no value is found. 687func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { 688 c.Lock() 689 defer c.Unlock() 690 691 if elem, ok := c.m[sessionKey]; ok { 692 c.q.MoveToFront(elem) 693 return elem.Value.(*lruSessionCacheEntry).state, true 694 } 695 return nil, false 696} 697 698// TODO(jsing): Make these available to both crypto/x509 and crypto/tls. 699type dsaSignature struct { 700 R, S *big.Int 701} 702 703type ecdsaSignature dsaSignature 704 705var emptyConfig Config 706 707func defaultConfig() *Config { 708 return &emptyConfig 709} 710 711var ( 712 once sync.Once 713 varDefaultCipherSuites []uint16 714) 715 716func defaultCipherSuites() []uint16 { 717 once.Do(initDefaultCipherSuites) 718 return varDefaultCipherSuites 719} 720 721func initDefaultCipherSuites() { 722 varDefaultCipherSuites = make([]uint16, len(cipherSuites)) 723 for i, suite := range cipherSuites { 724 varDefaultCipherSuites[i] = suite.id 725 } 726} 727 728func unexpectedMessageError(wanted, got interface{}) error { 729 return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted) 730} 731