Daily bump.
[official-gcc.git] / libgo / go / crypto / tls / handshake_client.go
blob85e4adefcb0944a8c88a200ebabd311fbca9c97a
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.
5 package tls
7 import (
8 "bytes"
9 "crypto/ecdsa"
10 "crypto/rsa"
11 "crypto/subtle"
12 "crypto/x509"
13 "encoding/asn1"
14 "errors"
15 "io"
16 "strconv"
19 func (c *Conn) clientHandshake() error {
20 if c.config == nil {
21 c.config = defaultConfig()
24 hello := &clientHelloMsg{
25 vers: c.config.maxVersion(),
26 compressionMethods: []uint8{compressionNone},
27 random: make([]byte, 32),
28 ocspStapling: true,
29 serverName: c.config.ServerName,
30 supportedCurves: []uint16{curveP256, curveP384, curveP521},
31 supportedPoints: []uint8{pointFormatUncompressed},
32 nextProtoNeg: len(c.config.NextProtos) > 0,
35 possibleCipherSuites := c.config.cipherSuites()
36 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
38 NextCipherSuite:
39 for _, suiteId := range possibleCipherSuites {
40 for _, suite := range cipherSuites {
41 if suite.id != suiteId {
42 continue
44 // Don't advertise TLS 1.2-only cipher suites unless
45 // we're attempting TLS 1.2.
46 if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
47 continue
49 hello.cipherSuites = append(hello.cipherSuites, suiteId)
50 continue NextCipherSuite
54 t := uint32(c.config.time().Unix())
55 hello.random[0] = byte(t >> 24)
56 hello.random[1] = byte(t >> 16)
57 hello.random[2] = byte(t >> 8)
58 hello.random[3] = byte(t)
59 _, err := io.ReadFull(c.config.rand(), hello.random[4:])
60 if err != nil {
61 c.sendAlert(alertInternalError)
62 return errors.New("short read from Rand")
65 if hello.vers >= VersionTLS12 {
66 hello.signatureAndHashes = supportedSKXSignatureAlgorithms
69 c.writeRecord(recordTypeHandshake, hello.marshal())
71 msg, err := c.readHandshake()
72 if err != nil {
73 return err
75 serverHello, ok := msg.(*serverHelloMsg)
76 if !ok {
77 return c.sendAlert(alertUnexpectedMessage)
80 vers, ok := c.config.mutualVersion(serverHello.vers)
81 if !ok || vers < VersionTLS10 {
82 // TLS 1.0 is the minimum version supported as a client.
83 return c.sendAlert(alertProtocolVersion)
85 c.vers = vers
86 c.haveVers = true
88 finishedHash := newFinishedHash(c.vers)
89 finishedHash.Write(hello.marshal())
90 finishedHash.Write(serverHello.marshal())
92 if serverHello.compressionMethod != compressionNone {
93 return c.sendAlert(alertUnexpectedMessage)
96 if !hello.nextProtoNeg && serverHello.nextProtoNeg {
97 c.sendAlert(alertHandshakeFailure)
98 return errors.New("server advertised unrequested NPN")
101 suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
102 if suite == nil {
103 return c.sendAlert(alertHandshakeFailure)
106 msg, err = c.readHandshake()
107 if err != nil {
108 return err
110 certMsg, ok := msg.(*certificateMsg)
111 if !ok || len(certMsg.certificates) == 0 {
112 return c.sendAlert(alertUnexpectedMessage)
114 finishedHash.Write(certMsg.marshal())
116 certs := make([]*x509.Certificate, len(certMsg.certificates))
117 for i, asn1Data := range certMsg.certificates {
118 cert, err := x509.ParseCertificate(asn1Data)
119 if err != nil {
120 c.sendAlert(alertBadCertificate)
121 return errors.New("failed to parse certificate from server: " + err.Error())
123 certs[i] = cert
126 if !c.config.InsecureSkipVerify {
127 opts := x509.VerifyOptions{
128 Roots: c.config.RootCAs,
129 CurrentTime: c.config.time(),
130 DNSName: c.config.ServerName,
131 Intermediates: x509.NewCertPool(),
134 for i, cert := range certs {
135 if i == 0 {
136 continue
138 opts.Intermediates.AddCert(cert)
140 c.verifiedChains, err = certs[0].Verify(opts)
141 if err != nil {
142 c.sendAlert(alertBadCertificate)
143 return err
147 switch certs[0].PublicKey.(type) {
148 case *rsa.PublicKey, *ecdsa.PublicKey:
149 break
150 default:
151 return c.sendAlert(alertUnsupportedCertificate)
154 c.peerCertificates = certs
156 if serverHello.ocspStapling {
157 msg, err = c.readHandshake()
158 if err != nil {
159 return err
161 cs, ok := msg.(*certificateStatusMsg)
162 if !ok {
163 return c.sendAlert(alertUnexpectedMessage)
165 finishedHash.Write(cs.marshal())
167 if cs.statusType == statusTypeOCSP {
168 c.ocspResponse = cs.response
172 msg, err = c.readHandshake()
173 if err != nil {
174 return err
177 keyAgreement := suite.ka(c.vers)
179 skx, ok := msg.(*serverKeyExchangeMsg)
180 if ok {
181 finishedHash.Write(skx.marshal())
182 err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx)
183 if err != nil {
184 c.sendAlert(alertUnexpectedMessage)
185 return err
188 msg, err = c.readHandshake()
189 if err != nil {
190 return err
194 var chainToSend *Certificate
195 var certRequested bool
196 certReq, ok := msg.(*certificateRequestMsg)
197 if ok {
198 certRequested = true
200 // RFC 4346 on the certificateAuthorities field:
201 // A list of the distinguished names of acceptable certificate
202 // authorities. These distinguished names may specify a desired
203 // distinguished name for a root CA or for a subordinate CA;
204 // thus, this message can be used to describe both known roots
205 // and a desired authorization space. If the
206 // certificate_authorities list is empty then the client MAY
207 // send any certificate of the appropriate
208 // ClientCertificateType, unless there is some external
209 // arrangement to the contrary.
211 finishedHash.Write(certReq.marshal())
213 var rsaAvail, ecdsaAvail bool
214 for _, certType := range certReq.certificateTypes {
215 switch certType {
216 case certTypeRSASign:
217 rsaAvail = true
218 case certTypeECDSASign:
219 ecdsaAvail = true
223 // We need to search our list of client certs for one
224 // where SignatureAlgorithm is RSA and the Issuer is in
225 // certReq.certificateAuthorities
226 findCert:
227 for i, chain := range c.config.Certificates {
228 if !rsaAvail && !ecdsaAvail {
229 continue
232 for j, cert := range chain.Certificate {
233 x509Cert := chain.Leaf
234 // parse the certificate if this isn't the leaf
235 // node, or if chain.Leaf was nil
236 if j != 0 || x509Cert == nil {
237 if x509Cert, err = x509.ParseCertificate(cert); err != nil {
238 c.sendAlert(alertInternalError)
239 return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
243 switch {
244 case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
245 case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
246 default:
247 continue findCert
250 if len(certReq.certificateAuthorities) == 0 {
251 // they gave us an empty list, so just take the
252 // first RSA cert from c.config.Certificates
253 chainToSend = &chain
254 break findCert
257 for _, ca := range certReq.certificateAuthorities {
258 if bytes.Equal(x509Cert.RawIssuer, ca) {
259 chainToSend = &chain
260 break findCert
266 msg, err = c.readHandshake()
267 if err != nil {
268 return err
272 shd, ok := msg.(*serverHelloDoneMsg)
273 if !ok {
274 return c.sendAlert(alertUnexpectedMessage)
276 finishedHash.Write(shd.marshal())
278 // If the server requested a certificate then we have to send a
279 // Certificate message, even if it's empty because we don't have a
280 // certificate to send.
281 if certRequested {
282 certMsg = new(certificateMsg)
283 if chainToSend != nil {
284 certMsg.certificates = chainToSend.Certificate
286 finishedHash.Write(certMsg.marshal())
287 c.writeRecord(recordTypeHandshake, certMsg.marshal())
290 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0])
291 if err != nil {
292 c.sendAlert(alertInternalError)
293 return err
295 if ckx != nil {
296 finishedHash.Write(ckx.marshal())
297 c.writeRecord(recordTypeHandshake, ckx.marshal())
300 if chainToSend != nil {
301 var signed []byte
302 certVerify := &certificateVerifyMsg{
303 hasSignatureAndHash: c.vers >= VersionTLS12,
306 switch key := c.config.Certificates[0].PrivateKey.(type) {
307 case *ecdsa.PrivateKey:
308 digest, _, hashId := finishedHash.hashForClientCertificate(signatureECDSA)
309 r, s, err := ecdsa.Sign(c.config.rand(), key, digest)
310 if err == nil {
311 signed, err = asn1.Marshal(ecdsaSignature{r, s})
313 certVerify.signatureAndHash.signature = signatureECDSA
314 certVerify.signatureAndHash.hash = hashId
315 case *rsa.PrivateKey:
316 digest, hashFunc, hashId := finishedHash.hashForClientCertificate(signatureRSA)
317 signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
318 certVerify.signatureAndHash.signature = signatureRSA
319 certVerify.signatureAndHash.hash = hashId
320 default:
321 err = errors.New("unknown private key type")
323 if err != nil {
324 return c.sendAlert(alertInternalError)
326 certVerify.signature = signed
328 finishedHash.Write(certVerify.marshal())
329 c.writeRecord(recordTypeHandshake, certVerify.marshal())
332 masterSecret := masterFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random)
333 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
334 keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
336 var clientCipher interface{}
337 var clientHash macFunction
338 if suite.cipher != nil {
339 clientCipher = suite.cipher(clientKey, clientIV, false /* not for reading */)
340 clientHash = suite.mac(c.vers, clientMAC)
341 } else {
342 clientCipher = suite.aead(clientKey, clientIV)
344 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
345 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
347 if serverHello.nextProtoNeg {
348 nextProto := new(nextProtoMsg)
349 proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos)
350 nextProto.proto = proto
351 c.clientProtocol = proto
352 c.clientProtocolFallback = fallback
354 finishedHash.Write(nextProto.marshal())
355 c.writeRecord(recordTypeHandshake, nextProto.marshal())
358 finished := new(finishedMsg)
359 finished.verifyData = finishedHash.clientSum(masterSecret)
360 finishedHash.Write(finished.marshal())
361 c.writeRecord(recordTypeHandshake, finished.marshal())
363 var serverCipher interface{}
364 var serverHash macFunction
365 if suite.cipher != nil {
366 serverCipher = suite.cipher(serverKey, serverIV, true /* for reading */)
367 serverHash = suite.mac(c.vers, serverMAC)
368 } else {
369 serverCipher = suite.aead(serverKey, serverIV)
371 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
372 c.readRecord(recordTypeChangeCipherSpec)
373 if err := c.error(); err != nil {
374 return err
377 msg, err = c.readHandshake()
378 if err != nil {
379 return err
381 serverFinished, ok := msg.(*finishedMsg)
382 if !ok {
383 return c.sendAlert(alertUnexpectedMessage)
386 verify := finishedHash.serverSum(masterSecret)
387 if len(verify) != len(serverFinished.verifyData) ||
388 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
389 return c.sendAlert(alertHandshakeFailure)
392 c.handshakeComplete = true
393 c.cipherSuite = suite.id
394 return nil
397 // mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
398 // set of client and server supported protocols. The set of client supported
399 // protocols must not be empty. It returns the resulting protocol and flag
400 // indicating if the fallback case was reached.
401 func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
402 for _, s := range serverProtos {
403 for _, c := range clientProtos {
404 if s == c {
405 return s, false
410 return clientProtos[0], true