Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: net/socket/ssl_client_socket_mac.cc

Issue 165191: Implement SSL certificate error handling on the Mac. If the user gives... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Upload before checkin Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/socket/ssl_client_socket_mac.h ('k') | net/socket/ssl_client_socket_nss.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/ssl_client_socket_mac.h" 5 #include "net/socket/ssl_client_socket_mac.h"
6 6
7 #include "base/singleton.h" 7 #include "base/singleton.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: 234 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
235 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: 235 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
236 case TLS_DH_anon_WITH_AES_256_CBC_SHA: 236 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
237 return 256; 237 return 256;
238 238
239 default: 239 default:
240 return -1; 240 return -1;
241 } 241 }
242 } 242 }
243 243
244 // Returns the server's certificate. The caller must release a reference
245 // to the return value when done. Returns NULL on failure.
246 X509Certificate* GetServerCert(SSLContextRef ssl_context) {
247 CFArrayRef certs;
248 OSStatus status = SSLCopyPeerCertificates(ssl_context, &certs);
249 if (status != noErr)
250 return NULL;
251
252 DCHECK_GT(CFArrayGetCount(certs), 0);
253
254 SecCertificateRef server_cert = static_cast<SecCertificateRef>(
255 const_cast<void*>(CFArrayGetValueAtIndex(certs, 0)));
256 CFRetain(server_cert);
257 CFRelease(certs);
258 return X509Certificate::CreateFromHandle(
259 server_cert, X509Certificate::SOURCE_FROM_NETWORK);
260 }
261
244 } // namespace 262 } // namespace
245 263
246 //----------------------------------------------------------------------------- 264 //-----------------------------------------------------------------------------
247 265
248 SSLClientSocketMac::SSLClientSocketMac(ClientSocket* transport_socket, 266 SSLClientSocketMac::SSLClientSocketMac(ClientSocket* transport_socket,
249 const std::string& hostname, 267 const std::string& hostname,
250 const SSLConfig& ssl_config) 268 const SSLConfig& ssl_config)
251 : io_callback_(this, &SSLClientSocketMac::OnIOComplete), 269 : io_callback_(this, &SSLClientSocketMac::OnIOComplete),
252 write_callback_(this, &SSLClientSocketMac::OnWriteComplete), 270 write_callback_(this, &SSLClientSocketMac::OnWriteComplete),
253 transport_(transport_socket), 271 transport_(transport_socket),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 return NetErrorFromOSStatus(status); 316 return NetErrorFromOSStatus(status);
299 317
300 status = SSLSetIOFuncs(ssl_context_, SSLReadCallback, SSLWriteCallback); 318 status = SSLSetIOFuncs(ssl_context_, SSLReadCallback, SSLWriteCallback);
301 if (status) 319 if (status)
302 return NetErrorFromOSStatus(status); 320 return NetErrorFromOSStatus(status);
303 321
304 status = SSLSetConnection(ssl_context_, this); 322 status = SSLSetConnection(ssl_context_, this);
305 if (status) 323 if (status)
306 return NetErrorFromOSStatus(status); 324 return NetErrorFromOSStatus(status);
307 325
308 status = SSLSetPeerDomainName(ssl_context_, hostname_.c_str(), 326 if (ssl_config_.allowed_bad_certs.empty()) {
309 hostname_.length()); 327 // We're going to use the default certificate verification that the system
310 if (status) 328 // does, and accept its answer for the cert status.
311 return NetErrorFromOSStatus(status); 329 status = SSLSetPeerDomainName(ssl_context_, hostname_.data(),
330 hostname_.length());
331 if (status)
332 return NetErrorFromOSStatus(status);
333
334 // TODO(wtc): for now, always check revocation.
335 server_cert_status_ = CERT_STATUS_REV_CHECKING_ENABLED;
336 } else {
337 // Disable certificate chain validation. We will only allow the certs in
338 // ssl_config_.allowed_bad_certs.
339 status = SSLSetEnableCertVerify(ssl_context_, false);
340 if (status)
341 return NetErrorFromOSStatus(status);
342 }
312 343
313 next_state_ = STATE_HANDSHAKE; 344 next_state_ = STATE_HANDSHAKE;
314 int rv = DoLoop(OK); 345 int rv = DoLoop(OK);
315 if (rv == ERR_IO_PENDING) 346 if (rv == ERR_IO_PENDING)
316 user_callback_ = callback; 347 user_callback_ = callback;
317 return rv; 348 return rv;
318 } 349 }
319 350
320 void SSLClientSocketMac::Disconnect() { 351 void SSLClientSocketMac::Disconnect() {
321 completed_handshake_ = false; 352 completed_handshake_ = false;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } else { 418 } else {
388 user_buf_ = NULL; 419 user_buf_ = NULL;
389 } 420 }
390 return rv; 421 return rv;
391 } 422 }
392 423
393 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { 424 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) {
394 ssl_info->Reset(); 425 ssl_info->Reset();
395 426
396 // set cert 427 // set cert
397 CFArrayRef certs; 428 ssl_info->cert = server_cert_;
398 OSStatus status = SSLCopyPeerCertificates(ssl_context_, &certs);
399 if (!status) {
400 DCHECK(CFArrayGetCount(certs) > 0);
401
402 SecCertificateRef client_cert =
403 static_cast<SecCertificateRef>(
404 const_cast<void*>(CFArrayGetValueAtIndex(certs, 0)));
405 CFRetain(client_cert);
406 ssl_info->cert = X509Certificate::CreateFromHandle(
407 client_cert, X509Certificate::SOURCE_FROM_NETWORK);
408 CFRelease(certs);
409 }
410 429
411 // update status 430 // update status
412 ssl_info->cert_status = server_cert_status_; 431 ssl_info->cert_status = server_cert_status_;
413 432
414 // security info 433 // security info
415 SSLCipherSuite suite; 434 SSLCipherSuite suite;
416 status = SSLGetNegotiatedCipher(ssl_context_, &suite); 435 OSStatus status = SSLGetNegotiatedCipher(ssl_context_, &suite);
417 if (!status) 436 if (!status)
418 ssl_info->security_bits = KeySizeOfCipherSuite(suite); 437 ssl_info->security_bits = KeySizeOfCipherSuite(suite);
419 } 438 }
420 439
421 void SSLClientSocketMac::GetSSLCertRequestInfo( 440 void SSLClientSocketMac::GetSSLCertRequestInfo(
422 SSLCertRequestInfo* cert_request_info) { 441 SSLCertRequestInfo* cert_request_info) {
423 // TODO(wtc): implement this. 442 // TODO(wtc): implement this.
424 } 443 }
425 444
426 void SSLClientSocketMac::DoCallback(int rv) { 445 void SSLClientSocketMac::DoCallback(int rv) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 rv = ERR_UNEXPECTED; 497 rv = ERR_UNEXPECTED;
479 NOTREACHED() << "unexpected state"; 498 NOTREACHED() << "unexpected state";
480 break; 499 break;
481 } 500 }
482 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 501 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
483 return rv; 502 return rv;
484 } 503 }
485 504
486 int SSLClientSocketMac::DoHandshake() { 505 int SSLClientSocketMac::DoHandshake() {
487 OSStatus status = SSLHandshake(ssl_context_); 506 OSStatus status = SSLHandshake(ssl_context_);
488
489 if (status == errSSLWouldBlock)
490 next_state_ = STATE_HANDSHAKE;
491
492 if (status == noErr)
493 completed_handshake_ = true;
494
495 int net_error = NetErrorFromOSStatus(status); 507 int net_error = NetErrorFromOSStatus(status);
496 508
497 // At this point we have a connection. For now, we're going to use the default 509 if (status == errSSLWouldBlock) {
498 // certificate verification that the system does, and accept its answer for 510 next_state_ = STATE_HANDSHAKE;
499 // the cert status. In the future, we'll need to call SSLSetEnableCertVerify 511 } else if (status == noErr) {
500 // to disable cert verification and do the verification ourselves. This allows 512 completed_handshake_ = true; // We have a connection.
501 // very fine-grained control over what we'll accept for certification.
502 // TODO(avi): ditto
503 513
504 // TODO(wtc): for now, always check revocation. 514 server_cert_ = GetServerCert(ssl_context_);
505 server_cert_status_ = CERT_STATUS_REV_CHECKING_ENABLED; 515 DCHECK(server_cert_);
506 if (net_error) 516 if (!ssl_config_.allowed_bad_certs.empty()) {
517 // Check server_cert_ because SecureTransport didn't verify it.
518 // TODO(wtc): If server_cert_ is not one of the allowed bad certificates,
519 // we should verify server_cert_ ourselves. Since we don't know how to
520 // do that yet, treat it as an invalid certificate.
521 net_error = ERR_CERT_INVALID;
522 server_cert_status_ |= CERT_STATUS_INVALID;
523
524 for (size_t i = 0; i < ssl_config_.allowed_bad_certs.size(); ++i) {
525 if (server_cert_ == ssl_config_.allowed_bad_certs[i].cert) {
526 net_error = OK;
527 server_cert_status_ = ssl_config_.allowed_bad_certs[i].cert_status;
528 break;
529 }
530 }
531 }
532 } else if (IsCertStatusError(net_error)) {
533 server_cert_ = GetServerCert(ssl_context_);
534 DCHECK(server_cert_);
507 server_cert_status_ |= MapNetErrorToCertStatus(net_error); 535 server_cert_status_ |= MapNetErrorToCertStatus(net_error);
536 }
508 537
509 return net_error; 538 return net_error;
510 } 539 }
511 540
512 int SSLClientSocketMac::DoReadComplete(int result) { 541 int SSLClientSocketMac::DoReadComplete(int result) {
513 if (result < 0) { 542 if (result < 0) {
514 read_io_buf_ = NULL; 543 read_io_buf_ = NULL;
515 return result; 544 return result;
516 } 545 }
517 546
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 799
771 if (rv < 0 && rv != ERR_IO_PENDING) { 800 if (rv < 0 && rv != ERR_IO_PENDING) {
772 return OSStatusFromNetError(rv); 801 return OSStatusFromNetError(rv);
773 } 802 }
774 803
775 // always lie to our caller 804 // always lie to our caller
776 return noErr; 805 return noErr;
777 } 806 }
778 807
779 } // namespace net 808 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_mac.h ('k') | net/socket/ssl_client_socket_nss.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698