| Index: net/http/transport_security_state.cc
 | 
| diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
 | 
| index 4486954966631398bc9cc155e1b6435fa2138475..bc45c63f9182c1271ceba6e68b964821e18e0e26 100644
 | 
| --- a/net/http/transport_security_state.cc
 | 
| +++ b/net/http/transport_security_state.cc
 | 
| @@ -50,7 +50,7 @@ const size_t kReportCacheKeyLength = 16;
 | 
|  // Points to the active transport security state source.
 | 
|  const TransportSecurityStateSource* g_hsts_source = &kHSTSSource;
 | 
|  
 | 
| -// Override for ShouldRequireCT() for unit tests. Possible values:
 | 
| +// Override for CheckCTRequirements() for unit tests. Possible values:
 | 
|  //  -1: Unless a delegate says otherwise, do not require CT.
 | 
|  //   0: Use the default implementation (e.g. production)
 | 
|  //   1: Unless a delegate says otherwise, require CT.
 | 
| @@ -860,26 +860,61 @@ bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
 | 
|    return false;
 | 
|  }
 | 
|  
 | 
| -bool TransportSecurityState::ShouldRequireCT(
 | 
| -    const std::string& hostname,
 | 
| +TransportSecurityState::CTRequirementsStatus
 | 
| +TransportSecurityState::CheckCTRequirements(
 | 
| +    const net::HostPortPair& host_port_pair,
 | 
| +    bool is_issued_by_known_root,
 | 
| +    const HashValueVector& public_key_hashes,
 | 
|      const X509Certificate* validated_certificate_chain,
 | 
| -    const HashValueVector& public_key_hashes) {
 | 
| +    const X509Certificate* served_certificate_chain,
 | 
| +    const SignedCertificateTimestampAndStatusList&
 | 
| +        signed_certificate_timestamps,
 | 
| +    const ExpectCTReportStatus report_status,
 | 
| +    ct::CertPolicyCompliance cert_policy_compliance) {
 | 
|    using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
 | 
| +  std::string hostname = host_port_pair.host();
 | 
| +
 | 
| +  // If the connection complies with CT policy, then no further checks are
 | 
| +  // necessary.
 | 
| +  if (cert_policy_compliance ==
 | 
| +          ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS ||
 | 
| +      cert_policy_compliance ==
 | 
| +          ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY) {
 | 
| +    return CT_REQUIREMENTS_MET;
 | 
| +  }
 | 
| +
 | 
| +  // Check Expect-CT first so that other CT requirements do not prevent
 | 
| +  // Expect-CT reports from being sent.
 | 
| +  ExpectCTState state;
 | 
| +  if (is_issued_by_known_root && IsDynamicExpectCTEnabled() &&
 | 
| +      GetDynamicExpectCTState(hostname, &state)) {
 | 
| +    if (expect_ct_reporter_ && !state.report_uri.is_empty() &&
 | 
| +        report_status == ENABLE_EXPECT_CT_REPORTS) {
 | 
| +      expect_ct_reporter_->OnExpectCTFailed(
 | 
| +          host_port_pair, state.report_uri, validated_certificate_chain,
 | 
| +          served_certificate_chain, signed_certificate_timestamps);
 | 
| +    }
 | 
| +    if (state.enforce)
 | 
| +      return CT_REQUIREMENTS_NOT_MET;
 | 
| +  }
 | 
|  
 | 
|    CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT;
 | 
|    if (require_ct_delegate_)
 | 
|      ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname);
 | 
|    if (ct_required != CTRequirementLevel::DEFAULT)
 | 
| -    return ct_required == CTRequirementLevel::REQUIRED;
 | 
| +    return (ct_required == CTRequirementLevel::REQUIRED
 | 
| +                ? CT_REQUIREMENTS_NOT_MET
 | 
| +                : CT_REQUIREMENTS_MET);
 | 
|  
 | 
|    // Allow unittests to override the default result.
 | 
|    if (g_ct_required_for_testing)
 | 
| -    return g_ct_required_for_testing == 1;
 | 
| +    return (g_ct_required_for_testing == 1 ? CT_REQUIREMENTS_NOT_MET
 | 
| +                                           : CT_REQUIREMENTS_MET);
 | 
|  
 | 
|    // Until CT is required for all secure hosts on the Internet, this should
 | 
| -  // remain false. It is provided to simplify the various short-circuit
 | 
| -  // returns below.
 | 
| -  bool default_response = false;
 | 
| +  // remain CT_REQUIREMENTS_MET. It is provided to simplify the various
 | 
| +  // short-circuit returns below.
 | 
| +  const CTRequirementsStatus default_response = CT_REQUIREMENTS_MET;
 | 
|  
 | 
|  // FieldTrials are not supported in Native Client apps.
 | 
|  #if !defined(OS_NACL)
 | 
| @@ -930,7 +965,7 @@ bool TransportSecurityState::ShouldRequireCT(
 | 
|        }
 | 
|  
 | 
|        // No exception found. This certificate must conform to the CT policy.
 | 
| -      return true;
 | 
| +      return CT_REQUIREMENTS_NOT_MET;
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -1413,8 +1448,10 @@ void TransportSecurityState::ProcessExpectCTHeader(
 | 
|        return;
 | 
|      ExpectCTState state;
 | 
|      if (GetStaticExpectCTState(host_port_pair.host(), &state)) {
 | 
| -      expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri,
 | 
| -                                            ssl_info);
 | 
| +      expect_ct_reporter_->OnExpectCTFailed(
 | 
| +          host_port_pair, state.report_uri, ssl_info.cert.get(),
 | 
| +          ssl_info.unverified_cert.get(),
 | 
| +          ssl_info.signed_certificate_timestamps);
 | 
|      }
 | 
|      return;
 | 
|    }
 | 
| @@ -1447,8 +1484,10 @@ void TransportSecurityState::ProcessExpectCTHeader(
 | 
|      // processing the header.
 | 
|      if (expect_ct_reporter_ && !report_uri.is_empty() &&
 | 
|          !GetDynamicExpectCTState(host_port_pair.host(), &state)) {
 | 
| -      expect_ct_reporter_->OnExpectCTFailed(host_port_pair, report_uri,
 | 
| -                                            ssl_info);
 | 
| +      expect_ct_reporter_->OnExpectCTFailed(
 | 
| +          host_port_pair, report_uri, ssl_info.cert.get(),
 | 
| +          ssl_info.unverified_cert.get(),
 | 
| +          ssl_info.signed_certificate_timestamps);
 | 
|      }
 | 
|      return;
 | 
|    }
 | 
| 
 |