| 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 |