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

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

Issue 27026002: CT: Adding preliminary Certificate Transparency support to Chromium. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Distinguish between SCTs from unknown logs and unverified ones Created 7 years, 1 month 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_nss.h ('k') | net/socket/ssl_client_socket_pool.h » ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 #include "crypto/scoped_nss_types.h" 86 #include "crypto/scoped_nss_types.h"
87 #include "net/base/address_list.h" 87 #include "net/base/address_list.h"
88 #include "net/base/connection_type_histograms.h" 88 #include "net/base/connection_type_histograms.h"
89 #include "net/base/dns_util.h" 89 #include "net/base/dns_util.h"
90 #include "net/base/io_buffer.h" 90 #include "net/base/io_buffer.h"
91 #include "net/base/net_errors.h" 91 #include "net/base/net_errors.h"
92 #include "net/base/net_log.h" 92 #include "net/base/net_log.h"
93 #include "net/cert/asn1_util.h" 93 #include "net/cert/asn1_util.h"
94 #include "net/cert/cert_status_flags.h" 94 #include "net/cert/cert_status_flags.h"
95 #include "net/cert/cert_verifier.h" 95 #include "net/cert/cert_verifier.h"
96 #include "net/cert/ct_verifier.h"
96 #include "net/cert/single_request_cert_verifier.h" 97 #include "net/cert/single_request_cert_verifier.h"
97 #include "net/cert/x509_certificate_net_log_param.h" 98 #include "net/cert/x509_certificate_net_log_param.h"
98 #include "net/cert/x509_util.h" 99 #include "net/cert/x509_util.h"
99 #include "net/http/transport_security_state.h" 100 #include "net/http/transport_security_state.h"
100 #include "net/ocsp/nss_ocsp.h" 101 #include "net/ocsp/nss_ocsp.h"
101 #include "net/socket/client_socket_handle.h" 102 #include "net/socket/client_socket_handle.h"
102 #include "net/socket/nss_ssl_util.h" 103 #include "net/socket/nss_ssl_util.h"
103 #include "net/socket/ssl_error_params.h" 104 #include "net/socket/ssl_error_params.h"
104 #include "net/ssl/ssl_cert_request_info.h" 105 #include "net/ssl/ssl_cert_request_info.h"
105 #include "net/ssl/ssl_connection_status_flags.h" 106 #include "net/ssl/ssl_connection_status_flags.h"
(...skipping 2638 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 host_and_port_(host_and_port), 2745 host_and_port_(host_and_port),
2745 ssl_config_(ssl_config), 2746 ssl_config_(ssl_config),
2746 cert_verifier_(context.cert_verifier), 2747 cert_verifier_(context.cert_verifier),
2747 server_bound_cert_service_(context.server_bound_cert_service), 2748 server_bound_cert_service_(context.server_bound_cert_service),
2748 ssl_session_cache_shard_(context.ssl_session_cache_shard), 2749 ssl_session_cache_shard_(context.ssl_session_cache_shard),
2749 completed_handshake_(false), 2750 completed_handshake_(false),
2750 next_handshake_state_(STATE_NONE), 2751 next_handshake_state_(STATE_NONE),
2751 nss_fd_(NULL), 2752 nss_fd_(NULL),
2752 net_log_(transport_->socket()->NetLog()), 2753 net_log_(transport_->socket()->NetLog()),
2753 transport_security_state_(context.transport_security_state), 2754 transport_security_state_(context.transport_security_state),
2755 cert_transparency_verifier_(context.cert_transparency_verifier),
2754 valid_thread_id_(base::kInvalidThreadId) { 2756 valid_thread_id_(base::kInvalidThreadId) {
2755 EnterFunction(""); 2757 EnterFunction("");
2756 InitCore(); 2758 InitCore();
2757 LeaveFunction(""); 2759 LeaveFunction("");
2758 } 2760 }
2759 2761
2760 SSLClientSocketNSS::~SSLClientSocketNSS() { 2762 SSLClientSocketNSS::~SSLClientSocketNSS() {
2761 EnterFunction(""); 2763 EnterFunction("");
2762 Disconnect(); 2764 Disconnect();
2763 LeaveFunction(""); 2765 LeaveFunction("");
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
3264 case STATE_HANDSHAKE_COMPLETE: 3266 case STATE_HANDSHAKE_COMPLETE:
3265 rv = DoHandshakeComplete(rv); 3267 rv = DoHandshakeComplete(rv);
3266 break; 3268 break;
3267 case STATE_VERIFY_CERT: 3269 case STATE_VERIFY_CERT:
3268 DCHECK(rv == OK); 3270 DCHECK(rv == OK);
3269 rv = DoVerifyCert(rv); 3271 rv = DoVerifyCert(rv);
3270 break; 3272 break;
3271 case STATE_VERIFY_CERT_COMPLETE: 3273 case STATE_VERIFY_CERT_COMPLETE:
3272 rv = DoVerifyCertComplete(rv); 3274 rv = DoVerifyCertComplete(rv);
3273 break; 3275 break;
3276 case STATE_VERIFY_CT:
3277 rv = DoVerifyCT(rv);
3278 break;
3279 case STATE_VERIFY_CT_COMPLETE:
3280 rv = DoVerifyCTComplete(rv);
3281 break;
3274 case STATE_NONE: 3282 case STATE_NONE:
3275 default: 3283 default:
3276 rv = ERR_UNEXPECTED; 3284 rv = ERR_UNEXPECTED;
3277 LOG(DFATAL) << "unexpected state " << state; 3285 LOG(DFATAL) << "unexpected state " << state;
3278 break; 3286 break;
3279 } 3287 }
3280 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); 3288 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
3281 LeaveFunction(""); 3289 LeaveFunction("");
3282 return rv; 3290 return rv;
3283 } 3291 }
(...skipping 16 matching lines...) Expand all
3300 // SSL handshake is completed. Let's verify the certificate. 3308 // SSL handshake is completed. Let's verify the certificate.
3301 GotoState(STATE_VERIFY_CERT); 3309 GotoState(STATE_VERIFY_CERT);
3302 // Done! 3310 // Done!
3303 } 3311 }
3304 set_channel_id_sent(core_->state().channel_id_sent); 3312 set_channel_id_sent(core_->state().channel_id_sent);
3305 3313
3306 LeaveFunction(result); 3314 LeaveFunction(result);
3307 return result; 3315 return result;
3308 } 3316 }
3309 3317
3310
3311 int SSLClientSocketNSS::DoVerifyCert(int result) { 3318 int SSLClientSocketNSS::DoVerifyCert(int result) {
3312 DCHECK(!core_->state().server_cert_chain.empty()); 3319 DCHECK(!core_->state().server_cert_chain.empty());
3313 DCHECK(core_->state().server_cert_chain[0]); 3320 DCHECK(core_->state().server_cert_chain[0]);
3314 3321
3315 GotoState(STATE_VERIFY_CERT_COMPLETE); 3322 GotoState(STATE_VERIFY_CERT_COMPLETE);
3316 3323
3317 // If the certificate is expected to be bad we can use the expectation as 3324 // If the certificate is expected to be bad we can use the expectation as
3318 // the cert status. 3325 // the cert status.
3319 base::StringPiece der_cert( 3326 base::StringPiece der_cert(
3320 reinterpret_cast<char*>( 3327 reinterpret_cast<char*>(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
3384 // is fixed, we need to avoid using the NSS database for non-essential 3391 // is fixed, we need to avoid using the NSS database for non-essential
3385 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and 3392 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
3386 // http://crbug.com/15630 for more info. 3393 // http://crbug.com/15630 for more info.
3387 3394
3388 // TODO(hclam): Skip logging if server cert was expected to be bad because 3395 // TODO(hclam): Skip logging if server cert was expected to be bad because
3389 // |server_cert_verify_result_| doesn't contain all the information about 3396 // |server_cert_verify_result_| doesn't contain all the information about
3390 // the cert. 3397 // the cert.
3391 if (result == OK) 3398 if (result == OK)
3392 LogConnectionTypeMetrics(); 3399 LogConnectionTypeMetrics();
3393 3400
3394 completed_handshake_ = true;
3395
3396 #if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) && !defined(OS_IOS) 3401 #if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) && !defined(OS_IOS)
3397 // Take care of any mandates for public key pinning. 3402 // Take care of any mandates for public key pinning.
3398 // 3403 //
3399 // Pinning is only enabled for official builds to make sure that others don't 3404 // Pinning is only enabled for official builds to make sure that others don't
3400 // end up with pins that cannot be easily updated. 3405 // end up with pins that cannot be easily updated.
3401 // 3406 //
3402 // TODO(agl): We might have an issue here where a request for foo.example.com 3407 // TODO(agl): We might have an issue here where a request for foo.example.com
3403 // merges into a SPDY connection to www.example.com, and gets a different 3408 // merges into a SPDY connection to www.example.com, and gets a different
3404 // certificate. 3409 // certificate.
3405 3410
(...skipping 27 matching lines...) Expand all
3433 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 3438 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
3434 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); 3439 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false);
3435 TransportSecurityState::ReportUMAOnPinFailure(host); 3440 TransportSecurityState::ReportUMAOnPinFailure(host);
3436 } else { 3441 } else {
3437 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); 3442 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true);
3438 } 3443 }
3439 } 3444 }
3440 } 3445 }
3441 #endif 3446 #endif
3442 3447
3448 if (result == OK) {
3449 // Only check Certificate Transparency if there were no other errors with
3450 // the connection.
3451 GotoState(STATE_VERIFY_CT);
3452 return OK;
3453 }
3454
3455 completed_handshake_ = true;
3456
3443 // Exit DoHandshakeLoop and return the result to the caller to Connect. 3457 // Exit DoHandshakeLoop and return the result to the caller to Connect.
3444 DCHECK_EQ(STATE_NONE, next_handshake_state_); 3458 DCHECK_EQ(STATE_NONE, next_handshake_state_);
3445 return result; 3459 return result;
3446 } 3460 }
3447 3461
3462 int SSLClientSocketNSS::DoVerifyCT(int result) {
3463 GotoState(STATE_VERIFY_CT_COMPLETE);
3464
3465 if (!cert_transparency_verifier_)
3466 return OK;
3467
3468 // XXX(rsleevi): Not actually async-safe (using base::Unretained and giving
3469 // the raw pointer up). Need to use WeakPtr<> so that this can be cancelled,
3470 // but without requiring the opaque request handles of CertVerifier.
3471 return cert_transparency_verifier_->Verify(
3472 core_->state().server_cert,
3473 server_cert_verify_result_.verified_cert,
3474 &ct_verify_result_,
3475 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
3476 base::Unretained(this)),
3477 net_log_);
3478 }
3479
3480 int SSLClientSocketNSS::DoVerifyCTComplete(int result) {
3481 VLOG(1) << "CT Verification complete: result " << result <<
3482 " Unverified scts: " << ct_verify_result_.unverified_scts.size() <<
3483 " Verified scts: " << ct_verify_result_.verified_scts.size() <<
3484 " scts from unknown logs: " <<
3485 ct_verify_result_.unknown_logs_scts.size();
3486 if (ct_verify_result_.unverified_scts.empty() &&
3487 ct_verify_result_.unknown_logs_scts.empty() &&
3488 ct_verify_result_.verified_scts.empty()) {
3489 return OK;
3490 }
3491
3492 // XXX(eranm): Saving CT state in cert_status bits is a temporary solution,
3493 // until the SCTs themselves are threaded into the SSLInfo (as well as into
3494 // the HTTP cache). Using a status flag is a cheap way to persist the
3495 // SCT status.
3496 server_cert_verify_result_.cert_status |= CERT_STATUS_HAS_ANY_SCT;
3497
3498 if (!ct_verify_result_.verified_scts.empty() && result == OK) {
3499 // Found some valid SCTs - good
3500 server_cert_verify_result_.cert_status |=
3501 CERT_STATUS_HAS_VALID_SCT | CERT_STATUS_HAS_SCT_FROM_KNOWN_LOG;
3502 } else if (!ct_verify_result_.unverified_scts.empty()) {
3503 server_cert_verify_result_.cert_status |=
3504 CERT_STATUS_HAS_SCT_FROM_KNOWN_LOG;
3505 }
3506
3507 completed_handshake_ = true;
3508
3509 DCHECK_EQ(STATE_NONE, next_handshake_state_);
3510
3511 return OK;
3512 }
3513
3448 void SSLClientSocketNSS::LogConnectionTypeMetrics() const { 3514 void SSLClientSocketNSS::LogConnectionTypeMetrics() const {
3449 UpdateConnectionTypeHistograms(CONNECTION_SSL); 3515 UpdateConnectionTypeHistograms(CONNECTION_SSL);
3450 int ssl_version = SSLConnectionStatusToVersion( 3516 int ssl_version = SSLConnectionStatusToVersion(
3451 core_->state().ssl_connection_status); 3517 core_->state().ssl_connection_status);
3452 switch (ssl_version) { 3518 switch (ssl_version) {
3453 case SSL_CONNECTION_VERSION_SSL2: 3519 case SSL_CONNECTION_VERSION_SSL2:
3454 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2); 3520 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2);
3455 break; 3521 break;
3456 case SSL_CONNECTION_VERSION_SSL3: 3522 case SSL_CONNECTION_VERSION_SSL3:
3457 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3); 3523 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3);
(...skipping 21 matching lines...) Expand all
3479 EnsureThreadIdAssigned(); 3545 EnsureThreadIdAssigned();
3480 base::AutoLock auto_lock(lock_); 3546 base::AutoLock auto_lock(lock_);
3481 return valid_thread_id_ == base::PlatformThread::CurrentId(); 3547 return valid_thread_id_ == base::PlatformThread::CurrentId();
3482 } 3548 }
3483 3549
3484 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { 3550 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const {
3485 return server_bound_cert_service_; 3551 return server_bound_cert_service_;
3486 } 3552 }
3487 3553
3488 } // namespace net 3554 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_nss.h ('k') | net/socket/ssl_client_socket_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698