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.
17 func (c
*Conn
) clientHandshake() os
.Error
{
18 finishedHash
:= newFinishedHash()
21 c
.config
= defaultConfig()
24 hello
:= &clientHelloMsg
{
26 cipherSuites
: []uint16{TLS_RSA_WITH_RC4_128_SHA
},
27 compressionMethods
: []uint8{compressionNone
},
28 random
: make([]byte, 32),
30 serverName
: c
.config
.ServerName
,
33 t
:= uint32(c
.config
.Time())
34 hello
.random
[0] = byte(t
>> 24)
35 hello
.random
[1] = byte(t
>> 16)
36 hello
.random
[2] = byte(t
>> 8)
37 hello
.random
[3] = byte(t
)
38 _
, err
:= io
.ReadFull(c
.config
.Rand
, hello
.random
[4:])
40 c
.sendAlert(alertInternalError
)
41 return os
.ErrorString("short read from Rand")
44 finishedHash
.Write(hello
.marshal())
45 c
.writeRecord(recordTypeHandshake
, hello
.marshal())
47 msg
, err
:= c
.readHandshake()
51 serverHello
, ok
:= msg
.(*serverHelloMsg
)
53 return c
.sendAlert(alertUnexpectedMessage
)
55 finishedHash
.Write(serverHello
.marshal())
57 vers
, ok
:= mutualVersion(serverHello
.vers
)
59 c
.sendAlert(alertProtocolVersion
)
64 if serverHello
.cipherSuite
!= TLS_RSA_WITH_RC4_128_SHA ||
65 serverHello
.compressionMethod
!= compressionNone
{
66 return c
.sendAlert(alertUnexpectedMessage
)
69 msg
, err
= c
.readHandshake()
73 certMsg
, ok
:= msg
.(*certificateMsg
)
74 if !ok ||
len(certMsg
.certificates
) == 0 {
75 return c
.sendAlert(alertUnexpectedMessage
)
77 finishedHash
.Write(certMsg
.marshal())
79 certs
:= make([]*x509
.Certificate
, len(certMsg
.certificates
))
81 for i
, asn1Data
:= range certMsg
.certificates
{
82 cert
, err
:= x509
.ParseCertificate(asn1Data
)
84 c
.sendAlert(alertBadCertificate
)
85 return os
.ErrorString("failed to parse certificate from server: " + err
.String())
91 // If we don't have a root CA set configured then anything is accepted.
92 // TODO(rsc): Find certificates for OS X 10.6.
93 for cur
:= certs
[0]; c
.config
.RootCAs
!= nil; {
94 parent
:= c
.config
.RootCAs
.FindVerifiedParent(cur
)
99 parent
= chain
.FindVerifiedParent(cur
)
101 c
.sendAlert(alertBadCertificate
)
102 return os
.ErrorString("could not find root certificate for chain")
105 if !parent
.BasicConstraintsValid ||
!parent
.IsCA
{
106 c
.sendAlert(alertBadCertificate
)
107 return os
.ErrorString("intermediate certificate does not have CA bit set")
109 // KeyUsage status flags are ignored. From Engineering
110 // Security, Peter Gutmann: A European government CA marked its
111 // signing certificates as being valid for encryption only, but
112 // no-one noticed. Another European CA marked its signature
113 // keys as not being valid for signatures. A different CA
114 // marked its own trusted root certificate as being invalid for
115 // certificate signing. Another national CA distributed a
116 // certificate to be used to encrypt data for the country’s tax
117 // authority that was marked as only being usable for digital
118 // signatures but not for encryption. Yet another CA reversed
119 // the order of the bit flags in the keyUsage due to confusion
120 // over encoding endianness, essentially setting a random
121 // keyUsage in certificates that it issued. Another CA created
122 // a self-invalidating certificate by adding a certificate
123 // policy statement stipulating that the certificate had to be
124 // used strictly as specified in the keyUsage, and a keyUsage
125 // containing a flag indicating that the RSA encryption key
126 // could only be used for Diffie-Hellman key agreement.
131 pub
, ok
:= certs
[0].PublicKey
.(*rsa
.PublicKey
)
133 return c
.sendAlert(alertUnsupportedCertificate
)
136 c
.peerCertificates
= certs
138 if serverHello
.certStatus
{
139 msg
, err
= c
.readHandshake()
143 cs
, ok
:= msg
.(*certificateStatusMsg
)
145 return c
.sendAlert(alertUnexpectedMessage
)
147 finishedHash
.Write(cs
.marshal())
149 if cs
.statusType
== statusTypeOCSP
{
150 c
.ocspResponse
= cs
.response
154 msg
, err
= c
.readHandshake()
159 transmitCert
:= false
160 certReq
, ok
:= msg
.(*certificateRequestMsg
)
162 // We only accept certificates with RSA keys.
164 for _
, certType
:= range certReq
.certificateTypes
{
165 if certType
== certTypeRSASign
{
171 // For now, only send a certificate back if the server gives us an
172 // empty list of certificateAuthorities.
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; thus,
178 // this message can be used to describe both known roots and a
179 // desired authorization space. If the certificate_authorities
180 // list is empty then the client MAY send any certificate of the
181 // appropriate ClientCertificateType, unless there is some
182 // external arrangement to the contrary.
183 if rsaAvail
&& len(certReq
.certificateAuthorities
) == 0 {
187 finishedHash
.Write(certReq
.marshal())
189 msg
, err
= c
.readHandshake()
195 shd
, ok
:= msg
.(*serverHelloDoneMsg
)
197 return c
.sendAlert(alertUnexpectedMessage
)
199 finishedHash
.Write(shd
.marshal())
201 var cert
*x509
.Certificate
203 certMsg
= new(certificateMsg
)
204 if len(c
.config
.Certificates
) > 0 {
205 cert
, err
= x509
.ParseCertificate(c
.config
.Certificates
[0].Certificate
[0])
206 if err
== nil && cert
.PublicKeyAlgorithm
== x509
.RSA
{
207 certMsg
.certificates
= c
.config
.Certificates
[0].Certificate
212 finishedHash
.Write(certMsg
.marshal())
213 c
.writeRecord(recordTypeHandshake
, certMsg
.marshal())
216 ckx
:= new(clientKeyExchangeMsg
)
217 preMasterSecret
:= make([]byte, 48)
218 preMasterSecret
[0] = byte(hello
.vers
>> 8)
219 preMasterSecret
[1] = byte(hello
.vers
)
220 _
, err
= io
.ReadFull(c
.config
.Rand
, preMasterSecret
[2:])
222 return c
.sendAlert(alertInternalError
)
225 ckx
.ciphertext
, err
= rsa
.EncryptPKCS1v15(c
.config
.Rand
, pub
, preMasterSecret
)
227 return c
.sendAlert(alertInternalError
)
230 finishedHash
.Write(ckx
.marshal())
231 c
.writeRecord(recordTypeHandshake
, ckx
.marshal())
234 certVerify
:= new(certificateVerifyMsg
)
236 copy(digest
[0:16], finishedHash
.serverMD5
.Sum())
237 copy(digest
[16:36], finishedHash
.serverSHA1
.Sum())
238 signed
, err
:= rsa
.SignPKCS1v15(c
.config
.Rand
, c
.config
.Certificates
[0].PrivateKey
, rsa
.HashMD5SHA1
, digest
[0:])
240 return c
.sendAlert(alertInternalError
)
242 certVerify
.signature
= signed
244 finishedHash
.Write(certVerify
.marshal())
245 c
.writeRecord(recordTypeHandshake
, certVerify
.marshal())
248 suite
:= cipherSuites
[0]
249 masterSecret
, clientMAC
, serverMAC
, clientKey
, serverKey
:=
250 keysFromPreMasterSecret11(preMasterSecret
, hello
.random
, serverHello
.random
, suite
.hashLength
, suite
.cipherKeyLength
)
252 cipher
, _
:= rc4
.NewCipher(clientKey
)
254 c
.out
.prepareCipherSpec(cipher
, hmac
.NewSHA1(clientMAC
))
255 c
.writeRecord(recordTypeChangeCipherSpec
, []byte{1})
257 finished
:= new(finishedMsg
)
258 finished
.verifyData
= finishedHash
.clientSum(masterSecret
)
259 finishedHash
.Write(finished
.marshal())
260 c
.writeRecord(recordTypeHandshake
, finished
.marshal())
262 cipher2
, _
:= rc4
.NewCipher(serverKey
)
263 c
.in
.prepareCipherSpec(cipher2
, hmac
.NewSHA1(serverMAC
))
264 c
.readRecord(recordTypeChangeCipherSpec
)
269 msg
, err
= c
.readHandshake()
273 serverFinished
, ok
:= msg
.(*finishedMsg
)
275 return c
.sendAlert(alertUnexpectedMessage
)
278 verify
:= finishedHash
.serverSum(masterSecret
)
279 if len(verify
) != len(serverFinished
.verifyData
) ||
280 subtle
.ConstantTimeCompare(verify
, serverFinished
.verifyData
) != 1 {
281 return c
.sendAlert(alertHandshakeFailure
)
284 c
.handshakeComplete
= true
285 c
.cipherSuite
= TLS_RSA_WITH_RC4_128_SHA