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