1
2
3
4
5 package tls
6
7 import (
8 "crypto"
9 "crypto/rsa"
10 "crypto/subtle"
11 "crypto/x509"
12 "io"
13 "os"
14 )
15
16 func (c *Conn) clientHandshake() os.Error {
17 finishedHash := newFinishedHash()
18
19 if c.config == nil {
20 c.config = defaultConfig()
21 }
22
23 hello := &clientHelloMsg{
24 vers: maxVersion,
25 cipherSuites: c.config.cipherSuites(),
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,
33 }
34
35 t := uint32(c.config.time())
36 hello.random[0] = byte(t >> 24)
37 hello.random[1] = byte(t >> 16)
38 hello.random[2] = byte(t >> 8)
39 hello.random[3] = byte(t)
40 _, err := io.ReadFull(c.config.rand(), hello.random[4:])
41 if err != nil {
42 c.sendAlert(alertInternalError)
43 return os.NewError("short read from Rand")
44 }
45
46 finishedHash.Write(hello.marshal())
47 c.writeRecord(recordTypeHandshake, hello.marshal())
48
49 msg, err := c.readHandshake()
50 if err != nil {
51 return err
52 }
53 serverHello, ok := msg.(*serverHelloMsg)
54 if !ok {
55 return c.sendAlert(alertUnexpectedMessage)
56 }
57 finishedHash.Write(serverHello.marshal())
58
59 vers, ok := mutualVersion(serverHello.vers)
60 if !ok {
61 return c.sendAlert(alertProtocolVersion)
62 }
63 c.vers = vers
64 c.haveVers = true
65
66 if serverHello.compressionMethod != compressionNone {
67 return c.sendAlert(alertUnexpectedMessage)
68 }
69
70 if !hello.nextProtoNeg && serverHello.nextProtoNeg {
71 c.sendAlert(alertHandshakeFailure)
72 return os.NewError("server advertised unrequested NPN")
73 }
74
75 suite, suiteId := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
76 if suite == nil {
77 return c.sendAlert(alertHandshakeFailure)
78 }
79
80 msg, err = c.readHandshake()
81 if err != nil {
82 return err
83 }
84 certMsg, ok := msg.(*certificateMsg)
85 if !ok || len(certMsg.certificates) == 0 {
86 return c.sendAlert(alertUnexpectedMessage)
87 }
88 finishedHash.Write(certMsg.marshal())
89
90 certs := make([]*x509.Certificate, len(certMsg.certificates))
91 for i, asn1Data := range certMsg.certificates {
92 cert, err := x509.ParseCertificate(asn1Data)
93 if err != nil {
94 c.sendAlert(alertBadCertificate)
95 return os.NewError("failed to parse certificate from server: " + err.String())
96 }
97 certs[i] = cert
98 }
99
100
101
102 if c.config.RootCAs != nil {
103 opts := x509.VerifyOptions{
104 Roots: c.config.RootCAs,
105 CurrentTime: c.config.time(),
106 DNSName: c.config.ServerName,
107 Intermediates: x509.NewCertPool(),
108 }
109
110 for i, cert := range certs {
111 if i == 0 {
112 continue
113 }
114 opts.Intermediates.AddCert(cert)
115 }
116 c.verifiedChains, err = certs[0].Verify(opts)
117 if err != nil {
118 c.sendAlert(alertBadCertificate)
119 return err
120 }
121 }
122
123 if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok {
124 return c.sendAlert(alertUnsupportedCertificate)
125 }
126
127 c.peerCertificates = certs
128
129 if serverHello.ocspStapling {
130 msg, err = c.readHandshake()
131 if err != nil {
132 return err
133 }
134 cs, ok := msg.(*certificateStatusMsg)
135 if !ok {
136 return c.sendAlert(alertUnexpectedMessage)
137 }
138 finishedHash.Write(cs.marshal())
139
140 if cs.statusType == statusTypeOCSP {
141 c.ocspResponse = cs.response
142 }
143 }
144
145 msg, err = c.readHandshake()
146 if err != nil {
147 return err
148 }
149
150 keyAgreement := suite.ka()
151
152 skx, ok := msg.(*serverKeyExchangeMsg)
153 if ok {
154 finishedHash.Write(skx.marshal())
155 err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx)
156 if err != nil {
157 c.sendAlert(alertUnexpectedMessage)
158 return err
159 }
160
161 msg, err = c.readHandshake()
162 if err != nil {
163 return err
164 }
165 }
166
167 transmitCert := false
168 certReq, ok := msg.(*certificateRequestMsg)
169 if ok {
170
171 rsaAvail := false
172 for _, certType := range certReq.certificateTypes {
173 if certType == certTypeRSASign {
174 rsaAvail = true
175 break
176 }
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191 if rsaAvail && len(certReq.certificateAuthorities) == 0 {
192 transmitCert = true
193 }
194
195 finishedHash.Write(certReq.marshal())
196
197 msg, err = c.readHandshake()
198 if err != nil {
199 return err
200 }
201 }
202
203 shd, ok := msg.(*serverHelloDoneMsg)
204 if !ok {
205 return c.sendAlert(alertUnexpectedMessage)
206 }
207 finishedHash.Write(shd.marshal())
208
209 var cert *x509.Certificate
210 if transmitCert {
211 certMsg = new(certificateMsg)
212 if len(c.config.Certificates) > 0 {
213 cert, err = x509.ParseCertificate(c.config.Certificates[0].Certificate[0])
214 if err == nil && cert.PublicKeyAlgorithm == x509.RSA {
215 certMsg.certificates = c.config.Certificates[0].Certificate
216 } else {
217 cert = nil
218 }
219 }
220 finishedHash.Write(certMsg.marshal())
221 c.writeRecord(recordTypeHandshake, certMsg.marshal())
222 }
223
224 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0])
225 if err != nil {
226 c.sendAlert(alertInternalError)
227 return err
228 }
229 if ckx != nil {
230 finishedHash.Write(ckx.marshal())
231 c.writeRecord(recordTypeHandshake, ckx.marshal())
232 }
233
234 if cert != nil {
235 certVerify := new(certificateVerifyMsg)
236 var digest [36]byte
237 copy(digest[0:16], finishedHash.serverMD5.Sum())
238 copy(digest[16:36], finishedHash.serverSHA1.Sum())
239 signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest[0:])
240 if err != nil {
241 return c.sendAlert(alertInternalError)
242 }
243 certVerify.signature = signed
244
245 finishedHash.Write(certVerify.marshal())
246 c.writeRecord(recordTypeHandshake, certVerify.marshal())
247 }
248
249 masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
250 keysFromPreMasterSecret10(preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
251
252 clientCipher := suite.cipher(clientKey, clientIV, false )
253 clientHash := suite.mac(clientMAC)
254 c.out.prepareCipherSpec(clientCipher, clientHash)
255 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
256
257 if serverHello.nextProtoNeg {
258 nextProto := new(nextProtoMsg)
259 proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos)
260 nextProto.proto = proto
261 c.clientProtocol = proto
262 c.clientProtocolFallback = fallback
263
264 finishedHash.Write(nextProto.marshal())
265 c.writeRecord(recordTypeHandshake, nextProto.marshal())
266 }
267
268 finished := new(finishedMsg)
269 finished.verifyData = finishedHash.clientSum(masterSecret)
270 finishedHash.Write(finished.marshal())
271 c.writeRecord(recordTypeHandshake, finished.marshal())
272
273 serverCipher := suite.cipher(serverKey, serverIV, true )
274 serverHash := suite.mac(serverMAC)
275 c.in.prepareCipherSpec(serverCipher, serverHash)
276 c.readRecord(recordTypeChangeCipherSpec)
277 if c.err != nil {
278 return c.err
279 }
280
281 msg, err = c.readHandshake()
282 if err != nil {
283 return err
284 }
285 serverFinished, ok := msg.(*finishedMsg)
286 if !ok {
287 return c.sendAlert(alertUnexpectedMessage)
288 }
289
290 verify := finishedHash.serverSum(masterSecret)
291 if len(verify) != len(serverFinished.verifyData) ||
292 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
293 return c.sendAlert(alertHandshakeFailure)
294 }
295
296 c.handshakeComplete = true
297 c.cipherSuite = suiteId
298 return nil
299 }
300
301
302
303
304
305 func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
306 for _, s := range serverProtos {
307 for _, c := range clientProtos {
308 if s == c {
309 return s, false
310 }
311 }
312 }
313
314 return clientProtos[0], true
315 }