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

Unified Diff: net/socket/ssl_client_socket_impl.cc

Issue 2076363002: Introduce the ability to require CT for specific hosts (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@require_ct_enforcer
Patch Set: Rebased Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: net/socket/ssl_client_socket_impl.cc
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index 60a8fae446bc38d88b85149bbbb7bdeb07299eef..b843d4eb8cee54b28c0213e34034dc29b5338a29 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1327,27 +1327,31 @@ int SSLClientSocketImpl::DoVerifyCertComplete(int result) {
}
}
+ // If the connection was good, check HPKP and CT status simultaneously,
+ // but prefer to treat the HPKP error as more serious, if there was one.
const CertStatus cert_status = server_cert_verify_result_.cert_status;
if ((result == OK ||
- (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
- !transport_security_state_->CheckPublicKeyPins(
- host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
- server_cert_verify_result_.public_key_hashes, server_cert_.get(),
- server_cert_verify_result_.verified_cert.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_)) {
- if (server_cert_verify_result_.is_issued_by_known_root) {
- server_cert_verify_result_.cert_status |= CERT_STATUS_PINNED_KEY_MISSING;
- result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
- } else {
- pkp_bypassed_ = true;
+ (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
+ int ct_result = VerifyCT();
+ if (!transport_security_state_->CheckPublicKeyPins(
+ host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
+ server_cert_verify_result_.public_key_hashes, server_cert_.get(),
+ server_cert_verify_result_.verified_cert.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS,
+ &pinning_failure_log_)) {
+ if (server_cert_verify_result_.is_issued_by_known_root) {
+ server_cert_verify_result_.cert_status |=
+ CERT_STATUS_PINNED_KEY_MISSING;
+ result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
+ } else {
+ pkp_bypassed_ = true;
+ }
}
+ if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK)
+ result = ct_result;
davidben 2016/06/22 21:44:59 SSLClientSocket-level test for all this? Particula
Ryan Sleevi 2016/06/22 22:07:39 Sure
}
if (result == OK) {
- // Only check Certificate Transparency if there were no other errors with
- // the connection.
- VerifyCT();
-
DCHECK(!certificate_verified_);
certificate_verified_ = true;
MaybeCacheSession();
@@ -1377,58 +1381,6 @@ void SSLClientSocketImpl::UpdateServerCert() {
}
}
-void SSLClientSocketImpl::VerifyCT() {
- const uint8_t* ocsp_response_raw;
- size_t ocsp_response_len;
- SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
- std::string ocsp_response;
- if (ocsp_response_len > 0) {
- ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
- ocsp_response_len);
- }
-
- const uint8_t* sct_list_raw;
- size_t sct_list_len;
- SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
- std::string sct_list;
- if (sct_list_len > 0)
- sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
-
- // 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.
- cert_transparency_verifier_->Verify(
- server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
- &ct_verify_result_, net_log_);
-
- ct_verify_result_.ct_policies_applied = true;
- ct_verify_result_.ev_policy_compliance =
- ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
- if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
- scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
- SSLConfigService::GetEVCertsWhitelist();
- ct::EVPolicyCompliance ev_policy_compliance =
- policy_enforcer_->DoesConformToCTEVPolicy(
- server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(),
- ct_verify_result_.verified_scts, net_log_);
- ct_verify_result_.ev_policy_compliance = ev_policy_compliance;
- if (ev_policy_compliance !=
- ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
- ev_policy_compliance !=
- ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
- ev_policy_compliance !=
- ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
- server_cert_verify_result_.cert_status |=
- CERT_STATUS_CT_COMPLIANCE_FAILED;
- server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
- }
- }
- ct_verify_result_.cert_policy_compliance =
- policy_enforcer_->DoesConformToCertPolicy(
- server_cert_verify_result_.verified_cert.get(),
- ct_verify_result_.verified_scts, net_log_);
-}
-
void SSLClientSocketImpl::OnHandshakeIOComplete(int result) {
int rv = DoHandshakeLoop(result);
if (rv != ERR_IO_PENDING) {
@@ -1817,6 +1769,70 @@ int SSLClientSocketImpl::TransportReadComplete(int result) {
return result;
}
+int SSLClientSocketImpl::VerifyCT() {
+ const uint8_t* ocsp_response_raw;
+ size_t ocsp_response_len;
+ SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
+ std::string ocsp_response;
+ if (ocsp_response_len > 0) {
+ ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
+ ocsp_response_len);
+ }
+
+ const uint8_t* sct_list_raw;
+ size_t sct_list_len;
+ SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
+ std::string sct_list;
+ if (sct_list_len > 0)
+ sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
+
+ // 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.
+ cert_transparency_verifier_->Verify(
+ server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
+ &ct_verify_result_, net_log_);
+
+ ct_verify_result_.ct_policies_applied = true;
+ ct_verify_result_.ev_policy_compliance =
+ ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
+ if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
+ scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
+ SSLConfigService::GetEVCertsWhitelist();
+ ct::EVPolicyCompliance ev_policy_compliance =
+ policy_enforcer_->DoesConformToCTEVPolicy(
+ server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(),
+ ct_verify_result_.verified_scts, net_log_);
+ ct_verify_result_.ev_policy_compliance = ev_policy_compliance;
+ if (ev_policy_compliance !=
+ ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
+ ev_policy_compliance !=
+ ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
+ ev_policy_compliance !=
+ ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
+ server_cert_verify_result_.cert_status |=
+ CERT_STATUS_CT_COMPLIANCE_FAILED;
+ server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
+ }
+ }
+ ct_verify_result_.cert_policy_compliance =
+ policy_enforcer_->DoesConformToCertPolicy(
+ server_cert_verify_result_.verified_cert.get(),
+ ct_verify_result_.verified_scts, net_log_);
+
+ if (ct_verify_result_.cert_policy_compliance !=
+ ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS &&
davidben 2016/06/22 21:44:59 To confirm: it is intentional that CERT_POLICY_COM
Ryan Sleevi 2016/06/22 22:07:39 There is no CERT_POLICY_COMPLIES_VIA_WHITELIST - t
+ transport_security_state_->ShouldRequireCT(
+ host_and_port_.host(), server_cert_verify_result_.verified_cert.get(),
+ server_cert_verify_result_.public_key_hashes)) {
+ server_cert_verify_result_.cert_status |=
+ CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
+ return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
+ }
+
+ return OK;
+}
+
int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
DCHECK(ssl == ssl_);

Powered by Google App Engine
This is Rietveld 408576698