OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/ct_policy_enforcer.h" | 5 #include "net/cert/ct_policy_enforcer.h" |
6 | 6 |
| 7 #include <stdint.h> |
| 8 |
7 #include <algorithm> | 9 #include <algorithm> |
8 #include <memory> | 10 #include <memory> |
9 #include <utility> | 11 #include <utility> |
10 | 12 |
11 #include "base/bind.h" | 13 #include "base/bind.h" |
12 #include "base/build_time.h" | 14 #include "base/build_time.h" |
13 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
14 #include "base/metrics/field_trial.h" | 16 #include "base/metrics/field_trial.h" |
15 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
16 #include "base/numerics/safe_conversions.h" | 18 #include "base/numerics/safe_conversions.h" |
17 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
18 #include "base/time/time.h" | 20 #include "base/time/time.h" |
19 #include "base/values.h" | 21 #include "base/values.h" |
20 #include "base/version.h" | 22 #include "base/version.h" |
21 #include "net/cert/ct_ev_whitelist.h" | 23 #include "net/cert/ct_ev_whitelist.h" |
22 #include "net/cert/ct_known_logs.h" | 24 #include "net/cert/ct_known_logs.h" |
23 #include "net/cert/ct_policy_status.h" | 25 #include "net/cert/ct_policy_status.h" |
24 #include "net/cert/ct_verify_result.h" | 26 #include "net/cert/ct_verify_result.h" |
25 #include "net/cert/signed_certificate_timestamp.h" | 27 #include "net/cert/signed_certificate_timestamp.h" |
26 #include "net/cert/x509_certificate.h" | 28 #include "net/cert/x509_certificate.h" |
27 #include "net/cert/x509_certificate_net_log_param.h" | 29 #include "net/cert/x509_certificate_net_log_param.h" |
28 #include "net/log/net_log.h" | 30 #include "net/log/net_log.h" |
29 | 31 |
30 namespace net { | 32 namespace net { |
31 | 33 |
32 namespace { | 34 namespace { |
33 | 35 |
34 bool IsEmbeddedSCT(const scoped_refptr<ct::SignedCertificateTimestamp>& sct) { | |
35 return sct->origin == ct::SignedCertificateTimestamp::SCT_EMBEDDED; | |
36 } | |
37 | |
38 // Returns true if the current build is recent enough to ensure that | 36 // Returns true if the current build is recent enough to ensure that |
39 // built-in security information (e.g. CT Logs) is fresh enough. | 37 // built-in security information (e.g. CT Logs) is fresh enough. |
40 // TODO(eranm): Move to base or net/base | 38 // TODO(eranm): Move to base or net/base |
41 bool IsBuildTimely() { | 39 bool IsBuildTimely() { |
42 const base::Time build_time = base::GetBuildTime(); | 40 const base::Time build_time = base::GetBuildTime(); |
43 // We consider built-in information to be timely for 10 weeks. | 41 // We consider built-in information to be timely for 10 weeks. |
44 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 42 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
45 } | 43 } |
46 | 44 |
47 bool IsGoogleIssuedSCT( | |
48 const scoped_refptr<ct::SignedCertificateTimestamp>& sct) { | |
49 return ct::IsLogOperatedByGoogle(sct->log_id); | |
50 } | |
51 | |
52 // Returns a rounded-down months difference of |start| and |end|, | 45 // Returns a rounded-down months difference of |start| and |end|, |
53 // together with an indication of whether the last month was | 46 // together with an indication of whether the last month was |
54 // a full month, because the range starts specified in the policy | 47 // a full month, because the range starts specified in the policy |
55 // are not consistent in terms of including the range start value. | 48 // are not consistent in terms of including the range start value. |
56 void RoundedDownMonthDifference(const base::Time& start, | 49 void RoundedDownMonthDifference(const base::Time& start, |
57 const base::Time& end, | 50 const base::Time& end, |
58 size_t* rounded_months_difference, | 51 size_t* rounded_months_difference, |
59 bool* has_partial_month) { | 52 bool* has_partial_month) { |
60 DCHECK(rounded_months_difference); | 53 DCHECK(rounded_months_difference); |
61 DCHECK(has_partial_month); | 54 DCHECK(has_partial_month); |
(...skipping 10 matching lines...) Expand all Loading... |
72 uint32_t month_diff = (exploded_expiry.year - exploded_start.year) * 12 + | 65 uint32_t month_diff = (exploded_expiry.year - exploded_start.year) * 12 + |
73 (exploded_expiry.month - exploded_start.month); | 66 (exploded_expiry.month - exploded_start.month); |
74 if (exploded_expiry.day_of_month < exploded_start.day_of_month) | 67 if (exploded_expiry.day_of_month < exploded_start.day_of_month) |
75 --month_diff; | 68 --month_diff; |
76 else if (exploded_expiry.day_of_month == exploded_start.day_of_month) | 69 else if (exploded_expiry.day_of_month == exploded_start.day_of_month) |
77 *has_partial_month = false; | 70 *has_partial_month = false; |
78 | 71 |
79 *rounded_months_difference = month_diff; | 72 *rounded_months_difference = month_diff; |
80 } | 73 } |
81 | 74 |
82 bool HasRequiredNumberOfSCTs(const X509Certificate& cert, | |
83 const ct::SCTList& verified_scts) { | |
84 size_t num_valid_scts = verified_scts.size(); | |
85 size_t num_embedded_scts = base::checked_cast<size_t>( | |
86 std::count_if(verified_scts.begin(), verified_scts.end(), IsEmbeddedSCT)); | |
87 | |
88 size_t num_non_embedded_scts = num_valid_scts - num_embedded_scts; | |
89 // If at least two valid SCTs were delivered by means other than embedding | |
90 // (i.e. in a TLS extension or OCSP), then the certificate conforms to bullet | |
91 // number 3 of the "Qualifying Certificate" section of the CT/EV policy. | |
92 if (num_non_embedded_scts >= 2) | |
93 return true; | |
94 | |
95 if (cert.valid_start().is_null() || cert.valid_expiry().is_null() || | |
96 cert.valid_start().is_max() || cert.valid_expiry().is_max()) { | |
97 // Will not be able to calculate the certificate's validity period. | |
98 return false; | |
99 } | |
100 | |
101 size_t lifetime; | |
102 bool has_partial_month; | |
103 RoundedDownMonthDifference(cert.valid_start(), cert.valid_expiry(), &lifetime, | |
104 &has_partial_month); | |
105 | |
106 // For embedded SCTs, if the certificate has the number of SCTs specified in | |
107 // table 1 of the "Qualifying Certificate" section of the CT/EV policy, then | |
108 // it qualifies. | |
109 size_t num_required_embedded_scts; | |
110 if (lifetime > 39 || (lifetime == 39 && has_partial_month)) { | |
111 num_required_embedded_scts = 5; | |
112 } else if (lifetime > 27 || (lifetime == 27 && has_partial_month)) { | |
113 num_required_embedded_scts = 4; | |
114 } else if (lifetime >= 15) { | |
115 num_required_embedded_scts = 3; | |
116 } else { | |
117 num_required_embedded_scts = 2; | |
118 } | |
119 | |
120 return num_embedded_scts >= num_required_embedded_scts; | |
121 } | |
122 | |
123 // Returns true if |verified_scts| contains SCTs from at least one log that is | |
124 // operated by Google and at least one log that is not operated by Google. This | |
125 // is required for SCTs after July 1st, 2015, as documented at | |
126 // http://dev.chromium.org/Home/chromium-security/root-ca-policy/EVCTPlanMay2015
edition.pdf | |
127 bool HasEnoughDiverseSCTs(const ct::SCTList& verified_scts) { | |
128 size_t num_google_issued_scts = base::checked_cast<size_t>(std::count_if( | |
129 verified_scts.begin(), verified_scts.end(), IsGoogleIssuedSCT)); | |
130 return (num_google_issued_scts > 0) && | |
131 (verified_scts.size() != num_google_issued_scts); | |
132 } | |
133 | |
134 const char* EVPolicyComplianceToString(ct::EVPolicyCompliance status) { | 75 const char* EVPolicyComplianceToString(ct::EVPolicyCompliance status) { |
135 switch (status) { | 76 switch (status) { |
136 case ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY: | 77 case ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY: |
137 return "POLICY_DOES_NOT_APPLY"; | 78 return "POLICY_DOES_NOT_APPLY"; |
138 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST: | 79 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST: |
139 return "WHITELISTED"; | 80 return "WHITELISTED"; |
140 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS: | 81 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS: |
141 return "COMPLIES_VIA_SCTS"; | 82 return "COMPLIES_VIA_SCTS"; |
142 case ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS: | 83 case ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS: |
143 return "NOT_ENOUGH_SCTS"; | 84 return "NOT_ENOUGH_SCTS"; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 ct::CertPolicyCompliance compliance, | 172 ct::CertPolicyCompliance compliance, |
232 NetLogCaptureMode capture_mode) { | 173 NetLogCaptureMode capture_mode) { |
233 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 174 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
234 dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode)); | 175 dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode)); |
235 dict->SetBoolean("build_timely", build_timely); | 176 dict->SetBoolean("build_timely", build_timely); |
236 dict->SetString("ct_compliance_status", | 177 dict->SetString("ct_compliance_status", |
237 CertPolicyComplianceToString(compliance)); | 178 CertPolicyComplianceToString(compliance)); |
238 return std::move(dict); | 179 return std::move(dict); |
239 } | 180 } |
240 | 181 |
241 // Returns true if all SCTs in |verified_scts| were issued on, or after, the | |
242 // date specified in kDiverseSCTRequirementStartDate | |
243 bool AllSCTsPastDistinctSCTRequirementEnforcementDate( | |
244 const ct::SCTList& verified_scts) { | |
245 // The date when diverse SCTs requirement is effective from. | |
246 // 2015-07-01 00:00:00 UTC. | |
247 base::Time kDiverseSCTRequirementStartDate = | |
248 base::Time::FromInternalValue(13080182400000000); | |
249 | |
250 for (const auto& it : verified_scts) { | |
251 if (it->timestamp < kDiverseSCTRequirementStartDate) | |
252 return false; | |
253 } | |
254 | |
255 return true; | |
256 } | |
257 | |
258 bool IsCertificateInWhitelist(const X509Certificate& cert, | 182 bool IsCertificateInWhitelist(const X509Certificate& cert, |
259 const ct::EVCertsWhitelist* ev_whitelist) { | 183 const ct::EVCertsWhitelist* ev_whitelist) { |
260 bool cert_in_ev_whitelist = false; | 184 if (!ev_whitelist || !ev_whitelist->IsValid()) |
261 if (ev_whitelist && ev_whitelist->IsValid()) { | 185 return false; |
262 const SHA256HashValue fingerprint( | |
263 X509Certificate::CalculateFingerprint256(cert.os_cert_handle())); | |
264 | 186 |
265 std::string truncated_fp = | 187 const SHA256HashValue fingerprint( |
266 std::string(reinterpret_cast<const char*>(fingerprint.data), 8); | 188 X509Certificate::CalculateFingerprint256(cert.os_cert_handle())); |
267 cert_in_ev_whitelist = ev_whitelist->ContainsCertificateHash(truncated_fp); | |
268 | 189 |
269 UMA_HISTOGRAM_BOOLEAN("Net.SSL_EVCertificateInWhitelist", | 190 std::string truncated_fp = |
270 cert_in_ev_whitelist); | 191 std::string(reinterpret_cast<const char*>(fingerprint.data), 8); |
271 } | 192 bool cert_in_ev_whitelist = |
| 193 ev_whitelist->ContainsCertificateHash(truncated_fp); |
| 194 |
| 195 UMA_HISTOGRAM_BOOLEAN("Net.SSL_EVCertificateInWhitelist", |
| 196 cert_in_ev_whitelist); |
272 return cert_in_ev_whitelist; | 197 return cert_in_ev_whitelist; |
273 } | 198 } |
274 | 199 |
| 200 // Evaluates against the policy specified at |
| 201 // https://sites.google.com/a/chromium.org/dev/Home/chromium-security/root-ca-po
licy/EVCTPlanMay2015edition.pdf?attredirects=0 |
275 ct::CertPolicyCompliance CheckCertPolicyCompliance( | 202 ct::CertPolicyCompliance CheckCertPolicyCompliance( |
276 X509Certificate* cert, | 203 const X509Certificate& cert, |
277 const ct::SCTList& verified_scts, | 204 const ct::SCTList& verified_scts) { |
278 const BoundNetLog& net_log) { | 205 // Cert is outside the bounds of parsable; reject it. |
279 if (!HasRequiredNumberOfSCTs(*cert, verified_scts)) | 206 if (cert.valid_start().is_null() || cert.valid_expiry().is_null() || |
| 207 cert.valid_start().is_max() || cert.valid_expiry().is_max()) { |
280 return ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; | 208 return ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; |
281 if (AllSCTsPastDistinctSCTRequirementEnforcementDate(verified_scts) && | 209 } |
282 !HasEnoughDiverseSCTs(verified_scts)) { | 210 |
| 211 // Scan for the earliest SCT. This is used to determine whether to enforce |
| 212 // log diversity requirements, as well as whether to enforce whether or not |
| 213 // a log was qualified or pending qualification at time of issuance (in the |
| 214 // case of embedded SCTs). It's acceptable to ignore the origin of the SCT, |
| 215 // because SCTs delivered via OCSP/TLS extension will cover the full |
| 216 // certificate, which necessarily will exist only after the precertificate |
| 217 // has been logged and the actual certificate issued. |
| 218 // Note: Here, issuance date is defined as the earliest of all SCTs, rather |
| 219 // than the latest of embedded SCTs, in order to give CAs the benefit of |
| 220 // the doubt in the event a log is revoked in the midst of processing |
| 221 // a precertificate and issuing the certificate. |
| 222 base::Time issuance_date = base::Time::Max(); |
| 223 for (const auto& sct : verified_scts) |
| 224 issuance_date = std::min(sct->timestamp, issuance_date); |
| 225 |
| 226 bool has_valid_google_sct = false; |
| 227 bool has_valid_nongoogle_sct = false; |
| 228 bool has_valid_embedded_sct = false; |
| 229 bool has_valid_nonembedded_sct = false; |
| 230 bool has_embedded_google_sct = false; |
| 231 bool has_embedded_nongoogle_sct = false; |
| 232 std::vector<base::StringPiece> embedded_log_ids; |
| 233 for (const auto& sct : verified_scts) { |
| 234 if (ct::IsLogOperatedByGoogle(sct->log_id)) { |
| 235 has_valid_google_sct = true; |
| 236 if (sct->origin == ct::SignedCertificateTimestamp::SCT_EMBEDDED) |
| 237 has_embedded_google_sct = true; |
| 238 } else { |
| 239 has_valid_nongoogle_sct = true; |
| 240 if (sct->origin == ct::SignedCertificateTimestamp::SCT_EMBEDDED) |
| 241 has_embedded_nongoogle_sct = true; |
| 242 } |
| 243 if (sct->origin != ct::SignedCertificateTimestamp::SCT_EMBEDDED) { |
| 244 has_valid_nonembedded_sct = true; |
| 245 } else { |
| 246 has_valid_embedded_sct = true; |
| 247 embedded_log_ids.push_back(sct->log_id); |
| 248 } |
| 249 } |
| 250 |
| 251 // Option 1: |
| 252 // An SCT presented via the TLS extension OR embedded within a stapled OCSP |
| 253 // response is from a log qualified at time of check; |
| 254 // AND there is at least one SCT from a Google Log that is qualified at |
| 255 // time of check, presented via any method; |
| 256 // AND there is at least one SCT from a non-Google Log that is qualified |
| 257 // at the time of check, presented via any method. |
| 258 // |
| 259 // Note: Because SCTs embedded via TLS or OCSP can be updated on the fly, |
| 260 // the issuance date is irrelevant, as any policy changes can be |
| 261 // accomodated. |
| 262 if (has_valid_nonembedded_sct && has_valid_google_sct && |
| 263 has_valid_nongoogle_sct) { |
| 264 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS; |
| 265 } |
| 266 // Note: If has_valid_nonembedded_sct was true, but Option 2 isn't met, |
| 267 // then the result will be that there weren't diverse enough SCTs, as that |
| 268 // the only other way for the conditional above to fail). Because Option 1 |
| 269 // has the diversity requirement, it's implicitly a minimum number of SCTs |
| 270 // (specifically, 2), but that's not explicitly specified in the policy. |
| 271 |
| 272 // Option 2: |
| 273 // There is at least one embedded SCT from a log qualified at the time of |
| 274 // check ... |
| 275 if (!has_valid_embedded_sct) { |
| 276 // Under Option 2, there weren't enough SCTs, and potentially under |
| 277 // Option 1, there weren't diverse enough SCTs. Try to signal the error |
| 278 // that is most easily fixed. |
| 279 return has_valid_nonembedded_sct |
| 280 ? ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS |
| 281 : ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; |
| 282 } |
| 283 |
| 284 // ... AND there is at least one embedded SCT from a Google Log once or |
| 285 // currently qualified; |
| 286 // AND there is at least one embedded SCT from a non-Google Log once or |
| 287 // currently qualified; |
| 288 // ... |
| 289 // |
| 290 // Note: This policy language is only enforced after the below issuance |
| 291 // date, as that's when the diversity policy first came into effect for |
| 292 // SCTs embedded in certificates. |
| 293 // The date when diverse SCTs requirement is effective from. |
| 294 // 2015-07-01 00:00:00 UTC. |
| 295 const base::Time kDiverseSCTRequirementStartDate = |
| 296 base::Time::FromInternalValue(INT64_C(13080182400000000)); |
| 297 if (issuance_date >= kDiverseSCTRequirementStartDate && |
| 298 !(has_embedded_google_sct && has_embedded_nongoogle_sct)) { |
| 299 // Note: This also covers the case for non-embedded SCTs, as it's only |
| 300 // possible to reach here if both sets are not diverse enough. |
283 return ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS; | 301 return ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS; |
284 } | 302 } |
285 | 303 |
286 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS; | 304 size_t lifetime_in_months = 0; |
| 305 bool has_partial_month = false; |
| 306 RoundedDownMonthDifference(cert.valid_start(), cert.valid_expiry(), |
| 307 &lifetime_in_months, &has_partial_month); |
| 308 |
| 309 // ... AND the certificate embeds SCTs from AT LEAST the number of logs |
| 310 // once or currently qualified shown in Table 1 of the CT Policy. |
| 311 size_t num_required_embedded_scts = 5; |
| 312 if (lifetime_in_months > 39 || |
| 313 (lifetime_in_months == 39 && has_partial_month)) { |
| 314 num_required_embedded_scts = 5; |
| 315 } else if (lifetime_in_months > 27 || |
| 316 (lifetime_in_months == 27 && has_partial_month)) { |
| 317 num_required_embedded_scts = 4; |
| 318 } else if (lifetime_in_months >= 15) { |
| 319 num_required_embedded_scts = 3; |
| 320 } else { |
| 321 num_required_embedded_scts = 2; |
| 322 } |
| 323 |
| 324 // Sort the embedded log IDs and remove duplicates, so that only a single |
| 325 // SCT from each log is accepted. This is to handle the case where a given |
| 326 // log returns different SCTs for the same precertificate (which is |
| 327 // permitted, but advised against). |
| 328 std::sort(embedded_log_ids.begin(), embedded_log_ids.end()); |
| 329 auto sorted_end = |
| 330 std::unique(embedded_log_ids.begin(), embedded_log_ids.end()); |
| 331 size_t num_embedded_scts = |
| 332 std::distance(embedded_log_ids.begin(), sorted_end); |
| 333 |
| 334 if (num_embedded_scts >= num_required_embedded_scts) |
| 335 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS; |
| 336 |
| 337 // Under Option 2, there weren't enough SCTs, and potentially under Option |
| 338 // 1, there weren't diverse enough SCTs. Try to signal the error that is |
| 339 // most easily fixed. |
| 340 return has_valid_nonembedded_sct |
| 341 ? ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS |
| 342 : ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; |
287 } | 343 } |
288 | 344 |
289 ct::EVPolicyCompliance CertPolicyComplianceToEVPolicyCompliance( | 345 ct::EVPolicyCompliance CertPolicyComplianceToEVPolicyCompliance( |
290 ct::CertPolicyCompliance cert_policy_compliance) { | 346 ct::CertPolicyCompliance cert_policy_compliance) { |
291 switch (cert_policy_compliance) { | 347 switch (cert_policy_compliance) { |
292 case ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS: | 348 case ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS: |
293 return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS; | 349 return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS; |
294 case ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS: | 350 case ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS: |
295 return ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS; | 351 return ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS; |
296 case ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS: | 352 case ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS: |
297 return ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS; | 353 return ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS; |
298 case ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY: | 354 case ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY: |
299 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; | 355 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; |
300 } | 356 } |
301 return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; | 357 return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; |
302 } | 358 } |
303 | 359 |
304 void CheckCTEVPolicyCompliance(X509Certificate* cert, | 360 void CheckCTEVPolicyCompliance(X509Certificate* cert, |
305 const ct::EVCertsWhitelist* ev_whitelist, | 361 const ct::EVCertsWhitelist* ev_whitelist, |
306 const ct::SCTList& verified_scts, | 362 const ct::SCTList& verified_scts, |
307 const BoundNetLog& net_log, | 363 const BoundNetLog& net_log, |
308 EVComplianceDetails* result) { | 364 EVComplianceDetails* result) { |
309 result->status = CertPolicyComplianceToEVPolicyCompliance( | 365 result->status = CertPolicyComplianceToEVPolicyCompliance( |
310 CheckCertPolicyCompliance(cert, verified_scts, net_log)); | 366 CheckCertPolicyCompliance(*cert, verified_scts)); |
311 if (ev_whitelist && ev_whitelist->IsValid()) | 367 if (ev_whitelist && ev_whitelist->IsValid()) |
312 result->whitelist_version = ev_whitelist->Version(); | 368 result->whitelist_version = ev_whitelist->Version(); |
313 | 369 |
314 if (result->status != ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS && | 370 if (result->status != ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS && |
315 IsCertificateInWhitelist(*cert, ev_whitelist)) { | 371 IsCertificateInWhitelist(*cert, ev_whitelist)) { |
316 result->status = ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST; | 372 result->status = ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST; |
317 } | 373 } |
318 } | 374 } |
319 | 375 |
320 } // namespace | 376 } // namespace |
321 | 377 |
322 ct::CertPolicyCompliance CTPolicyEnforcer::DoesConformToCertPolicy( | 378 ct::CertPolicyCompliance CTPolicyEnforcer::DoesConformToCertPolicy( |
323 X509Certificate* cert, | 379 X509Certificate* cert, |
324 const ct::SCTList& verified_scts, | 380 const ct::SCTList& verified_scts, |
325 const BoundNetLog& net_log) { | 381 const BoundNetLog& net_log) { |
326 // If the build is not timely, no certificate is considered compliant | 382 // If the build is not timely, no certificate is considered compliant |
327 // with CT policy. The reasoning is that, for example, a log might | 383 // with CT policy. The reasoning is that, for example, a log might |
328 // have been pulled and is no longer considered valid; thus, a client | 384 // have been pulled and is no longer considered valid; thus, a client |
329 // needs up-to-date information about logs to consider certificates to | 385 // needs up-to-date information about logs to consider certificates to |
330 // be compliant with policy. | 386 // be compliant with policy. |
331 bool build_timely = IsBuildTimely(); | 387 bool build_timely = IsBuildTimely(); |
332 ct::CertPolicyCompliance compliance; | 388 ct::CertPolicyCompliance compliance; |
333 if (!build_timely) { | 389 if (!build_timely) { |
334 compliance = ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY; | 390 compliance = ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY; |
335 } else { | 391 } else { |
336 compliance = CheckCertPolicyCompliance(cert, verified_scts, net_log); | 392 compliance = CheckCertPolicyCompliance(*cert, verified_scts); |
337 } | 393 } |
338 | 394 |
339 NetLog::ParametersCallback net_log_callback = | 395 NetLog::ParametersCallback net_log_callback = |
340 base::Bind(&NetLogCertComplianceCheckResultCallback, | 396 base::Bind(&NetLogCertComplianceCheckResultCallback, |
341 base::Unretained(cert), build_timely, compliance); | 397 base::Unretained(cert), build_timely, compliance); |
342 | 398 |
343 net_log.AddEvent(NetLog::TYPE_CERT_CT_COMPLIANCE_CHECKED, net_log_callback); | 399 net_log.AddEvent(NetLog::TYPE_CERT_CT_COMPLIANCE_CHECKED, net_log_callback); |
344 | 400 |
345 return compliance; | 401 return compliance; |
346 } | 402 } |
(...skipping 26 matching lines...) Expand all Loading... |
373 | 429 |
374 if (!details.build_timely) | 430 if (!details.build_timely) |
375 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; | 431 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; |
376 | 432 |
377 LogEVPolicyComplianceToUMA(details.status, ev_whitelist); | 433 LogEVPolicyComplianceToUMA(details.status, ev_whitelist); |
378 | 434 |
379 return details.status; | 435 return details.status; |
380 } | 436 } |
381 | 437 |
382 } // namespace net | 438 } // namespace net |
OLD | NEW |