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.
19 func (c
*Conn
) clientHandshake() error
{
21 c
.config
= defaultConfig()
24 hello
:= &clientHelloMsg
{
25 vers
: c
.config
.maxVersion(),
26 compressionMethods
: []uint8{compressionNone
},
27 random
: make([]byte, 32),
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
))
39 for _
, suiteId
:= range possibleCipherSuites
{
40 for _
, suite
:= range cipherSuites
{
41 if suite
.id
!= suiteId
{
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 {
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:])
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()
75 serverHello
, ok
:= msg
.(*serverHelloMsg
)
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
)
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
)
103 return c
.sendAlert(alertHandshakeFailure
)
106 msg
, err
= c
.readHandshake()
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
)
120 c
.sendAlert(alertBadCertificate
)
121 return errors
.New("failed to parse certificate from server: " + err
.Error())
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
{
138 opts
.Intermediates
.AddCert(cert
)
140 c
.verifiedChains
, err
= certs
[0].Verify(opts
)
142 c
.sendAlert(alertBadCertificate
)
147 switch certs
[0].PublicKey
.(type) {
148 case *rsa
.PublicKey
, *ecdsa
.PublicKey
:
151 return c
.sendAlert(alertUnsupportedCertificate
)
154 c
.peerCertificates
= certs
156 if serverHello
.ocspStapling
{
157 msg
, err
= c
.readHandshake()
161 cs
, ok
:= msg
.(*certificateStatusMsg
)
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()
177 keyAgreement
:= suite
.ka(c
.vers
)
179 skx
, ok
:= msg
.(*serverKeyExchangeMsg
)
181 finishedHash
.Write(skx
.marshal())
182 err
= keyAgreement
.processServerKeyExchange(c
.config
, hello
, serverHello
, certs
[0], skx
)
184 c
.sendAlert(alertUnexpectedMessage
)
188 msg
, err
= c
.readHandshake()
194 var chainToSend
*Certificate
195 var certRequested
bool
196 certReq
, ok
:= msg
.(*certificateRequestMsg
)
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
{
216 case certTypeRSASign
:
218 case certTypeECDSASign
:
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
227 for i
, chain
:= range c
.config
.Certificates
{
228 if !rsaAvail
&& !ecdsaAvail
{
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())
244 case rsaAvail
&& x509Cert
.PublicKeyAlgorithm
== x509
.RSA
:
245 case ecdsaAvail
&& x509Cert
.PublicKeyAlgorithm
== x509
.ECDSA
:
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
257 for _
, ca
:= range certReq
.certificateAuthorities
{
258 if bytes
.Equal(x509Cert
.RawIssuer
, ca
) {
266 msg
, err
= c
.readHandshake()
272 shd
, ok
:= msg
.(*serverHelloDoneMsg
)
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.
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])
292 c
.sendAlert(alertInternalError
)
296 finishedHash
.Write(ckx
.marshal())
297 c
.writeRecord(recordTypeHandshake
, ckx
.marshal())
300 if chainToSend
!= nil {
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
)
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
321 err
= errors
.New("unknown private key type")
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
)
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
)
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 {
377 msg
, err
= c
.readHandshake()
381 serverFinished
, ok
:= msg
.(*finishedMsg
)
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
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
{
410 return clientProtos
[0], true