LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package tls | 5 package tls |
6 | 6 |
7 import ( | 7 import ( |
8 "crypto" | 8 "crypto" |
9 "crypto/rsa" | 9 "crypto/rsa" |
10 "crypto/subtle" | 10 "crypto/subtle" |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 c.writeRecord(recordTypeHandshake, certReq.marshal()) | 167 c.writeRecord(recordTypeHandshake, certReq.marshal()) |
168 } | 168 } |
169 | 169 |
170 helloDone := new(serverHelloDoneMsg) | 170 helloDone := new(serverHelloDoneMsg) |
171 finishedHash.Write(helloDone.marshal()) | 171 finishedHash.Write(helloDone.marshal()) |
172 c.writeRecord(recordTypeHandshake, helloDone.marshal()) | 172 c.writeRecord(recordTypeHandshake, helloDone.marshal()) |
173 | 173 |
174 var pub *rsa.PublicKey | 174 var pub *rsa.PublicKey |
175 | 175 |
176 // See if there is a client certificate | 176 // See if there is a client certificate |
177 var skipCert, skipRead bool | |
178 msg, err = c.readHandshake() | 177 msg, err = c.readHandshake() |
179 if err != nil { | 178 if err != nil { |
180 return err | 179 return err |
181 } | 180 } |
182 certMsg, ok = msg.(*certificateMsg) | 181 certMsg, ok = msg.(*certificateMsg) |
183 » if !ok { | 182 » if ok { |
184 » » // The message wasn't a cert... either die or recover with | |
185 » » // a handshake without a cert, depending on the policy. | |
186 » » if config.ClientAuth == RequireAnyClientCert || config.ClientAut
h == RequireAndVerifyClientCert { | |
187 » » » return c.sendAlert(alertHandshakeFailure) | |
188 » » } else { | |
189 » » » skipCert = true | |
190 » » » skipRead = true | |
191 » » } | |
192 » } | |
193 » if !skipCert { | |
194 // this is a cert message, so finish processing it | 183 // this is a cert message, so finish processing it |
195 finishedHash.Write(certMsg.marshal()) | 184 finishedHash.Write(certMsg.marshal()) |
196 | 185 |
197 certs := make([]*x509.Certificate, len(certMsg.certificates)) | 186 certs := make([]*x509.Certificate, len(certMsg.certificates)) |
198 for i, asn1Data := range certMsg.certificates { | 187 for i, asn1Data := range certMsg.certificates { |
199 cert, err := x509.ParseCertificate(asn1Data) | 188 cert, err := x509.ParseCertificate(asn1Data) |
200 if err != nil { | 189 if err != nil { |
201 c.sendAlert(alertBadCertificate) | 190 c.sendAlert(alertBadCertificate) |
202 return errors.New("could not parse client's cert
ificate: " + err.Error()) | 191 return errors.New("could not parse client's cert
ificate: " + err.Error()) |
203 } | 192 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 } | 234 } |
246 | 235 |
247 if len(certs) > 0 { | 236 if len(certs) > 0 { |
248 key, ok := certs[0].PublicKey.(*rsa.PublicKey) | 237 key, ok := certs[0].PublicKey.(*rsa.PublicKey) |
249 if !ok { | 238 if !ok { |
250 return c.sendAlert(alertUnsupportedCertificate) | 239 return c.sendAlert(alertUnsupportedCertificate) |
251 } | 240 } |
252 pub = key | 241 pub = key |
253 c.peerCertificates = certs | 242 c.peerCertificates = certs |
254 } | 243 } |
255 » } | 244 |
256 | 245 » » // finished processing offered cert, so get next message (proces
sing below) |
257 » // Get client key exchange (skipRead means that the last readHandshake | |
258 » // hasn't been processed yet because it turned out not to be a client ce
rt) | |
259 » if !skipRead { | |
260 msg, err = c.readHandshake() | 246 msg, err = c.readHandshake() |
261 » } | 247 » » if err != nil { |
262 » if err != nil { | 248 » » » return err |
263 » » return err | 249 » » } |
264 » } | 250 » } else { |
| 251 » » // The message wasn't a cert; depending on policy maybe die now |
| 252 » » if config.ClientAuth == RequireAnyClientCert || config.ClientAut
h == RequireAndVerifyClientCert { |
| 253 » » » return c.sendAlert(alertHandshakeFailure) |
| 254 » » } |
| 255 » } |
| 256 |
| 257 » // Get client key exchange |
265 ckx, ok := msg.(*clientKeyExchangeMsg) | 258 ckx, ok := msg.(*clientKeyExchangeMsg) |
266 if !ok { | 259 if !ok { |
267 return c.sendAlert(alertUnexpectedMessage) | 260 return c.sendAlert(alertUnexpectedMessage) |
268 } | 261 } |
269 finishedHash.Write(ckx.marshal()) | 262 finishedHash.Write(ckx.marshal()) |
270 | 263 |
271 // If we received a client cert in response to our certificate request m
essage, | 264 // If we received a client cert in response to our certificate request m
essage, |
272 // the client will send us a certificateVerifyMsg immediately after the | 265 // the client will send us a certificateVerifyMsg immediately after the |
273 // clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preced
ing | 266 // clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preced
ing |
274 // handshake-layer messages that is signed using the private key corresp
onding | 267 // handshake-layer messages that is signed using the private key corresp
onding |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 | 343 |
351 finished := new(finishedMsg) | 344 finished := new(finishedMsg) |
352 finished.verifyData = finishedHash.serverSum(masterSecret) | 345 finished.verifyData = finishedHash.serverSum(masterSecret) |
353 c.writeRecord(recordTypeHandshake, finished.marshal()) | 346 c.writeRecord(recordTypeHandshake, finished.marshal()) |
354 | 347 |
355 c.handshakeComplete = true | 348 c.handshakeComplete = true |
356 c.cipherSuite = suite.id | 349 c.cipherSuite = suite.id |
357 | 350 |
358 return nil | 351 return nil |
359 } | 352 } |
LEFT | RIGHT |