Source file src/pkg/crypto/tls/handshake_client.go
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, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
282 keysFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
283
284 clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */)
285 clientHash := suite.mac(c.vers, clientMAC)
286 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
287 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
288
289 if serverHello.nextProtoNeg {
290 nextProto := new(nextProtoMsg)
291 proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos)
292 nextProto.proto = proto
293 c.clientProtocol = proto
294 c.clientProtocolFallback = fallback
295
296 finishedHash.Write(nextProto.marshal())
297 c.writeRecord(recordTypeHandshake, nextProto.marshal())
298 }
299
300 finished := new(finishedMsg)
301 finished.verifyData = finishedHash.clientSum(masterSecret)
302 finishedHash.Write(finished.marshal())
303 c.writeRecord(recordTypeHandshake, finished.marshal())
304
305 serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */)
306 serverHash := suite.mac(c.vers, serverMAC)
307 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
308 c.readRecord(recordTypeChangeCipherSpec)
309 if c.err != nil {
310 return c.err
311 }
312
313 msg, err = c.readHandshake()
314 if err != nil {
315 return err
316 }
317 serverFinished, ok := msg.(*finishedMsg)
318 if !ok {
319 return c.sendAlert(alertUnexpectedMessage)
320 }
321
322 verify := finishedHash.serverSum(masterSecret)
323 if len(verify) != len(serverFinished.verifyData) ||
324 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
325 return c.sendAlert(alertHandshakeFailure)
326 }
327
328 c.handshakeComplete = true
329 c.cipherSuite = suite.id
330 return nil
331 }
332
333 // mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
334 // set of client and server supported protocols. The set of client supported
335 // protocols must not be empty. It returns the resulting protocol and flag
336 // indicating if the fallback case was reached.
337 func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
338 for _, s := range serverProtos {
339 for _, c := range clientProtos {
340 if s == c {
341 return s, false
342 }
343 }
344 }
345
346 return clientProtos[0], true
347 }