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..4bdb241432a0325bb6c49f66bc40c31cf1ca5efe 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" |
| @@ -2769,6 +2770,7 @@ SSLClientSocketNSS::SSLClientSocketNSS( |
| nss_fd_(NULL), |
| net_log_(transport_->socket()->NetLog()), |
| transport_security_state_(context.transport_security_state), |
| + cert_transparency_verifier_(context.cert_transparency_verifier), |
| valid_thread_id_(base::kInvalidThreadId) { |
| EnterFunction(""); |
| InitCore(); |
| @@ -3289,6 +3291,12 @@ int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) { |
| case STATE_VERIFY_CERT_COMPLETE: |
| rv = DoVerifyCertComplete(rv); |
| break; |
| + case STATE_VERIFY_CT: |
| + rv = DoVerifyCT(rv); |
| + break; |
| + case STATE_VERIFY_CT_COMPLETE: |
| + rv = DoVerifyCTComplete(rv); |
| + break; |
| case STATE_NONE: |
| default: |
| rv = ERR_UNEXPECTED; |
| @@ -3325,7 +3333,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 +3416,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 +3463,71 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) { |
| } |
| #endif |
| + if (result == OK) { |
| + // Only check Certificate Transparency if there were no other errors with |
| + // the connection. Note that in this case DoVerifyCTComplete will set |
| + // completed_handshake_ to true. |
| + GotoState(STATE_VERIFY_CT); |
| + return OK; |
| + } |
| + |
| + completed_handshake_ = true; |
| + |
| // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| return result; |
| } |
| +int SSLClientSocketNSS::DoVerifyCT(int result) { |
| + GotoState(STATE_VERIFY_CT_COMPLETE); |
| + |
| + if (!cert_transparency_verifier_) |
| + return OK; |
| + |
| + // Note that this is a completely synchronic operation: The CT Log Verifier |
| + // gets all the data it needs for SCT verification and does not do any |
| + // external communication |
| + return cert_transparency_verifier_->Verify( |
| + server_cert_verify_result_.verified_cert, |
| + "", // SCT list from OCSP stapling response |
|
Ryan Sleevi
2013/11/25 06:49:31
style: every "" should be std::string() instead
Eran M. (Google)
2013/11/25 17:18:33
Done.
|
| + "", // SCT list from TLS handshake |
| + &ct_verify_result_); |
| +} |
| + |
| +int SSLClientSocketNSS::DoVerifyCTComplete(int 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(); |
|
Ryan Sleevi
2013/11/25 06:49:31
The << call should be the first on the line - see
Eran M. (Google)
2013/11/25 17:18:33
Formatting done.
Yes, this will be part of the Bou
|
| + |
| + 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. |
| + server_cert_verify_result_.cert_status |= CERT_STATUS_HAS_ANY_SCT; |
| + |
| + if (!ct_verify_result_.verified_scts.empty() && result == OK) { |
| + // Found some valid SCTs - good |
| + server_cert_verify_result_.cert_status |= |
| + CERT_STATUS_HAS_VALID_SCT | CERT_STATUS_HAS_SCT_FROM_KNOWN_LOG; |
|
Ryan Sleevi
2013/11/25 06:49:31
style: four space indent
Eran M. (Google)
2013/11/25 17:18:33
Done.
|
| + } else if (!ct_verify_result_.unverified_scts.empty()) { |
| + server_cert_verify_result_.cert_status |= |
| + CERT_STATUS_HAS_SCT_FROM_KNOWN_LOG; |
|
Ryan Sleevi
2013/11/25 06:49:31
I don't understand how you can get into this state
Ryan Sleevi
2013/11/25 06:49:31
style: four space indent
Eran M. (Google)
2013/11/25 17:18:33
Done.
Eran M. (Google)
2013/11/25 17:18:33
This is exactly the state where verified_scts.empt
|
| + } |
| + } |
| + |
| + completed_handshake_ = true; |
| + DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| + |
| + return OK; |
| +} |
| + |
| void SSLClientSocketNSS::LogConnectionTypeMetrics() const { |
| UpdateConnectionTypeHistograms(CONNECTION_SSL); |
| int ssl_version = SSLConnectionStatusToVersion( |