github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/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 "crypto" 9 "crypto/rand" 10 "crypto/x509" 11 "io" 12 "math/big" 13 "strings" 14 "sync" 15 "time" 16 ) 17 18 const ( 19 VersionSSL30 = 0x0300 20 VersionTLS10 = 0x0301 21 VersionTLS11 = 0x0302 22 VersionTLS12 = 0x0303 23 ) 24 25 const ( 26 maxPlaintext = 16384 // maximum plaintext payload length 27 maxCiphertext = 16384 + 2048 // maximum ciphertext payload length 28 recordHeaderLen = 5 // record header length 29 maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) 30 31 minVersion = VersionSSL30 32 maxVersion = VersionTLS12 33 ) 34 35 // TLS record types. 36 type recordType uint8 37 38 const ( 39 recordTypeChangeCipherSpec recordType = 20 40 recordTypeAlert recordType = 21 41 recordTypeHandshake recordType = 22 42 recordTypeApplicationData recordType = 23 43 ) 44 45 // TLS handshake message types. 46 const ( 47 typeClientHello uint8 = 1 48 typeServerHello uint8 = 2 49 typeNewSessionTicket uint8 = 4 50 typeCertificate uint8 = 11 51 typeServerKeyExchange uint8 = 12 52 typeCertificateRequest uint8 = 13 53 typeServerHelloDone uint8 = 14 54 typeCertificateVerify uint8 = 15 55 typeClientKeyExchange uint8 = 16 56 typeFinished uint8 = 20 57 typeCertificateStatus uint8 = 22 58 typeNextProtocol uint8 = 67 // Not IANA assigned 59 ) 60 61 // TLS compression types. 62 const ( 63 compressionNone uint8 = 0 64 ) 65 66 // TLS extension numbers 67 var ( 68 extensionServerName uint16 = 0 69 extensionStatusRequest uint16 = 5 70 extensionSupportedCurves uint16 = 10 71 extensionSupportedPoints uint16 = 11 72 extensionSignatureAlgorithms uint16 = 13 73 extensionSessionTicket uint16 = 35 74 extensionNextProtoNeg uint16 = 13172 // not IANA assigned 75 ) 76 77 // TLS Elliptic Curves 78 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 79 var ( 80 curveP256 uint16 = 23 81 curveP384 uint16 = 24 82 curveP521 uint16 = 25 83 ) 84 85 // TLS Elliptic Curve Point Formats 86 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 87 var ( 88 pointFormatUncompressed uint8 = 0 89 ) 90 91 // TLS CertificateStatusType (RFC 3546) 92 const ( 93 statusTypeOCSP uint8 = 1 94 ) 95 96 // Certificate types (for certificateRequestMsg) 97 const ( 98 certTypeRSASign = 1 // A certificate containing an RSA key 99 certTypeDSSSign = 2 // A certificate containing a DSA key 100 certTypeRSAFixedDH = 3 // A certificate containing a static DH key 101 certTypeDSSFixedDH = 4 // A certificate containing a static DH key 102 103 // See RFC4492 sections 3 and 5.5. 104 certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. 105 certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. 106 certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. 107 108 // Rest of these are reserved by the TLS spec 109 ) 110 111 // Hash functions for TLS 1.2 (See RFC 5246, section A.4.1) 112 const ( 113 hashSHA1 uint8 = 2 114 hashSHA256 uint8 = 4 115 ) 116 117 // Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1) 118 const ( 119 signatureRSA uint8 = 1 120 signatureECDSA uint8 = 3 121 ) 122 123 // signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See 124 // RFC 5246, section A.4.1. 125 type signatureAndHash struct { 126 hash, signature uint8 127 } 128 129 // supportedSKXSignatureAlgorithms contains the signature and hash algorithms 130 // that the code advertises as supported in a TLS 1.2 ClientHello. 131 var supportedSKXSignatureAlgorithms = []signatureAndHash{ 132 {hashSHA256, signatureRSA}, 133 {hashSHA256, signatureECDSA}, 134 {hashSHA1, signatureRSA}, 135 {hashSHA1, signatureECDSA}, 136 } 137 138 // supportedClientCertSignatureAlgorithms contains the signature and hash 139 // algorithms that the code advertises as supported in a TLS 1.2 140 // CertificateRequest. 141 var supportedClientCertSignatureAlgorithms = []signatureAndHash{ 142 {hashSHA256, signatureRSA}, 143 {hashSHA256, signatureECDSA}, 144 } 145 146 // ConnectionState records basic TLS details about the connection. 147 type ConnectionState struct { 148 HandshakeComplete bool // TLS handshake is complete 149 DidResume bool // connection resumes a previous TLS connection 150 CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...) 151 NegotiatedProtocol string // negotiated next protocol (from Config.NextProtos) 152 NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server 153 ServerName string // server name requested by client, if any (server side only) 154 PeerCertificates []*x509.Certificate // certificate chain presented by remote peer 155 VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates 156 } 157 158 // ClientAuthType declares the policy the server will follow for 159 // TLS Client Authentication. 160 type ClientAuthType int 161 162 const ( 163 NoClientCert ClientAuthType = iota 164 RequestClientCert 165 RequireAnyClientCert 166 VerifyClientCertIfGiven 167 RequireAndVerifyClientCert 168 ) 169 170 // A Config structure is used to configure a TLS client or server. After one 171 // has been passed to a TLS function it must not be modified. 172 type Config struct { 173 // Rand provides the source of entropy for nonces and RSA blinding. 174 // If Rand is nil, TLS uses the cryptographic random reader in package 175 // crypto/rand. 176 Rand io.Reader 177 178 // Time returns the current time as the number of seconds since the epoch. 179 // If Time is nil, TLS uses time.Now. 180 Time func() time.Time 181 182 // Certificates contains one or more certificate chains 183 // to present to the other side of the connection. 184 // Server configurations must include at least one certificate. 185 Certificates []Certificate 186 187 // NameToCertificate maps from a certificate name to an element of 188 // Certificates. Note that a certificate name can be of the form 189 // '*.example.com' and so doesn't have to be a domain name as such. 190 // See Config.BuildNameToCertificate 191 // The nil value causes the first element of Certificates to be used 192 // for all connections. 193 NameToCertificate map[string]*Certificate 194 195 // RootCAs defines the set of root certificate authorities 196 // that clients use when verifying server certificates. 197 // If RootCAs is nil, TLS uses the host's root CA set. 198 RootCAs *x509.CertPool 199 200 // NextProtos is a list of supported, application level protocols. 201 NextProtos []string 202 203 // ServerName is included in the client's handshake to support virtual 204 // hosting. 205 ServerName string 206 207 // ClientAuth determines the server's policy for 208 // TLS Client Authentication. The default is NoClientCert. 209 ClientAuth ClientAuthType 210 211 // ClientCAs defines the set of root certificate authorities 212 // that servers use if required to verify a client certificate 213 // by the policy in ClientAuth. 214 ClientCAs *x509.CertPool 215 216 // InsecureSkipVerify controls whether a client verifies the 217 // server's certificate chain and host name. 218 // If InsecureSkipVerify is true, TLS accepts any certificate 219 // presented by the server and any host name in that certificate. 220 // In this mode, TLS is susceptible to man-in-the-middle attacks. 221 // This should be used only for testing. 222 InsecureSkipVerify bool 223 224 // CipherSuites is a list of supported cipher suites. If CipherSuites 225 // is nil, TLS uses a list of suites supported by the implementation. 226 CipherSuites []uint16 227 228 // PreferServerCipherSuites controls whether the server selects the 229 // client's most preferred ciphersuite, or the server's most preferred 230 // ciphersuite. If true then the server's preference, as expressed in 231 // the order of elements in CipherSuites, is used. 232 PreferServerCipherSuites bool 233 234 // SessionTicketsDisabled may be set to true to disable session ticket 235 // (resumption) support. 236 SessionTicketsDisabled bool 237 238 // SessionTicketKey is used by TLS servers to provide session 239 // resumption. See RFC 5077. If zero, it will be filled with 240 // random data before the first server handshake. 241 // 242 // If multiple servers are terminating connections for the same host 243 // they should all have the same SessionTicketKey. If the 244 // SessionTicketKey leaks, previously recorded and future TLS 245 // connections using that key are compromised. 246 SessionTicketKey [32]byte 247 248 // MinVersion contains the minimum SSL/TLS version that is acceptable. 249 // If zero, then SSLv3 is taken as the minimum. 250 MinVersion uint16 251 252 // MaxVersion contains the maximum SSL/TLS version that is acceptable. 253 // If zero, then the maximum version supported by this package is used, 254 // which is currently TLS 1.2. 255 MaxVersion uint16 256 257 serverInitOnce sync.Once // guards calling (*Config).serverInit 258 } 259 260 func (c *Config) serverInit() { 261 if c.SessionTicketsDisabled { 262 return 263 } 264 265 // If the key has already been set then we have nothing to do. 266 for _, b := range c.SessionTicketKey { 267 if b != 0 { 268 return 269 } 270 } 271 272 if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { 273 c.SessionTicketsDisabled = true 274 } 275 } 276 277 func (c *Config) rand() io.Reader { 278 r := c.Rand 279 if r == nil { 280 return rand.Reader 281 } 282 return r 283 } 284 285 func (c *Config) time() time.Time { 286 t := c.Time 287 if t == nil { 288 t = time.Now 289 } 290 return t() 291 } 292 293 func (c *Config) cipherSuites() []uint16 { 294 s := c.CipherSuites 295 if s == nil { 296 s = defaultCipherSuites() 297 } 298 return s 299 } 300 301 func (c *Config) minVersion() uint16 { 302 if c == nil || c.MinVersion == 0 { 303 return minVersion 304 } 305 return c.MinVersion 306 } 307 308 func (c *Config) maxVersion() uint16 { 309 if c == nil || c.MaxVersion == 0 { 310 return maxVersion 311 } 312 return c.MaxVersion 313 } 314 315 // mutualVersion returns the protocol version to use given the advertised 316 // version of the peer. 317 func (c *Config) mutualVersion(vers uint16) (uint16, bool) { 318 minVersion := c.minVersion() 319 maxVersion := c.maxVersion() 320 321 if vers < minVersion { 322 return 0, false 323 } 324 if vers > maxVersion { 325 vers = maxVersion 326 } 327 return vers, true 328 } 329 330 // getCertificateForName returns the best certificate for the given name, 331 // defaulting to the first element of c.Certificates if there are no good 332 // options. 333 func (c *Config) getCertificateForName(name string) *Certificate { 334 if len(c.Certificates) == 1 || c.NameToCertificate == nil { 335 // There's only one choice, so no point doing any work. 336 return &c.Certificates[0] 337 } 338 339 name = strings.ToLower(name) 340 for len(name) > 0 && name[len(name)-1] == '.' { 341 name = name[:len(name)-1] 342 } 343 344 if cert, ok := c.NameToCertificate[name]; ok { 345 return cert 346 } 347 348 // try replacing labels in the name with wildcards until we get a 349 // match. 350 labels := strings.Split(name, ".") 351 for i := range labels { 352 labels[i] = "*" 353 candidate := strings.Join(labels, ".") 354 if cert, ok := c.NameToCertificate[candidate]; ok { 355 return cert 356 } 357 } 358 359 // If nothing matches, return the first certificate. 360 return &c.Certificates[0] 361 } 362 363 // BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate 364 // from the CommonName and SubjectAlternateName fields of each of the leaf 365 // certificates. 366 func (c *Config) BuildNameToCertificate() { 367 c.NameToCertificate = make(map[string]*Certificate) 368 for i := range c.Certificates { 369 cert := &c.Certificates[i] 370 x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) 371 if err != nil { 372 continue 373 } 374 if len(x509Cert.Subject.CommonName) > 0 { 375 c.NameToCertificate[x509Cert.Subject.CommonName] = cert 376 } 377 for _, san := range x509Cert.DNSNames { 378 c.NameToCertificate[san] = cert 379 } 380 } 381 } 382 383 // A Certificate is a chain of one or more certificates, leaf first. 384 type Certificate struct { 385 Certificate [][]byte 386 PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey 387 // OCSPStaple contains an optional OCSP response which will be served 388 // to clients that request it. 389 OCSPStaple []byte 390 // Leaf is the parsed form of the leaf certificate, which may be 391 // initialized using x509.ParseCertificate to reduce per-handshake 392 // processing for TLS clients doing client authentication. If nil, the 393 // leaf certificate will be parsed as needed. 394 Leaf *x509.Certificate 395 } 396 397 // A TLS record. 398 type record struct { 399 contentType recordType 400 major, minor uint8 401 payload []byte 402 } 403 404 type handshakeMessage interface { 405 marshal() []byte 406 unmarshal([]byte) bool 407 } 408 409 // TODO(jsing): Make these available to both crypto/x509 and crypto/tls. 410 type dsaSignature struct { 411 R, S *big.Int 412 } 413 414 type ecdsaSignature dsaSignature 415 416 var emptyConfig Config 417 418 func defaultConfig() *Config { 419 return &emptyConfig 420 } 421 422 var ( 423 once sync.Once 424 varDefaultCipherSuites []uint16 425 ) 426 427 func defaultCipherSuites() []uint16 { 428 once.Do(initDefaultCipherSuites) 429 return varDefaultCipherSuites 430 } 431 432 func initDefaultCipherSuites() { 433 varDefaultCipherSuites = make([]uint16, len(cipherSuites)) 434 for i, suite := range cipherSuites { 435 varDefaultCipherSuites[i] = suite.id 436 } 437 }