OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/internal/verify_certificate_chain.h" | 5 #include "net/cert/internal/verify_certificate_chain.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 // | 86 // |
87 // The certificate's validity requirements are described by RFC 5280 section | 87 // The certificate's validity requirements are described by RFC 5280 section |
88 // 4.1.2.5: | 88 // 4.1.2.5: |
89 // | 89 // |
90 // The validity period for a certificate is the period of time from | 90 // The validity period for a certificate is the period of time from |
91 // notBefore through notAfter, inclusive. | 91 // notBefore through notAfter, inclusive. |
92 WARN_UNUSED_RESULT bool VerifyTimeValidity(const ParsedCertificate& cert, | 92 WARN_UNUSED_RESULT bool VerifyTimeValidity(const ParsedCertificate& cert, |
93 const der::GeneralizedTime time, | 93 const der::GeneralizedTime time, |
94 CertErrors* errors) { | 94 CertErrors* errors) { |
95 if (time < cert.tbs().validity_not_before) { | 95 if (time < cert.tbs().validity_not_before) { |
96 errors->Add(kValidityFailedNotBefore); | 96 errors->AddError(kValidityFailedNotBefore); |
97 return false; | 97 return false; |
98 } | 98 } |
99 | 99 |
100 if (cert.tbs().validity_not_after < time) { | 100 if (cert.tbs().validity_not_after < time) { |
101 errors->Add(kValidityFailedNotAfter); | 101 errors->AddError(kValidityFailedNotAfter); |
102 return false; | 102 return false; |
103 } | 103 } |
104 | 104 |
105 return true; | 105 return true; |
106 } | 106 } |
107 | 107 |
108 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for | 108 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for |
109 // RSA with SHA1. | 109 // RSA with SHA1. |
110 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( | 110 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( |
111 const der::Input& signature_algorithm_tlv) { | 111 const der::Input& signature_algorithm_tlv) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 if (!cert.has_valid_supported_signature_algorithm()) { | 187 if (!cert.has_valid_supported_signature_algorithm()) { |
188 errors->AddError( | 188 errors->AddError( |
189 kInvalidOrUnsupportedSignatureAlgorithm, | 189 kInvalidOrUnsupportedSignatureAlgorithm, |
190 CreateCertErrorParams1Der("algorithm", cert.signature_algorithm_tlv())); | 190 CreateCertErrorParams1Der("algorithm", cert.signature_algorithm_tlv())); |
191 return false; | 191 return false; |
192 } | 192 } |
193 | 193 |
194 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), | 194 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), |
195 cert.signature_value(), working_spki, signature_policy, | 195 cert.signature_value(), working_spki, signature_policy, |
196 errors)) { | 196 errors)) { |
197 errors->Add(kVerifySignedDataFailed); | 197 errors->AddError(kVerifySignedDataFailed); |
198 return false; | 198 return false; |
199 } | 199 } |
200 | 200 |
201 // Check the time range for the certificate's validity, ensuring it is valid | 201 // Check the time range for the certificate's validity, ensuring it is valid |
202 // at |time|. | 202 // at |time|. |
203 // (RFC 5280 section 6.1.3 step a.2) | 203 // (RFC 5280 section 6.1.3 step a.2) |
204 if (!VerifyTimeValidity(cert, time, errors)) | 204 if (!VerifyTimeValidity(cert, time, errors)) |
205 return false; | 205 return false; |
206 | 206 |
207 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) | 207 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) |
208 | 208 |
209 // Verify the certificate's issuer name matches the issuing certificate's | 209 // Verify the certificate's issuer name matches the issuing certificate's |
210 // subject name. (RFC 5280 section 6.1.3 step a.4) | 210 // subject name. (RFC 5280 section 6.1.3 step a.4) |
211 if (cert.normalized_issuer() != working_normalized_issuer_name) { | 211 if (cert.normalized_issuer() != working_normalized_issuer_name) { |
212 errors->Add(kSubjectDoesNotMatchIssuer); | 212 errors->AddError(kSubjectDoesNotMatchIssuer); |
213 return false; | 213 return false; |
214 } | 214 } |
215 | 215 |
216 // Name constraints (RFC 5280 section 6.1.3 step b & c) | 216 // Name constraints (RFC 5280 section 6.1.3 step b & c) |
217 // If certificate i is self-issued and it is not the final certificate in the | 217 // If certificate i is self-issued and it is not the final certificate in the |
218 // path, skip this step for certificate i. | 218 // path, skip this step for certificate i. |
219 if (!name_constraints_list.empty() && | 219 if (!name_constraints_list.empty() && |
220 (!IsSelfIssued(cert) || is_target_cert)) { | 220 (!IsSelfIssued(cert) || is_target_cert)) { |
221 for (const NameConstraints* nc : name_constraints_list) { | 221 for (const NameConstraints* nc : name_constraints_list) { |
222 if (!nc->IsPermittedCert(cert.normalized_subject(), | 222 if (!nc->IsPermittedCert(cert.normalized_subject(), |
223 cert.subject_alt_names())) { | 223 cert.subject_alt_names())) { |
224 errors->Add(kNotPermittedByNameConstraints); | 224 errors->AddError(kNotPermittedByNameConstraints); |
225 return false; | 225 return false; |
226 } | 226 } |
227 } | 227 } |
228 } | 228 } |
229 | 229 |
230 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet | 230 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet |
231 // implemented. | 231 // implemented. |
232 | 232 |
233 return true; | 233 return true; |
234 } | 234 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 // TRUE. (If certificate i is a version 1 or version 2 | 273 // TRUE. (If certificate i is a version 1 or version 2 |
274 // certificate, then the application MUST either verify that | 274 // certificate, then the application MUST either verify that |
275 // certificate i is a CA certificate through out-of-band means | 275 // certificate i is a CA certificate through out-of-band means |
276 // or reject the certificate. Conforming implementations may | 276 // or reject the certificate. Conforming implementations may |
277 // choose to reject all version 1 and version 2 intermediate | 277 // choose to reject all version 1 and version 2 intermediate |
278 // certificates.) | 278 // certificates.) |
279 // | 279 // |
280 // This code implicitly rejects non version 3 intermediates, since they | 280 // This code implicitly rejects non version 3 intermediates, since they |
281 // can't contain a BasicConstraints extension. | 281 // can't contain a BasicConstraints extension. |
282 if (!cert.has_basic_constraints()) { | 282 if (!cert.has_basic_constraints()) { |
283 errors->Add(kMissingBasicConstraints); | 283 errors->AddError(kMissingBasicConstraints); |
284 return false; | 284 return false; |
285 } | 285 } |
286 | 286 |
287 if (!cert.basic_constraints().is_ca) { | 287 if (!cert.basic_constraints().is_ca) { |
288 errors->Add(kBasicConstraintsIndicatesNotCa); | 288 errors->AddError(kBasicConstraintsIndicatesNotCa); |
289 return false; | 289 return false; |
290 } | 290 } |
291 | 291 |
292 // From RFC 5280 section 6.1.4 step l: | 292 // From RFC 5280 section 6.1.4 step l: |
293 // | 293 // |
294 // If the certificate was not self-issued, verify that | 294 // If the certificate was not self-issued, verify that |
295 // max_path_length is greater than zero and decrement | 295 // max_path_length is greater than zero and decrement |
296 // max_path_length by 1. | 296 // max_path_length by 1. |
297 if (!IsSelfIssued(cert)) { | 297 if (!IsSelfIssued(cert)) { |
298 if (*max_path_length_ptr == 0) { | 298 if (*max_path_length_ptr == 0) { |
299 errors->Add(kMaxPathLengthViolated); | 299 errors->AddError(kMaxPathLengthViolated); |
300 return false; | 300 return false; |
301 } | 301 } |
302 --(*max_path_length_ptr); | 302 --(*max_path_length_ptr); |
303 } | 303 } |
304 | 304 |
305 // From RFC 5280 section 6.1.4 step m: | 305 // From RFC 5280 section 6.1.4 step m: |
306 // | 306 // |
307 // If pathLenConstraint is present in the certificate and is | 307 // If pathLenConstraint is present in the certificate and is |
308 // less than max_path_length, set max_path_length to the value | 308 // less than max_path_length, set max_path_length to the value |
309 // of pathLenConstraint. | 309 // of pathLenConstraint. |
310 if (cert.basic_constraints().has_path_len && | 310 if (cert.basic_constraints().has_path_len && |
311 cert.basic_constraints().path_len < *max_path_length_ptr) { | 311 cert.basic_constraints().path_len < *max_path_length_ptr) { |
312 *max_path_length_ptr = cert.basic_constraints().path_len; | 312 *max_path_length_ptr = cert.basic_constraints().path_len; |
313 } | 313 } |
314 | 314 |
315 // From RFC 5280 section 6.1.4 step n: | 315 // From RFC 5280 section 6.1.4 step n: |
316 // | 316 // |
317 // If a key usage extension is present, verify that the | 317 // If a key usage extension is present, verify that the |
318 // keyCertSign bit is set. | 318 // keyCertSign bit is set. |
319 if (cert.has_key_usage() && | 319 if (cert.has_key_usage() && |
320 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { | 320 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { |
321 errors->Add(kKeyCertSignBitNotSet); | 321 errors->AddError(kKeyCertSignBitNotSet); |
322 return false; | 322 return false; |
323 } | 323 } |
324 | 324 |
325 // From RFC 5280 section 6.1.4 step o: | 325 // From RFC 5280 section 6.1.4 step o: |
326 // | 326 // |
327 // Recognize and process any other critical extension present in | 327 // Recognize and process any other critical extension present in |
328 // the certificate. Process any other recognized non-critical | 328 // the certificate. Process any other recognized non-critical |
329 // extension present in the certificate that is relevant to path | 329 // extension present in the certificate that is relevant to path |
330 // processing. | 330 // processing. |
331 if (!VerifyNoUnconsumedCriticalExtensions(cert, errors)) | 331 if (!VerifyNoUnconsumedCriticalExtensions(cert, errors)) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 369 |
370 // If it "looks" like a CA because it has a CA-only property, then check that | 370 // If it "looks" like a CA because it has a CA-only property, then check that |
371 // it sets ALL the properties expected of a CA. | 371 // it sets ALL the properties expected of a CA. |
372 if (has_ca_property) { | 372 if (has_ca_property) { |
373 bool success = cert.has_basic_constraints() && | 373 bool success = cert.has_basic_constraints() && |
374 cert.basic_constraints().is_ca && | 374 cert.basic_constraints().is_ca && |
375 (!cert.has_key_usage() || | 375 (!cert.has_key_usage() || |
376 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); | 376 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); |
377 if (!success) { | 377 if (!success) { |
378 // TODO(eroman): Add DER for basic constraints and key usage. | 378 // TODO(eroman): Add DER for basic constraints and key usage. |
379 errors->Add(kTargetCertInconsistentCaBits); | 379 errors->AddError(kTargetCertInconsistentCaBits); |
380 } | 380 } |
381 | 381 |
382 return success; | 382 return success; |
383 } | 383 } |
384 | 384 |
385 return true; | 385 return true; |
386 } | 386 } |
387 | 387 |
388 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". | 388 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". |
389 // It does processing for the final certificate (the target cert). | 389 // It does processing for the final certificate (the target cert). |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 const TrustAnchor* trust_anchor, | 486 const TrustAnchor* trust_anchor, |
487 const SignaturePolicy* signature_policy, | 487 const SignaturePolicy* signature_policy, |
488 const der::GeneralizedTime& time, | 488 const der::GeneralizedTime& time, |
489 CertErrors* errors) { | 489 CertErrors* errors) { |
490 DCHECK(trust_anchor); | 490 DCHECK(trust_anchor); |
491 DCHECK(signature_policy); | 491 DCHECK(signature_policy); |
492 DCHECK(errors); | 492 DCHECK(errors); |
493 | 493 |
494 // An empty chain is necessarily invalid. | 494 // An empty chain is necessarily invalid. |
495 if (certs.empty()) { | 495 if (certs.empty()) { |
496 errors->Add(kChainIsEmpty); | 496 errors->AddError(kChainIsEmpty); |
497 return false; | 497 return false; |
498 } | 498 } |
499 | 499 |
500 // Will contain a NameConstraints for each previous cert in the chain which | 500 // Will contain a NameConstraints for each previous cert in the chain which |
501 // had nameConstraints. This corresponds to the permitted_subtrees and | 501 // had nameConstraints. This corresponds to the permitted_subtrees and |
502 // excluded_subtrees state variables from RFC 5280. | 502 // excluded_subtrees state variables from RFC 5280. |
503 std::vector<const NameConstraints*> name_constraints_list; | 503 std::vector<const NameConstraints*> name_constraints_list; |
504 | 504 |
505 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: | 505 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: |
506 // * working_public_key | 506 // * working_public_key |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 DEFINE_CERT_ERROR_ID(kVerifySignedDataFailed, "VerifySignedData failed"); | 619 DEFINE_CERT_ERROR_ID(kVerifySignedDataFailed, "VerifySignedData failed"); |
620 DEFINE_CERT_ERROR_ID(kValidityFailedNotAfter, "Time is after notAfter"); | 620 DEFINE_CERT_ERROR_ID(kValidityFailedNotAfter, "Time is after notAfter"); |
621 DEFINE_CERT_ERROR_ID(kValidityFailedNotBefore, "Time is before notBefore"); | 621 DEFINE_CERT_ERROR_ID(kValidityFailedNotBefore, "Time is before notBefore"); |
622 DEFINE_CERT_ERROR_ID(kSignatureAlgorithmsDifferentEncoding, | 622 DEFINE_CERT_ERROR_ID(kSignatureAlgorithmsDifferentEncoding, |
623 "Certificate.signatureAlgorithm is encoded differently " | 623 "Certificate.signatureAlgorithm is encoded differently " |
624 "than TBSCertificate.signature"); | 624 "than TBSCertificate.signature"); |
625 | 625 |
626 } // verify_certificate_chain_errors | 626 } // verify_certificate_chain_errors |
627 | 627 |
628 } // namespace net | 628 } // namespace net |
OLD | NEW |