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