github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/crypto/tls/handshake_client.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 "bytes" 9 "crypto" 10 "crypto/rsa" 11 "crypto/subtle" 12 "crypto/x509" 13 "errors" 14 "io" 15 "strconv" 16 ) 17 18 func (c *Conn) clientHandshake() error { 19 finishedHash := newFinishedHash(versionTLS10) 20 21 if c.config == nil { 22 c.config = defaultConfig() 23 } 24 25 hello := &clientHelloMsg{ 26 vers: maxVersion, 27 cipherSuites: c.config.cipherSuites(), 28 compressionMethods: []uint8{compressionNone}, 29 random: make([]byte, 32), 30 ocspStapling: true, 31 serverName: c.config.ServerName, 32 supportedCurves: []uint16{curveP256, curveP384, curveP521}, 33 supportedPoints: []uint8{pointFormatUncompressed}, 34 nextProtoNeg: len(c.config.NextProtos) > 0, 35 } 36 37 t := uint32(c.config.time().Unix()) 38 hello.random[0] = byte(t >> 24) 39 hello.random[1] = byte(t >> 16) 40 hello.random[2] = byte(t >> 8) 41 hello.random[3] = byte(t) 42 _, err := io.ReadFull(c.config.rand(), hello.random[4:]) 43 if err != nil { 44 c.sendAlert(alertInternalError) 45 return errors.New("short read from Rand") 46 } 47 48 finishedHash.Write(hello.marshal()) 49 c.writeRecord(recordTypeHandshake, hello.marshal()) 50 51 msg, err := c.readHandshake() 52 if err != nil { 53 return err 54 } 55 serverHello, ok := msg.(*serverHelloMsg) 56 if !ok { 57 return c.sendAlert(alertUnexpectedMessage) 58 } 59 finishedHash.Write(serverHello.marshal()) 60 61 vers, ok := mutualVersion(serverHello.vers) 62 if !ok || vers < versionTLS10 { 63 // TLS 1.0 is the minimum version supported as a client. 64 return c.sendAlert(alertProtocolVersion) 65 } 66 c.vers = vers 67 c.haveVers = true 68 69 if serverHello.compressionMethod != compressionNone { 70 return c.sendAlert(alertUnexpectedMessage) 71 } 72 73 if !hello.nextProtoNeg && serverHello.nextProtoNeg { 74 c.sendAlert(alertHandshakeFailure) 75 return errors.New("server advertised unrequested NPN") 76 } 77 78 suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite) 79 if suite == nil { 80 return c.sendAlert(alertHandshakeFailure) 81 } 82 83 msg, err = c.readHandshake() 84 if err != nil { 85 return err 86 } 87 certMsg, ok := msg.(*certificateMsg) 88 if !ok || len(certMsg.certificates) == 0 { 89 return c.sendAlert(alertUnexpectedMessage) 90 } 91 finishedHash.Write(certMsg.marshal()) 92 93 certs := make([]*x509.Certificate, len(certMsg.certificates)) 94 for i, asn1Data := range certMsg.certificates { 95 cert, err := x509.ParseCertificate(asn1Data) 96 if err != nil { 97 c.sendAlert(alertBadCertificate) 98 return errors.New("failed to parse certificate from server: " + err.Error()) 99 } 100 certs[i] = cert 101 } 102 103 if !c.config.InsecureSkipVerify { 104 opts := x509.VerifyOptions{ 105 Roots: c.config.RootCAs, 106 CurrentTime: c.config.time(), 107 DNSName: c.config.ServerName, 108 Intermediates: x509.NewCertPool(), 109 } 110 111 for i, cert := range certs { 112 if i == 0 { 113 continue 114 } 115 opts.Intermediates.AddCert(cert) 116 } 117 c.verifiedChains, err = certs[0].Verify(opts) 118 if err != nil { 119 c.sendAlert(alertBadCertificate) 120 return err 121 } 122 } 123 124 if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok { 125 return c.sendAlert(alertUnsupportedCertificate) 126 } 127 128 c.peerCertificates = certs 129 130 if serverHello.ocspStapling { 131 msg, err = c.readHandshake() 132 if err != nil { 133 return err 134 } 135 cs, ok := msg.(*certificateStatusMsg) 136 if !ok { 137 return c.sendAlert(alertUnexpectedMessage) 138 } 139 finishedHash.Write(cs.marshal()) 140 141 if cs.statusType == statusTypeOCSP { 142 c.ocspResponse = cs.response 143 } 144 } 145 146 msg, err = c.readHandshake() 147 if err != nil { 148 return err 149 } 150 151 keyAgreement := suite.ka() 152 153 skx, ok := msg.(*serverKeyExchangeMsg) 154 if ok { 155 finishedHash.Write(skx.marshal()) 156 err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx) 157 if err != nil { 158 c.sendAlert(alertUnexpectedMessage) 159 return err 160 } 161 162 msg, err = c.readHandshake() 163 if err != nil { 164 return err 165 } 166 } 167 168 var certToSend *Certificate 169 var certRequested bool 170 certReq, ok := msg.(*certificateRequestMsg) 171 if ok { 172 certRequested = true 173 174 // RFC 4346 on the certificateAuthorities field: 175 // A list of the distinguished names of acceptable certificate 176 // authorities. These distinguished names may specify a desired 177 // distinguished name for a root CA or for a subordinate CA; 178 // thus, this message can be used to describe both known roots 179 // and a desired authorization space. If the 180 // certificate_authorities list is empty then the client MAY 181 // send any certificate of the appropriate 182 // ClientCertificateType, unless there is some external 183 // arrangement to the contrary. 184 185 finishedHash.Write(certReq.marshal()) 186 187 // For now, we only know how to sign challenges with RSA 188 rsaAvail := false 189 for _, certType := range certReq.certificateTypes { 190 if certType == certTypeRSASign { 191 rsaAvail = true 192 break 193 } 194 } 195 196 // We need to search our list of client certs for one 197 // where SignatureAlgorithm is RSA and the Issuer is in 198 // certReq.certificateAuthorities 199 findCert: 200 for i, cert := range c.config.Certificates { 201 if !rsaAvail { 202 continue 203 } 204 205 leaf := cert.Leaf 206 if leaf == nil { 207 if leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil { 208 c.sendAlert(alertInternalError) 209 return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) 210 } 211 } 212 213 if leaf.PublicKeyAlgorithm != x509.RSA { 214 continue 215 } 216 217 if len(certReq.certificateAuthorities) == 0 { 218 // they gave us an empty list, so just take the 219 // first RSA cert from c.config.Certificates 220 certToSend = &cert 221 break 222 } 223 224 for _, ca := range certReq.certificateAuthorities { 225 if bytes.Equal(leaf.RawIssuer, ca) { 226 certToSend = &cert 227 break findCert 228 } 229 } 230 } 231 232 msg, err = c.readHandshake() 233 if err != nil { 234 return err 235 } 236 } 237 238 shd, ok := msg.(*serverHelloDoneMsg) 239 if !ok { 240 return c.sendAlert(alertUnexpectedMessage) 241 } 242 finishedHash.Write(shd.marshal()) 243 244 // If the server requested a certificate then we have to send a 245 // Certificate message, even if it's empty because we don't have a 246 // certificate to send. 247 if certRequested { 248 certMsg = new(certificateMsg) 249 if certToSend != nil { 250 certMsg.certificates = certToSend.Certificate 251 } 252 finishedHash.Write(certMsg.marshal()) 253 c.writeRecord(recordTypeHandshake, certMsg.marshal()) 254 } 255 256 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0]) 257 if err != nil { 258 c.sendAlert(alertInternalError) 259 return err 260 } 261 if ckx != nil { 262 finishedHash.Write(ckx.marshal()) 263 c.writeRecord(recordTypeHandshake, ckx.marshal()) 264 } 265 266 if certToSend != nil { 267 certVerify := new(certificateVerifyMsg) 268 digest := make([]byte, 0, 36) 269 digest = finishedHash.serverMD5.Sum(digest) 270 digest = finishedHash.serverSHA1.Sum(digest) 271 signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, digest) 272 if err != nil { 273 return c.sendAlert(alertInternalError) 274 } 275 certVerify.signature = signed 276 277 finishedHash.Write(certVerify.marshal()) 278 c.writeRecord(recordTypeHandshake, certVerify.marshal()) 279 } 280 281 masterSecret := masterFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random) 282 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 283 keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen) 284 285 clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */) 286 clientHash := suite.mac(c.vers, clientMAC) 287 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) 288 c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 289 290 if serverHello.nextProtoNeg { 291 nextProto := new(nextProtoMsg) 292 proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos) 293 nextProto.proto = proto 294 c.clientProtocol = proto 295 c.clientProtocolFallback = fallback 296 297 finishedHash.Write(nextProto.marshal()) 298 c.writeRecord(recordTypeHandshake, nextProto.marshal()) 299 } 300 301 finished := new(finishedMsg) 302 finished.verifyData = finishedHash.clientSum(masterSecret) 303 finishedHash.Write(finished.marshal()) 304 c.writeRecord(recordTypeHandshake, finished.marshal()) 305 306 serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */) 307 serverHash := suite.mac(c.vers, serverMAC) 308 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) 309 c.readRecord(recordTypeChangeCipherSpec) 310 if err := c.error(); err != nil { 311 return err 312 } 313 314 msg, err = c.readHandshake() 315 if err != nil { 316 return err 317 } 318 serverFinished, ok := msg.(*finishedMsg) 319 if !ok { 320 return c.sendAlert(alertUnexpectedMessage) 321 } 322 323 verify := finishedHash.serverSum(masterSecret) 324 if len(verify) != len(serverFinished.verifyData) || 325 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { 326 return c.sendAlert(alertHandshakeFailure) 327 } 328 329 c.handshakeComplete = true 330 c.cipherSuite = suite.id 331 return nil 332 } 333 334 // mutualProtocol finds the mutual Next Protocol Negotiation protocol given the 335 // set of client and server supported protocols. The set of client supported 336 // protocols must not be empty. It returns the resulting protocol and flag 337 // indicating if the fallback case was reached. 338 func mutualProtocol(clientProtos, serverProtos []string) (string, bool) { 339 for _, s := range serverProtos { 340 for _, c := range clientProtos { 341 if s == c { 342 return s, false 343 } 344 } 345 } 346 347 return clientProtos[0], true 348 }