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 <algorithm> | 7 #include <algorithm> |
8 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "net/cert/ct_verify_result.h" | 24 #include "net/cert/ct_verify_result.h" |
25 #include "net/cert/signed_certificate_timestamp.h" | 25 #include "net/cert/signed_certificate_timestamp.h" |
26 #include "net/cert/x509_certificate.h" | 26 #include "net/cert/x509_certificate.h" |
27 #include "net/cert/x509_certificate_net_log_param.h" | 27 #include "net/cert/x509_certificate_net_log_param.h" |
28 #include "net/log/net_log.h" | 28 #include "net/log/net_log.h" |
29 | 29 |
30 namespace net { | 30 namespace net { |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
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 | 34 // Returns true if the current build is recent enough to ensure that |
39 // built-in security information (e.g. CT Logs) is fresh enough. | 35 // built-in security information (e.g. CT Logs) is fresh enough. |
40 // TODO(eranm): Move to base or net/base | 36 // TODO(eranm): Move to base or net/base |
41 bool IsBuildTimely() { | 37 bool IsBuildTimely() { |
42 const base::Time build_time = base::GetBuildTime(); | 38 const base::Time build_time = base::GetBuildTime(); |
43 // We consider built-in information to be timely for 10 weeks. | 39 // We consider built-in information to be timely for 10 weeks. |
44 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 40 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
45 } | 41 } |
46 | 42 |
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|, | 43 // Returns a rounded-down months difference of |start| and |end|, |
53 // together with an indication of whether the last month was | 44 // together with an indication of whether the last month was |
54 // a full month, because the range starts specified in the policy | 45 // a full month, because the range starts specified in the policy |
55 // are not consistent in terms of including the range start value. | 46 // are not consistent in terms of including the range start value. |
56 void RoundedDownMonthDifference(const base::Time& start, | 47 void RoundedDownMonthDifference(const base::Time& start, |
57 const base::Time& end, | 48 const base::Time& end, |
58 size_t* rounded_months_difference, | 49 size_t* rounded_months_difference, |
59 bool* has_partial_month) { | 50 bool* has_partial_month) { |
60 DCHECK(rounded_months_difference); | 51 DCHECK(rounded_months_difference); |
61 DCHECK(has_partial_month); | 52 DCHECK(has_partial_month); |
(...skipping 10 matching lines...) Expand all Loading... | |
72 uint32_t month_diff = (exploded_expiry.year - exploded_start.year) * 12 + | 63 uint32_t month_diff = (exploded_expiry.year - exploded_start.year) * 12 + |
73 (exploded_expiry.month - exploded_start.month); | 64 (exploded_expiry.month - exploded_start.month); |
74 if (exploded_expiry.day_of_month < exploded_start.day_of_month) | 65 if (exploded_expiry.day_of_month < exploded_start.day_of_month) |
75 --month_diff; | 66 --month_diff; |
76 else if (exploded_expiry.day_of_month == exploded_start.day_of_month) | 67 else if (exploded_expiry.day_of_month == exploded_start.day_of_month) |
77 *has_partial_month = false; | 68 *has_partial_month = false; |
78 | 69 |
79 *rounded_months_difference = month_diff; | 70 *rounded_months_difference = month_diff; |
80 } | 71 } |
81 | 72 |
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) { | 73 const char* EVPolicyComplianceToString(ct::EVPolicyCompliance status) { |
135 switch (status) { | 74 switch (status) { |
136 case ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY: | 75 case ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY: |
137 return "POLICY_DOES_NOT_APPLY"; | 76 return "POLICY_DOES_NOT_APPLY"; |
138 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST: | 77 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST: |
139 return "WHITELISTED"; | 78 return "WHITELISTED"; |
140 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS: | 79 case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS: |
141 return "COMPLIES_VIA_SCTS"; | 80 return "COMPLIES_VIA_SCTS"; |
142 case ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS: | 81 case ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS: |
143 return "NOT_ENOUGH_SCTS"; | 82 return "NOT_ENOUGH_SCTS"; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
231 ct::CertPolicyCompliance compliance, | 170 ct::CertPolicyCompliance compliance, |
232 NetLogCaptureMode capture_mode) { | 171 NetLogCaptureMode capture_mode) { |
233 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 172 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
234 dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode)); | 173 dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode)); |
235 dict->SetBoolean("build_timely", build_timely); | 174 dict->SetBoolean("build_timely", build_timely); |
236 dict->SetString("ct_compliance_status", | 175 dict->SetString("ct_compliance_status", |
237 CertPolicyComplianceToString(compliance)); | 176 CertPolicyComplianceToString(compliance)); |
238 return std::move(dict); | 177 return std::move(dict); |
239 } | 178 } |
240 | 179 |
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, | 180 bool IsCertificateInWhitelist(const X509Certificate& cert, |
259 const ct::EVCertsWhitelist* ev_whitelist) { | 181 const ct::EVCertsWhitelist* ev_whitelist) { |
260 bool cert_in_ev_whitelist = false; | 182 if (!ev_whitelist || !ev_whitelist->IsValid()) |
eroman
2016/05/04 19:56:23
Side-remark: When reading this it wasn't obvious t
Ryan Sleevi
2016/05/04 20:59:19
I'm not sure what you mean that it's not clear. It
eroman
2016/05/04 21:26:35
My feedback was to update the public API, DoesConf
| |
261 if (ev_whitelist && ev_whitelist->IsValid()) { | 183 return false; |
262 const SHA256HashValue fingerprint( | |
263 X509Certificate::CalculateFingerprint256(cert.os_cert_handle())); | |
264 | 184 |
265 std::string truncated_fp = | 185 const SHA256HashValue fingerprint( |
266 std::string(reinterpret_cast<const char*>(fingerprint.data), 8); | 186 X509Certificate::CalculateFingerprint256(cert.os_cert_handle())); |
267 cert_in_ev_whitelist = ev_whitelist->ContainsCertificateHash(truncated_fp); | |
268 | 187 |
269 UMA_HISTOGRAM_BOOLEAN("Net.SSL_EVCertificateInWhitelist", | 188 std::string truncated_fp = |
270 cert_in_ev_whitelist); | 189 std::string(reinterpret_cast<const char*>(fingerprint.data), 8); |
271 } | 190 bool cert_in_ev_whitelist = |
191 ev_whitelist->ContainsCertificateHash(truncated_fp); | |
192 | |
193 UMA_HISTOGRAM_BOOLEAN("Net.SSL_EVCertificateInWhitelist", | |
194 cert_in_ev_whitelist); | |
272 return cert_in_ev_whitelist; | 195 return cert_in_ev_whitelist; |
273 } | 196 } |
274 | 197 |
275 ct::CertPolicyCompliance CheckCertPolicyCompliance( | 198 ct::CertPolicyCompliance CheckCertPolicyCompliance( |
276 X509Certificate* cert, | 199 const X509Certificate& cert, |
277 const ct::SCTList& verified_scts, | 200 const ct::SCTList& verified_scts) { |
278 const BoundNetLog& net_log) { | 201 // Cert is outside the bounds of parsable; reject it. |
279 if (!HasRequiredNumberOfSCTs(*cert, verified_scts)) | 202 if (cert.valid_start().is_null() || cert.valid_expiry().is_null() || |
203 cert.valid_start().is_max() || cert.valid_expiry().is_max()) { | |
280 return ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; | 204 return ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; |
281 if (AllSCTsPastDistinctSCTRequirementEnforcementDate(verified_scts) && | 205 } |
282 !HasEnoughDiverseSCTs(verified_scts)) { | 206 |
207 // Scan for the earliest SCT. This is used to determine whether to enforce | |
208 // log diversity requirements, as well as whether to enforce whether or not | |
209 // a log was qualified or pending qualification at time of issuance (in the | |
210 // case of embedded SCTs). It's acceptable to ignore the origin of the SCT, | |
211 // because SCTs delivered via OCSP/TLS extension will cover the full | |
212 // certificate, which necessarily will exist only after the precertificate | |
213 // has been logged and the actual certificate issued. | |
214 // Note: Here, issuance date is defined as the earliest of all SCTs, rather | |
215 // than the latest of embedded SCTs, in order to give CAs the benefit of | |
216 // the doubt in the event a log is revoked in the midst of processing | |
217 // a precertificate and issuing the certificate. | |
218 base::Time issuance_date = base::Time::Max(); | |
219 for (const auto& sct : verified_scts) | |
220 issuance_date = std::min(sct->timestamp, issuance_date); | |
221 | |
222 bool has_valid_google_sct = false; | |
223 bool has_valid_nongoogle_sct = false; | |
224 bool has_valid_embedded_sct = false; | |
225 bool has_valid_nonembedded_sct = false; | |
226 bool has_embedded_google_sct = false; | |
227 bool has_embedded_nongoogle_sct = false; | |
228 std::vector<base::StringPiece> embedded_log_ids; | |
229 for (const auto& sct : verified_scts) { | |
230 if (ct::IsLogOperatedByGoogle(sct->log_id)) { | |
231 has_valid_google_sct = true; | |
232 if (sct->origin == ct::SignedCertificateTimestamp::SCT_EMBEDDED) | |
233 has_embedded_google_sct = true; | |
234 } else { | |
235 has_valid_nongoogle_sct = true; | |
236 if (sct->origin == ct::SignedCertificateTimestamp::SCT_EMBEDDED) | |
237 has_embedded_nongoogle_sct = true; | |
238 } | |
239 if (sct->origin != ct::SignedCertificateTimestamp::SCT_EMBEDDED) { | |
240 has_valid_nonembedded_sct = true; | |
241 } else { | |
242 has_valid_embedded_sct = true; | |
243 embedded_log_ids.push_back(sct->log_id); | |
244 } | |
245 } | |
246 | |
247 // Option 1: | |
248 // An SCT presented via the TLS extension OR embedded within a stapled OCSP | |
249 // response is from a log qualified at time of check; | |
eroman
2016/05/04 19:56:23
Not sure about this formatting... But I do like th
| |
250 // AND there is at least one SCT from a Google Log that is qualified at | |
251 // time of check, presented via any method; | |
252 // AND there is at least one SCT from a non-Google Log that is qualified | |
253 // at the time of check, presented via any method. | |
254 // | |
255 // Note: Because SCTs embedded via TLS or OCSP can be updated on the fly, | |
256 // the issuance date is irrelevant, as any policy changes can be | |
257 // accomodated. | |
258 if (has_valid_nonembedded_sct && has_valid_google_sct && | |
259 has_valid_nongoogle_sct) { | |
260 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS; | |
261 } | |
262 // Note: If has_valid_nonembedded_sct was true, but Option 2 isn't met, | |
263 // then the result will be that there weren't diverse enough SCTs, as that | |
264 // the only other way for the conditional above to fail). Because Option 1 | |
265 // has the diversity requirement, it's implicitly a minimum number of SCTs | |
266 // (specifically, 2), but that's not explicitly specified in the policy. | |
267 | |
268 // Option 2: | |
269 // There is at least one embedded SCT from a log qualified at the time of | |
270 // check ... | |
271 if (!has_valid_embedded_sct) { | |
272 // Under Option 2, there weren't enough SCTs, and potentially under | |
273 // Option 1, there weren't diverse enough SCTs. Try to signal the error | |
274 // that is most easily fixed. | |
275 return has_valid_nonembedded_sct | |
276 ? ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS | |
277 : ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; | |
278 } | |
279 | |
280 // ... AND there is at least one embedded SCT from a Google Log once or | |
281 // currently qualified; | |
282 // AND there is at least one embedded SCT from a non-Google Log once or | |
283 // currently qualified; | |
284 // ... | |
285 // | |
286 // Note: This policy language is only enforced after the below issuance | |
287 // date, as that's when the diversity policy first came into effect for | |
288 // SCTs embedded in certificates. | |
289 // The date when diverse SCTs requirement is effective from. | |
290 // 2015-07-01 00:00:00 UTC. | |
291 const base::Time kDiverseSCTRequirementStartDate = | |
292 base::Time::FromInternalValue(13080182400000000); | |
eroman
2016/05/04 19:56:23
I wouldn't have expected the compiler to be happy
Ryan Sleevi
2016/05/04 20:59:19
You're right, that should have been INT64_C(...).
eroman
2016/05/04 21:26:35
I still have issues with using FromInternalValue()
| |
293 if (issuance_date >= kDiverseSCTRequirementStartDate && | |
294 !(has_embedded_google_sct && has_embedded_nongoogle_sct)) { | |
295 // Note: This also covers the case for non-embedded SCTs, as it's only | |
296 // possible to reach here if both sets are not diverse enough. | |
283 return ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS; | 297 return ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS; |
284 } | 298 } |
285 | 299 |
286 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS; | 300 size_t lifetime_in_months = 0; |
301 bool has_partial_month = false; | |
302 RoundedDownMonthDifference(cert.valid_start(), cert.valid_expiry(), | |
303 &lifetime_in_months, &has_partial_month); | |
304 | |
305 // ... AND the certificate embeds SCTs from AT LEAST the number of logs | |
306 // once or currently qualified shown in Table 1 of the CT Policy. | |
307 size_t num_required_embedded_scts = 5; | |
308 if (lifetime_in_months > 39 || | |
309 (lifetime_in_months == 39 && has_partial_month)) { | |
310 num_required_embedded_scts = 5; | |
311 } else if (lifetime_in_months > 27 || | |
312 (lifetime_in_months == 27 && has_partial_month)) { | |
313 num_required_embedded_scts = 4; | |
314 } else if (lifetime_in_months >= 15) { | |
315 num_required_embedded_scts = 3; | |
316 } else { | |
317 num_required_embedded_scts = 2; | |
318 } | |
319 | |
320 // Sort the embedded log IDs and remove duplicates, so that only a single | |
321 // SCT from each log is accepted. This is to handle the case where a given | |
322 // log returns different SCTs for the same precertificate (which is | |
323 // permitted, but advised against). | |
324 std::sort(embedded_log_ids.begin(), embedded_log_ids.end()); | |
325 auto sorted_end = | |
326 std::unique(embedded_log_ids.begin(), embedded_log_ids.end()); | |
327 size_t num_embedded_scts = | |
328 std::distance(embedded_log_ids.begin(), sorted_end); | |
329 | |
330 if (num_embedded_scts >= num_required_embedded_scts) | |
331 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS; | |
332 | |
333 // Under Option 2, there weren't enough SCTs, and potentially under Option | |
334 // 1, there weren't diverse enough SCTs. Try to signal the error that is | |
335 // most easily fixed. | |
336 return has_valid_nonembedded_sct | |
337 ? ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS | |
338 : ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS; | |
287 } | 339 } |
288 | 340 |
289 ct::EVPolicyCompliance CertPolicyComplianceToEVPolicyCompliance( | 341 ct::EVPolicyCompliance CertPolicyComplianceToEVPolicyCompliance( |
290 ct::CertPolicyCompliance cert_policy_compliance) { | 342 ct::CertPolicyCompliance cert_policy_compliance) { |
291 switch (cert_policy_compliance) { | 343 switch (cert_policy_compliance) { |
292 case ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS: | 344 case ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS: |
293 return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS; | 345 return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS; |
294 case ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS: | 346 case ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS: |
295 return ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS; | 347 return ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS; |
296 case ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS: | 348 case ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS: |
297 return ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS; | 349 return ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS; |
298 case ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY: | 350 case ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY: |
299 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; | 351 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; |
300 } | 352 } |
301 return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; | 353 return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; |
302 } | 354 } |
303 | 355 |
304 void CheckCTEVPolicyCompliance(X509Certificate* cert, | 356 void CheckCTEVPolicyCompliance(X509Certificate* cert, |
305 const ct::EVCertsWhitelist* ev_whitelist, | 357 const ct::EVCertsWhitelist* ev_whitelist, |
306 const ct::SCTList& verified_scts, | 358 const ct::SCTList& verified_scts, |
307 const BoundNetLog& net_log, | 359 const BoundNetLog& net_log, |
308 EVComplianceDetails* result) { | 360 EVComplianceDetails* result) { |
309 result->status = CertPolicyComplianceToEVPolicyCompliance( | 361 result->status = CertPolicyComplianceToEVPolicyCompliance( |
310 CheckCertPolicyCompliance(cert, verified_scts, net_log)); | 362 CheckCertPolicyCompliance(*cert, verified_scts)); |
311 if (ev_whitelist && ev_whitelist->IsValid()) | 363 if (ev_whitelist && ev_whitelist->IsValid()) |
312 result->whitelist_version = ev_whitelist->Version(); | 364 result->whitelist_version = ev_whitelist->Version(); |
313 | 365 |
314 if (result->status != ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS && | 366 if (result->status != ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS && |
315 IsCertificateInWhitelist(*cert, ev_whitelist)) { | 367 IsCertificateInWhitelist(*cert, ev_whitelist)) { |
316 result->status = ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST; | 368 result->status = ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST; |
317 } | 369 } |
318 } | 370 } |
319 | 371 |
320 } // namespace | 372 } // namespace |
321 | 373 |
322 ct::CertPolicyCompliance CTPolicyEnforcer::DoesConformToCertPolicy( | 374 ct::CertPolicyCompliance CTPolicyEnforcer::DoesConformToCertPolicy( |
323 X509Certificate* cert, | 375 X509Certificate* cert, |
324 const ct::SCTList& verified_scts, | 376 const ct::SCTList& verified_scts, |
325 const BoundNetLog& net_log) { | 377 const BoundNetLog& net_log) { |
326 // If the build is not timely, no certificate is considered compliant | 378 // If the build is not timely, no certificate is considered compliant |
327 // with CT policy. The reasoning is that, for example, a log might | 379 // 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 | 380 // have been pulled and is no longer considered valid; thus, a client |
329 // needs up-to-date information about logs to consider certificates to | 381 // needs up-to-date information about logs to consider certificates to |
330 // be compliant with policy. | 382 // be compliant with policy. |
331 bool build_timely = IsBuildTimely(); | 383 bool build_timely = IsBuildTimely(); |
332 ct::CertPolicyCompliance compliance; | 384 ct::CertPolicyCompliance compliance; |
333 if (!build_timely) { | 385 if (!build_timely) { |
334 compliance = ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY; | 386 compliance = ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY; |
335 } else { | 387 } else { |
336 compliance = CheckCertPolicyCompliance(cert, verified_scts, net_log); | 388 compliance = CheckCertPolicyCompliance(*cert, verified_scts); |
337 } | 389 } |
338 | 390 |
339 NetLog::ParametersCallback net_log_callback = | 391 NetLog::ParametersCallback net_log_callback = |
340 base::Bind(&NetLogCertComplianceCheckResultCallback, | 392 base::Bind(&NetLogCertComplianceCheckResultCallback, |
341 base::Unretained(cert), build_timely, compliance); | 393 base::Unretained(cert), build_timely, compliance); |
342 | 394 |
343 net_log.AddEvent(NetLog::TYPE_CERT_CT_COMPLIANCE_CHECKED, net_log_callback); | 395 net_log.AddEvent(NetLog::TYPE_CERT_CT_COMPLIANCE_CHECKED, net_log_callback); |
344 | 396 |
345 return compliance; | 397 return compliance; |
346 } | 398 } |
(...skipping 26 matching lines...) Expand all Loading... | |
373 | 425 |
374 if (!details.build_timely) | 426 if (!details.build_timely) |
375 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; | 427 return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY; |
376 | 428 |
377 LogEVPolicyComplianceToUMA(details.status, ev_whitelist); | 429 LogEVPolicyComplianceToUMA(details.status, ev_whitelist); |
378 | 430 |
379 return details.status; | 431 return details.status; |
380 } | 432 } |
381 | 433 |
382 } // namespace net | 434 } // namespace net |
OLD | NEW |