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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 60f03240ab9e07f0496a1ffd71a6ec0c5cab599a..554d8d7119bfa733fde7d3031f66217d4359919c 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/single_request_cert_verifier.h"
#include "net/cert/x509_certificate_net_log_param.h"
#include "net/cert/x509_util.h"
@@ -2751,6 +2752,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();
@@ -3271,6 +3273,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;
@@ -3307,7 +3315,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]);
@@ -3391,8 +3398,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.
//
@@ -3440,11 +3445,72 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
}
#endif
+ if (result == OK) {
+ // Only check Certificate Transparency if there were no other errors with
+ // the connection.
+ 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;
+
+ // XXX(rsleevi): Not actually async-safe (using base::Unretained and giving
+ // the raw pointer up). Need to use WeakPtr<> so that this can be cancelled,
+ // but without requiring the opaque request handles of CertVerifier.
+ return cert_transparency_verifier_->Verify(
+ core_->state().server_cert,
+ server_cert_verify_result_.verified_cert,
+ &ct_verify_result_,
+ base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
+ base::Unretained(this)),
+ net_log_);
+}
+
+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();
+ if (ct_verify_result_.unverified_scts.empty() &&
+ ct_verify_result_.unknown_logs_scts.empty() &&
+ ct_verify_result_.verified_scts.empty()) {
+ return OK;
+ }
+
+ // XXX(eranm): Saving CT state in cert_status bits is a temporary solution,
+ // until the SCTs themselves are threaded into the SSLInfo (as well as into
+ // the HTTP cache). Using a status flag is a cheap way to persist the
+ // SCT status.
+ 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;
+ } else if (!ct_verify_result_.unverified_scts.empty()) {
+ server_cert_verify_result_.cert_status |=
+ CERT_STATUS_HAS_SCT_FROM_KNOWN_LOG;
+ }
+
+ completed_handshake_ = true;
+
+ DCHECK_EQ(STATE_NONE, next_handshake_state_);
+
+ return OK;
+}
+
void SSLClientSocketNSS::LogConnectionTypeMetrics() const {
UpdateConnectionTypeHistograms(CONNECTION_SSL);
int ssl_version = SSLConnectionStatusToVersion(
« 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