Chromium Code Reviews| Index: net/socket/ssl_client_socket_nss.cc | 
| diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc | 
| index 89eab143140f5aadadd7e5cf8678d9692499f8a8..2a44fb82704e8658e340da0a9ca7ec99e8029ed7 100644 | 
| --- a/net/socket/ssl_client_socket_nss.cc | 
| +++ b/net/socket/ssl_client_socket_nss.cc | 
| @@ -93,6 +93,7 @@ | 
| #include "net/cert/asn1_util.h" | 
| #include "net/cert/cert_status_flags.h" | 
| #include "net/cert/cert_verifier.h" | 
| +#include "net/cert/ct_verifier.h" | 
| #include "net/cert/scoped_nss_types.h" | 
| #include "net/cert/single_request_cert_verifier.h" | 
| #include "net/cert/x509_certificate_net_log_param.h" | 
| @@ -2762,6 +2763,7 @@ SSLClientSocketNSS::SSLClientSocketNSS( | 
| host_and_port_(host_and_port), | 
| ssl_config_(ssl_config), | 
| cert_verifier_(context.cert_verifier), | 
| + cert_transparency_verifier_(context.cert_transparency_verifier), | 
| server_bound_cert_service_(context.server_bound_cert_service), | 
| ssl_session_cache_shard_(context.ssl_session_cache_shard), | 
| completed_handshake_(false), | 
| @@ -3325,7 +3327,6 @@ int SSLClientSocketNSS::DoHandshakeComplete(int result) { | 
| return result; | 
| } | 
| - | 
| int SSLClientSocketNSS::DoVerifyCert(int result) { | 
| DCHECK(!core_->state().server_cert_chain.empty()); | 
| DCHECK(core_->state().server_cert_chain[0]); | 
| @@ -3409,8 +3410,6 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) { | 
| if (result == OK) | 
| LogConnectionTypeMetrics(); | 
| - completed_handshake_ = true; | 
| - | 
| #if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) && !defined(OS_IOS) | 
| // Take care of any mandates for public key pinning. | 
| // | 
| @@ -3458,11 +3457,63 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) { | 
| } | 
| #endif | 
| + if (result == OK) { | 
| + // Only check Certificate Transparency if there were no other errors with | 
| + // the connection. | 
| + VerifyCT(); | 
| + } | 
| + | 
| + completed_handshake_ = true; | 
| + | 
| // Exit DoHandshakeLoop and return the result to the caller to Connect. | 
| DCHECK_EQ(STATE_NONE, next_handshake_state_); | 
| return result; | 
| } | 
| +void SSLClientSocketNSS::VerifyCT() { | 
| + if (!cert_transparency_verifier_) | 
| + return; | 
| + | 
| + // Note that this is a completely synchronous operation: The CT Log Verifier | 
| + // gets all the data it needs for SCT verification and does not do any | 
| + // external communication. | 
| + int result = cert_transparency_verifier_->Verify( | 
| + server_cert_verify_result_.verified_cert, | 
| + std::string(), // SCT list from OCSP response | 
| + std::string(), // SCT list from TLS extension | 
| + &ct_verify_result_); | 
| + | 
| + VLOG(1) << "CT Verification complete: result " << result | 
| + << " Unverified scts: " << ct_verify_result_.unverified_scts.size() | 
| + << " Verified scts: " << ct_verify_result_.verified_scts.size() | 
| + << " scts from unknown logs: " | 
| + << ct_verify_result_.unknown_logs_scts.size(); | 
| + | 
| + if (!ct_verify_result_.unverified_scts.empty() || | 
| + !ct_verify_result_.unknown_logs_scts.empty() || | 
| + !ct_verify_result_.verified_scts.empty()) { | 
| + // Saving CT state in cert_status bits, in addition to the SCTs themselves | 
| + // (which will be threaded into the SSLInfo, as well as into the HTTP | 
| + // cache). | 
| + // This persists the CT status and simplifies UI code for figuring out | 
| + // the right CT info to display. | 
| + int ct_state; | 
| 
 
wtc
2013/11/27 20:00:49
I suggest declaring this variable as a uint32 or C
 
Eran M. (Google)
2013/11/27 23:01:42
Done - uint32 it is.
 
 | 
| + if (!ct_verify_result_.verified_scts.empty() && result == OK) | 
| + ct_state = CERT_TRANSPARENCY_SCT_VALIDATED_OK; | 
| + else if (!ct_verify_result_.unverified_scts.empty()) | 
| + ct_state = CERT_TRANSPARENCY_SCT_FAILED_VALIDATION; | 
| + else { | 
| + DCHECK(!ct_verify_result_.unknown_logs_scts.empty()); | 
| + ct_state = CERT_TRANSPARENCY_SCT_FROM_UNKNOWN_LOGS; | 
| + } | 
| 
 
wtc
2013/11/27 20:00:49
Nit: if one branch of the if statement needs curly
 
Eran M. (Google)
2013/11/27 23:01:42
Done.
 
 | 
| + server_cert_verify_result_.cert_status |= | 
| + (ct_state & CERTIFICATE_TRANSPARENCY_STATUS_MASK) << | 
| + CERTIFICATE_TRANSPARENCY_STATUS_SHIFT; | 
| 
 
wtc
2013/11/27 20:00:49
I don't think we need "& CERTIFICATE_TRANSPARENCY_
 
Eran M. (Google)
2013/11/27 23:01:42
Done.
 
 | 
| + } | 
| + | 
| + return; | 
| 
 
wtc
2013/11/27 20:00:49
Nit: the return statement is not necessary for a v
 
Eran M. (Google)
2013/11/27 23:01:42
Oops! Done.
 
 | 
| +} | 
| + | 
| void SSLClientSocketNSS::LogConnectionTypeMetrics() const { | 
| UpdateConnectionTypeHistograms(CONNECTION_SSL); | 
| int ssl_version = SSLConnectionStatusToVersion( |