| 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 "net/cert/internal/name_constraints.h" | 10 #include "net/cert/internal/name_constraints.h" |
| 11 #include "net/cert/internal/parse_certificate.h" | 11 #include "net/cert/internal/parse_certificate.h" |
| 12 #include "net/cert/internal/signature_algorithm.h" | 12 #include "net/cert/internal/signature_algorithm.h" |
| 13 #include "net/cert/internal/signature_policy.h" | 13 #include "net/cert/internal/signature_policy.h" |
| 14 #include "net/cert/internal/verify_name_match.h" | 14 #include "net/cert/internal/verify_name_match.h" |
| 15 #include "net/cert/internal/verify_signed_data.h" | 15 #include "net/cert/internal/verify_signed_data.h" |
| 16 #include "net/der/input.h" | 16 #include "net/der/input.h" |
| 17 #include "net/der/parser.h" | 17 #include "net/der/parser.h" |
| 18 | 18 |
| 19 namespace net { | 19 namespace net { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // Map from OID to ParsedExtension. | 23 // Map from OID to ParsedExtension. |
| 24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; | 24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; |
| 25 | 25 |
| 26 // Describes all parsed properties of a certificate that are relevant for | 26 // Describes all parsed properties of a certificate that are relevant for |
| 27 // certificate verification. | 27 // certificate verification. |
| 28 struct FullyParsedCert { | 28 struct FullyParsedCert { |
| 29 ParsedCertificate cert; | 29 // XXX better naming.. this results in lots of non-obvious cert.cert->foo code |
| 30 ParsedTbsCertificate tbs; | 30 const CertThing* cert; |
| 31 |
| 32 // XXX should some of this be moved into CertThing? |
| 31 | 33 |
| 32 std::unique_ptr<SignatureAlgorithm> signature_algorithm; | 34 std::unique_ptr<SignatureAlgorithm> signature_algorithm; |
| 33 | 35 |
| 34 // Standard extensions that were parsed. | 36 // Standard extensions that were parsed. |
| 35 bool has_basic_constraints = false; | 37 bool has_basic_constraints = false; |
| 36 ParsedBasicConstraints basic_constraints; | 38 ParsedBasicConstraints basic_constraints; |
| 37 | 39 |
| 38 bool has_key_usage = false; | 40 bool has_key_usage = false; |
| 39 der::BitString key_usage; | 41 der::BitString key_usage; |
| 40 | 42 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 } | 74 } |
| 73 return true; | 75 return true; |
| 74 } | 76 } |
| 75 | 77 |
| 76 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, | 78 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, |
| 77 der::Input* value) { | 79 der::Input* value) { |
| 78 der::Parser parser(tlv); | 80 der::Parser parser(tlv); |
| 79 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); | 81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
| 80 } | 82 } |
| 81 | 83 |
| 84 // XXX update doc |
| 82 // Parses an X.509 Certificate fully (including the TBSCertificate and | 85 // Parses an X.509 Certificate fully (including the TBSCertificate and |
| 83 // standard extensions), saving all the properties to |out_|. | 86 // standard extensions), saving all the properties to |out_|. |
| 84 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, | 87 WARN_UNUSED_RESULT bool FullyParseCertificate(const CertThing& cert, |
| 85 FullyParsedCert* out) { | 88 FullyParsedCert* out) { |
| 86 // Parse the outer Certificate. | 89 // XXX move more of this into CertThing? |
| 87 if (!ParseCertificate(cert_tlv, &out->cert)) | 90 |
| 88 return false; | 91 out->cert = &cert; |
| 89 | 92 |
| 90 // Parse the signature algorithm contained in the Certificate (there is | 93 // Parse the signature algorithm contained in the Certificate (there is |
| 91 // another one in the TBSCertificate, which is checked later by | 94 // another one in the TBSCertificate, which is checked later by |
| 92 // VerifySignatureAlgorithmsMatch) | 95 // VerifySignatureAlgorithmsMatch) |
| 93 out->signature_algorithm = | 96 out->signature_algorithm = SignatureAlgorithm::CreateFromDer( |
| 94 SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv); | 97 cert.parsed_cert().signature_algorithm_tlv); |
| 95 if (!out->signature_algorithm) | 98 if (!out->signature_algorithm) |
| 96 return false; | 99 return false; |
| 97 | 100 |
| 98 // Parse the TBSCertificate. | |
| 99 if (!ParseTbsCertificate(out->cert.tbs_certificate_tlv, &out->tbs)) | |
| 100 return false; | |
| 101 | |
| 102 // Reset state relating to extensions (which may not get overwritten). This is | 101 // Reset state relating to extensions (which may not get overwritten). This is |
| 103 // just a precaution, since in practice |out| will already be default | 102 // just a precaution, since in practice |out| will already be default |
| 104 // initialize. | 103 // initialize. |
| 105 out->has_basic_constraints = false; | 104 out->has_basic_constraints = false; |
| 106 out->has_key_usage = false; | 105 out->has_key_usage = false; |
| 107 out->unconsumed_extensions.clear(); | 106 out->unconsumed_extensions.clear(); |
| 108 out->subject_alt_names.reset(); | 107 out->subject_alt_names.reset(); |
| 109 out->has_name_constraints = false; | 108 out->has_name_constraints = false; |
| 110 | 109 |
| 111 // Parse the standard X.509 extensions and remove them from | 110 // Parse the standard X.509 extensions and remove them from |
| 112 // |unconsumed_extensions|. | 111 // |unconsumed_extensions|. |
| 113 if (out->tbs.has_extensions) { | 112 if (cert.parsed_tbs().has_extensions) { |
| 114 // ParseExtensions() ensures there are no duplicates, and maps the (unique) | 113 // ParseExtensions() ensures there are no duplicates, and maps the (unique) |
| 115 // OID to the extension value. | 114 // OID to the extension value. |
| 116 if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions)) | 115 if (!ParseExtensions(cert.parsed_tbs().extensions_tlv, |
| 116 &out->unconsumed_extensions)) |
| 117 return false; | 117 return false; |
| 118 | 118 |
| 119 ParsedExtension extension; | 119 ParsedExtension extension; |
| 120 | 120 |
| 121 // Basic constraints. | 121 // Basic constraints. |
| 122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, | 122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, |
| 123 &extension)) { | 123 &extension)) { |
| 124 out->has_basic_constraints = true; | 124 out->has_basic_constraints = true; |
| 125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) | 125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) |
| 126 return false; | 126 return false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value); | 142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value); |
| 143 if (!out->subject_alt_names) | 143 if (!out->subject_alt_names) |
| 144 return false; | 144 return false; |
| 145 // RFC 5280 section 4.1.2.6: | 145 // RFC 5280 section 4.1.2.6: |
| 146 // If subject naming information is present only in the subjectAltName | 146 // If subject naming information is present only in the subjectAltName |
| 147 // extension (e.g., a key bound only to an email address or URI), then the | 147 // extension (e.g., a key bound only to an email address or URI), then the |
| 148 // subject name MUST be an empty sequence and the subjectAltName extension | 148 // subject name MUST be an empty sequence and the subjectAltName extension |
| 149 // MUST be critical. | 149 // MUST be critical. |
| 150 if (!extension.critical) { | 150 if (!extension.critical) { |
| 151 der::Input subject_value; | 151 der::Input subject_value; |
| 152 if (!GetSequenceValue(out->tbs.subject_tlv, &subject_value)) | 152 if (!GetSequenceValue(cert.parsed_tbs().subject_tlv, &subject_value)) |
| 153 return false; | 153 return false; |
| 154 if (subject_value.Length() == 0) | 154 if (subject_value.Length() == 0) |
| 155 return false; | 155 return false; |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 // Name constraints. | 159 // Name constraints. |
| 160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, | 160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, |
| 161 &out->name_constraints_extension)) { | 161 &out->name_constraints_extension)) { |
| 162 out->has_name_constraints = true; | 162 out->has_name_constraints = true; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 188 // | 188 // |
| 189 // A certificate is self-issued if the same DN appears in the subject | 189 // A certificate is self-issued if the same DN appears in the subject |
| 190 // and issuer fields (the two DNs are the same if they match according | 190 // and issuer fields (the two DNs are the same if they match according |
| 191 // to the rules specified in Section 7.1). In general, the issuer and | 191 // to the rules specified in Section 7.1). In general, the issuer and |
| 192 // subject of the certificates that make up a path are different for | 192 // subject of the certificates that make up a path are different for |
| 193 // each certificate. However, a CA may issue a certificate to itself to | 193 // each certificate. However, a CA may issue a certificate to itself to |
| 194 // support key rollover or changes in certificate policies. These | 194 // support key rollover or changes in certificate policies. These |
| 195 // self-issued certificates are not counted when evaluating path length | 195 // self-issued certificates are not counted when evaluating path length |
| 196 // or name constraints. | 196 // or name constraints. |
| 197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { | 197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { |
| 198 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); | 198 return cert.cert->normalized_subject() == cert.cert->normalized_issuer(); |
| 199 } | 199 } |
| 200 | 200 |
| 201 // Returns true if |cert| is valid at time |time|. | 201 // Returns true if |cert| is valid at time |time|. |
| 202 // | 202 // |
| 203 // The certificate's validity requirements are described by RFC 5280 section | 203 // The certificate's validity requirements are described by RFC 5280 section |
| 204 // 4.1.2.5: | 204 // 4.1.2.5: |
| 205 // | 205 // |
| 206 // The validity period for a certificate is the period of time from | 206 // The validity period for a certificate is the period of time from |
| 207 // notBefore through notAfter, inclusive. | 207 // notBefore through notAfter, inclusive. |
| 208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, | 208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, |
| 209 const der::GeneralizedTime time) { | 209 const der::GeneralizedTime time) { |
| 210 return !(time < cert.tbs.validity_not_before) && | 210 return !(time < cert.cert->parsed_tbs().validity_not_before) && |
| 211 !(cert.tbs.validity_not_after < time); | 211 !(cert.cert->parsed_tbs().validity_not_after < time); |
| 212 } | 212 } |
| 213 | 213 |
| 214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for | 214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for |
| 215 // RSA with SHA1. | 215 // RSA with SHA1. |
| 216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( | 216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( |
| 217 const der::Input& signature_algorithm_tlv) { | 217 const der::Input& signature_algorithm_tlv) { |
| 218 std::unique_ptr<SignatureAlgorithm> algorithm = | 218 std::unique_ptr<SignatureAlgorithm> algorithm = |
| 219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); | 219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); |
| 220 | 220 |
| 221 return algorithm && | 221 return algorithm && |
| (...skipping 15 matching lines...) Expand all Loading... |
| 237 // | 237 // |
| 238 // The spec is not explicit about what "the same algorithm identifier" means. | 238 // The spec is not explicit about what "the same algorithm identifier" means. |
| 239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte | 239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte |
| 240 // identical. | 240 // identical. |
| 241 // | 241 // |
| 242 // In practice however there are certificates which use different encodings for | 242 // In practice however there are certificates which use different encodings for |
| 243 // specifying RSA with SHA1 (different OIDs). This is special-cased for | 243 // specifying RSA with SHA1 (different OIDs). This is special-cased for |
| 244 // compatibility sake. | 244 // compatibility sake. |
| 245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( | 245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( |
| 246 const FullyParsedCert& cert) { | 246 const FullyParsedCert& cert) { |
| 247 const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv; | 247 const der::Input& alg1_tlv = cert.cert->parsed_cert().signature_algorithm_tlv; |
| 248 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; | 248 const der::Input& alg2_tlv = cert.cert->parsed_tbs().signature_algorithm_tlv; |
| 249 | 249 |
| 250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
| 251 // equal, but make a compatibility concession for RSA with SHA1. | 251 // equal, but make a compatibility concession for RSA with SHA1. |
| 252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
| 253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); | 253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); |
| 254 } | 254 } |
| 255 | 255 |
| 256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
| 257 // Processing" procedure. | 257 // Processing" procedure. |
| 258 // | 258 // |
| 259 // |skip_issuer_checks| controls whether the function will skip: | 259 // |skip_issuer_checks| controls whether the function will skip: |
| 260 // - Checking that |cert|'s signature using |working_spki| | 260 // - Checking that |cert|'s signature using |working_spki| |
| 261 // - Checkinging that |cert|'s issuer matches |working_issuer_name| | 261 // - Checkinging that |cert|'s issuer matches |working_normalized_issuer_name| |
| 262 // This should be set to true only when verifying a trusted root certificate. | 262 // This should be set to true only when verifying a trusted root certificate. |
| 263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( | 263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( |
| 264 const FullyParsedCert& cert, | 264 const FullyParsedCert& cert, |
| 265 bool is_target_cert, | 265 bool is_target_cert, |
| 266 bool skip_issuer_checks, | 266 bool skip_issuer_checks, |
| 267 const SignaturePolicy* signature_policy, | 267 const SignaturePolicy* signature_policy, |
| 268 const der::GeneralizedTime& time, | 268 const der::GeneralizedTime& time, |
| 269 const der::Input& working_spki, | 269 const der::Input& working_spki, |
| 270 const der::Input& working_issuer_name, | 270 const der::Input& working_normalized_issuer_name, |
| 271 const std::vector<std::unique_ptr<NameConstraints>>& | 271 const std::vector<std::unique_ptr<NameConstraints>>& |
| 272 name_constraints_list) { | 272 name_constraints_list) { |
| 273 // Check that the signature algorithms in Certificate vs TBSCertificate | 273 // Check that the signature algorithms in Certificate vs TBSCertificate |
| 274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by | 274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by |
| 275 // sections 4.1.1.2 and 4.1.2.3. | 275 // sections 4.1.1.2 and 4.1.2.3. |
| 276 if (!VerifySignatureAlgorithmsMatch(cert)) | 276 if (!VerifySignatureAlgorithmsMatch(cert)) |
| 277 return false; | 277 return false; |
| 278 | 278 |
| 279 // Verify the digital signature using the previous certificate's key (RFC | 279 // Verify the digital signature using the previous certificate's key (RFC |
| 280 // 5280 section 6.1.3 step a.1). | 280 // 5280 section 6.1.3 step a.1). |
| 281 if (!skip_issuer_checks) { | 281 if (!skip_issuer_checks) { |
| 282 if (!VerifySignedData( | 282 if (!VerifySignedData(*cert.signature_algorithm, |
| 283 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, | 283 cert.cert->parsed_cert().tbs_certificate_tlv, |
| 284 cert.cert.signature_value, working_spki, signature_policy)) { | 284 cert.cert->parsed_cert().signature_value, |
| 285 working_spki, signature_policy)) { |
| 285 return false; | 286 return false; |
| 286 } | 287 } |
| 287 } | 288 } |
| 288 | 289 |
| 289 // Check the time range for the certificate's validity, ensuring it is valid | 290 // Check the time range for the certificate's validity, ensuring it is valid |
| 290 // at |time|. | 291 // at |time|. |
| 291 // (RFC 5280 section 6.1.3 step a.2) | 292 // (RFC 5280 section 6.1.3 step a.2) |
| 292 if (!VerifyTimeValidity(cert, time)) | 293 if (!VerifyTimeValidity(cert, time)) |
| 293 return false; | 294 return false; |
| 294 | 295 |
| 295 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) | 296 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) |
| 296 | 297 |
| 297 // Verify the certificate's issuer name matches the issuing certificate's | 298 // Verify the certificate's issuer name matches the issuing certificate's |
| 298 // subject name. (RFC 5280 section 6.1.3 step a.4) | 299 // subject name. (RFC 5280 section 6.1.3 step a.4) |
| 299 if (!skip_issuer_checks) { | 300 if (!skip_issuer_checks) { |
| 300 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) | 301 if (der::Input(&cert.cert->normalized_issuer()) != |
| 302 working_normalized_issuer_name) |
| 301 return false; | 303 return false; |
| 302 } | 304 } |
| 303 | 305 |
| 304 // Name constraints (RFC 5280 section 6.1.3 step b & c) | 306 // Name constraints (RFC 5280 section 6.1.3 step b & c) |
| 305 // If certificate i is self-issued and it is not the final certificate in the | 307 // If certificate i is self-issued and it is not the final certificate in the |
| 306 // path, skip this step for certificate i. | 308 // path, skip this step for certificate i. |
| 307 if (!name_constraints_list.empty() && | 309 if (!name_constraints_list.empty() && |
| 308 (!IsSelfIssued(cert) || is_target_cert)) { | 310 (!IsSelfIssued(cert) || is_target_cert)) { |
| 311 // XXX used normalized_subject here |
| 309 der::Input subject_value; | 312 der::Input subject_value; |
| 310 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) | 313 if (!GetSequenceValue(cert.cert->parsed_tbs().subject_tlv, &subject_value)) |
| 311 return false; | 314 return false; |
| 312 for (const auto& nc : name_constraints_list) { | 315 for (const auto& nc : name_constraints_list) { |
| 313 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get())) | 316 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get())) |
| 314 return false; | 317 return false; |
| 315 } | 318 } |
| 316 } | 319 } |
| 317 | 320 |
| 318 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet | 321 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet |
| 319 // implemented. | 322 // implemented. |
| 320 | 323 |
| 321 return true; | 324 return true; |
| 322 } | 325 } |
| 323 | 326 |
| 324 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for | 327 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for |
| 325 // Certificate i+1" procedure. |cert| is expected to be an intermediary. | 328 // Certificate i+1" procedure. |cert| is expected to be an intermediary. |
| 326 WARN_UNUSED_RESULT bool PrepareForNextCertificate( | 329 WARN_UNUSED_RESULT bool PrepareForNextCertificate( |
| 327 const FullyParsedCert& cert, | 330 const FullyParsedCert& cert, |
| 328 size_t* max_path_length_ptr, | 331 size_t* max_path_length_ptr, |
| 329 der::Input* working_spki, | 332 der::Input* working_spki, |
| 330 der::Input* working_issuer_name, | 333 der::Input* working_normalized_issuer_name, |
| 331 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { | 334 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { |
| 332 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet | 335 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet |
| 333 // implemented. | 336 // implemented. |
| 334 | 337 |
| 335 // From RFC 5280 section 6.1.4 step c: | 338 // From RFC 5280 section 6.1.4 step c: |
| 336 // | 339 // |
| 337 // Assign the certificate subject name to working_issuer_name. | 340 // Assign the certificate subject name to working_normalized_issuer_name. |
| 338 *working_issuer_name = cert.tbs.subject_tlv; | 341 *working_normalized_issuer_name = |
| 342 der::Input(&cert.cert->normalized_subject()); |
| 339 | 343 |
| 340 // From RFC 5280 section 6.1.4 step d: | 344 // From RFC 5280 section 6.1.4 step d: |
| 341 // | 345 // |
| 342 // Assign the certificate subjectPublicKey to working_public_key. | 346 // Assign the certificate subjectPublicKey to working_public_key. |
| 343 *working_spki = cert.tbs.spki_tlv; | 347 *working_spki = cert.cert->parsed_tbs().spki_tlv; |
| 344 | 348 |
| 345 // Note that steps e and f are omitted as they are handled by | 349 // Note that steps e and f are omitted as they are handled by |
| 346 // the assignment to |working_spki| above. See the definition | 350 // the assignment to |working_spki| above. See the definition |
| 347 // of |working_spki|. | 351 // of |working_spki|. |
| 348 | 352 |
| 349 // From RFC 5280 section 6.1.4 step g: | 353 // From RFC 5280 section 6.1.4 step g: |
| 350 if (cert.has_name_constraints) { | 354 if (cert.has_name_constraints) { |
| 351 std::unique_ptr<NameConstraints> name_constraints( | 355 std::unique_ptr<NameConstraints> name_constraints( |
| 352 NameConstraints::CreateFromDer( | 356 NameConstraints::CreateFromDer( |
| 353 cert.name_constraints_extension.value, | 357 cert.name_constraints_extension.value, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", | 491 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", |
| 488 // however is implied by RFC 5280 section 4.2.1.9. | 492 // however is implied by RFC 5280 section 4.2.1.9. |
| 489 if (!VerifyTargetCertHasConsistentCaBits(cert)) | 493 if (!VerifyTargetCertHasConsistentCaBits(cert)) |
| 490 return false; | 494 return false; |
| 491 | 495 |
| 492 return true; | 496 return true; |
| 493 } | 497 } |
| 494 | 498 |
| 495 } // namespace | 499 } // namespace |
| 496 | 500 |
| 497 TrustAnchor::TrustAnchor() {} | 501 CertThing::CertThing() {} |
| 498 TrustAnchor::~TrustAnchor() {} | 502 CertThing::~CertThing() {} |
| 499 | 503 |
| 500 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData( | 504 std::unique_ptr<CertThing> CertThing::CreateFromCertificateData( |
| 501 const uint8_t* data, | 505 const uint8_t* data, |
| 502 size_t length, | 506 size_t length, |
| 503 DataSource source) { | 507 DataSource source) { |
| 504 std::unique_ptr<TrustAnchor> result(new TrustAnchor); | 508 std::unique_ptr<CertThing> result(new CertThing); |
| 505 | 509 |
| 506 switch (source) { | 510 switch (source) { |
| 507 case DataSource::INTERNAL_COPY: | 511 case DataSource::INTERNAL_COPY: |
| 508 result->cert_data_.assign(data, data + length); | 512 result->cert_data_.assign(data, data + length); |
| 509 result->cert_ = | 513 result->cert_ = |
| 510 der::Input(result->cert_data_.data(), result->cert_data_.size()); | 514 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
| 511 break; | 515 break; |
| 512 case DataSource::EXTERNAL_REFERENCE: | 516 case DataSource::EXTERNAL_REFERENCE: |
| 513 result->cert_ = der::Input(data, length); | 517 result->cert_ = der::Input(data, length); |
| 514 break; | 518 break; |
| 515 } | 519 } |
| 516 | 520 |
| 517 // Parse the certificate to get its name. | 521 // Parse the certificate to get its name. |
| 518 ParsedCertificate cert; | 522 if (!ParseCertificate(result->cert_, &result->parsed_cert_)) |
| 519 if (!ParseCertificate(result->cert(), &cert)) | |
| 520 return nullptr; | 523 return nullptr; |
| 521 | 524 |
| 522 ParsedTbsCertificate tbs; | 525 if (!ParseTbsCertificate(result->parsed_cert_.tbs_certificate_tlv, |
| 523 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) | 526 &result->parsed_tbs_)) |
| 524 return nullptr; | 527 return nullptr; |
| 525 | 528 |
| 526 result->name_ = tbs.subject_tlv; | 529 der::Input subject_value; |
| 527 | 530 if (!GetSequenceValue(result->parsed_tbs_.subject_tlv, &subject_value) || |
| 528 // TODO(eroman): If adding a self-signed certificate, check that its | 531 !NormalizeName(subject_value, &result->normalized_subject_)) |
| 529 // signature is correct? This check will not otherwise be done during | 532 return nullptr; |
| 530 // verification. | 533 der::Input issuer_value; |
| 534 if (!GetSequenceValue(result->parsed_tbs_.issuer_tlv, &issuer_value) || |
| 535 !NormalizeName(issuer_value, &result->normalized_issuer_)) |
| 536 return nullptr; |
| 531 | 537 |
| 532 return result; | 538 return result; |
| 533 } | 539 } |
| 534 | 540 |
| 535 bool TrustAnchor::MatchesName(const der::Input& name) const { | 541 std::unique_ptr<CertThing> CertThing::CreateFromCertificateCopy( |
| 536 return NameMatches(name, name_); | 542 const base::StringPiece& data) { |
| 543 return CertThing::CreateFromCertificateData( |
| 544 reinterpret_cast<const uint8_t*>(data.data()), data.size(), |
| 545 DataSource::INTERNAL_COPY); |
| 546 } |
| 547 |
| 548 std::unique_ptr<CertThing> CertThing::Clone() const { |
| 549 // XXX Should it always INTERNAL_COPY, or should it continue with what the |
| 550 // previous had?.. lifetimes could get weird with that. (Eg, someone created a |
| 551 // Cert, passed it to a function they could gaurantee it would outlive, but |
| 552 // that function internall makes a clone and returns it as part of the results |
| 553 // or error info..) |
| 554 /*std::unique_ptr<CertThing> |
| 555 result(CreateFromCertificateData(cert_.UnsafeData(), cert_.Length(), |
| 556 CertThing::DataSource::INTERNAL_COPY)); |
| 557 // If it parsed to make this object, it should never fail to parse again. |
| 558 CHECK(result); |
| 559 return result;*/ |
| 560 |
| 561 std::unique_ptr<CertThing> result(new CertThing); |
| 562 |
| 563 result->cert_data_.assign( |
| 564 reinterpret_cast<const char*>(cert_.UnsafeData()), |
| 565 reinterpret_cast<const char*>(cert_.UnsafeData()) + cert_.Length()); |
| 566 result->cert_ = |
| 567 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
| 568 |
| 569 result->parsed_cert_ = ParsedCertificate(parsed_cert_, cert_, result->cert_); |
| 570 result->parsed_tbs_ = ParsedTbsCertificate(parsed_tbs_, cert_, result->cert_); |
| 571 |
| 572 result->normalized_subject_ = normalized_subject_; |
| 573 result->normalized_issuer_ = normalized_issuer_; |
| 574 |
| 575 // XXX clean up |
| 576 /*result->parsed_cert_.tbs_certificate_tlv = der::Input( |
| 577 result->cert_.UnsafeData() + |
| 578 (parsed_cert_.tbs_certificate_tlv.UnsafeData() - cert_.UnsafeData()), |
| 579 parsed_cert_.tbs_certificate_tlv.Length());*/ |
| 580 |
| 581 return result; |
| 582 } |
| 583 |
| 584 bool CertThing::MatchesName(const der::Input& name) const { |
| 585 return NameMatches(name, parsed_tbs_.subject_tlv); // XXX don't re-normalize |
| 537 } | 586 } |
| 538 | 587 |
| 539 TrustStore::TrustStore() {} | 588 TrustStore::TrustStore() {} |
| 540 TrustStore::~TrustStore() {} | 589 TrustStore::~TrustStore() {} |
| 541 | 590 |
| 542 void TrustStore::Clear() { | 591 void TrustStore::Clear() { |
| 543 anchors_.clear(); | 592 anchors_.clear(); |
| 544 } | 593 } |
| 545 | 594 |
| 546 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { | 595 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { |
| 596 // TODO(eroman): If adding a self-signed certificate, check that its |
| 597 // signature is correct? This check will not otherwise be done during |
| 598 // verification. |
| 547 return AddTrustedCertificate(data, length, | 599 return AddTrustedCertificate(data, length, |
| 548 TrustAnchor::DataSource::INTERNAL_COPY); | 600 CertThing::DataSource::INTERNAL_COPY); |
| 549 } | 601 } |
| 550 | 602 |
| 551 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { | 603 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { |
| 552 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), | 604 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), |
| 553 data.size()); | 605 data.size()); |
| 554 } | 606 } |
| 555 | 607 |
| 556 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, | 608 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, |
| 557 size_t length) { | 609 size_t length) { |
| 558 return AddTrustedCertificate(data, length, | 610 return AddTrustedCertificate(data, length, |
| 559 TrustAnchor::DataSource::EXTERNAL_REFERENCE); | 611 CertThing::DataSource::EXTERNAL_REFERENCE); |
| 560 } | 612 } |
| 561 | 613 |
| 562 const TrustAnchor* TrustStore::FindTrustAnchorByName( | 614 const CertThing* TrustStore::FindTrustAnchorByName( |
| 563 const der::Input& name) const { | 615 const der::Input& name) const { |
| 564 for (const auto& anchor : anchors_) { | 616 for (const auto& anchor : anchors_) { |
| 565 if (anchor->MatchesName(name)) { | 617 if (anchor->MatchesName(name)) { |
| 566 return anchor.get(); | 618 return anchor.get(); |
| 567 } | 619 } |
| 568 } | 620 } |
| 569 return nullptr; | 621 return nullptr; |
| 570 } | 622 } |
| 571 | 623 |
| 624 std::vector<const CertThing*> TrustStore::FindTrustAnchorsByNormalizedName( |
| 625 const std::string& normalized_name) const { |
| 626 std::vector<const CertThing*> result; |
| 627 for (const auto& anchor : anchors_) { |
| 628 if (anchor->normalized_subject() == normalized_name) { |
| 629 result.push_back(anchor.get()); |
| 630 } |
| 631 } |
| 632 return result; |
| 633 } |
| 634 |
| 572 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { | 635 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { |
| 573 for (const auto& anchor : anchors_) { | 636 for (const auto& anchor : anchors_) { |
| 574 if (anchor->cert() == cert_der) | 637 if (anchor->der_cert() == cert_der) |
| 575 return true; | 638 return true; |
| 576 } | 639 } |
| 577 return false; | 640 return false; |
| 578 } | 641 } |
| 579 | 642 |
| 580 bool TrustStore::AddTrustedCertificate(const uint8_t* data, | 643 bool TrustStore::AddTrustedCertificate(const uint8_t* data, |
| 581 size_t length, | 644 size_t length, |
| 582 TrustAnchor::DataSource source) { | 645 CertThing::DataSource source) { |
| 583 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source); | 646 auto anchor = CertThing::CreateFromCertificateData(data, length, source); |
| 584 if (!anchor) | 647 if (!anchor) |
| 585 return false; | 648 return false; |
| 586 anchors_.push_back(std::move(anchor)); | 649 anchors_.push_back(std::move(anchor)); |
| 587 return true; | 650 return true; |
| 588 } | 651 } |
| 589 | 652 |
| 590 // TODO(eroman): Move this into existing anonymous namespace. | |
| 591 namespace { | |
| 592 | |
| 593 // This implementation is structured to mimic the description of certificate | 653 // This implementation is structured to mimic the description of certificate |
| 594 // path verification given by RFC 5280 section 6.1. | 654 // path verification given by RFC 5280 section 6.1. |
| 595 // | 655 // |
| 596 // Unlike RFC 5280, the trust anchor is specified as the root certificate in | 656 // Unlike RFC 5280, the trust anchor is specified as the root certificate in |
| 597 // the chain. This root certificate is assumed to be trusted, and neither its | 657 // the chain. This root certificate is assumed to be trusted, and neither its |
| 598 // signature nor issuer name are verified. (It needn't be self-signed). | 658 // signature nor issuer name are verified. (It needn't be self-signed). |
| 599 bool VerifyCertificateChainAssumingTrustedRoot( | 659 bool VerifyCertificateChainAssumingTrustedRoot( |
| 600 const std::vector<der::Input>& certs_der, | 660 const std::vector<std::unique_ptr<CertThing>>& certs, |
| 601 // The trust store is only used for assertions. | 661 // The trust store is only used for assertions. |
| 602 const TrustStore& trust_store, | 662 const TrustStore& trust_store, |
| 603 const SignaturePolicy* signature_policy, | 663 const SignaturePolicy* signature_policy, |
| 604 const der::GeneralizedTime& time) { | 664 const der::GeneralizedTime& time) { |
| 605 // An empty chain is necessarily invalid. | 665 // An empty chain is necessarily invalid. |
| 606 if (certs_der.empty()) | 666 if (certs.empty()) |
| 607 return false; | 667 return false; |
| 608 | 668 |
| 609 // IMPORTANT: the assumption being made is that the root certificate in | 669 // IMPORTANT: the assumption being made is that the root certificate in |
| 610 // the given path is the trust anchor (and has already been verified as | 670 // the given path is the trust anchor (and has already been verified as |
| 611 // such). | 671 // such). |
| 612 DCHECK(trust_store.IsTrustedCertificate(certs_der.back())); | 672 DCHECK(trust_store.IsTrustedCertificate(certs.back()->der_cert())); // XXX |
| 613 | 673 |
| 614 // Will contain a NameConstraints for each previous cert in the chain which | 674 // Will contain a NameConstraints for each previous cert in the chain which |
| 615 // had nameConstraints. This corresponds to the permitted_subtrees and | 675 // had nameConstraints. This corresponds to the permitted_subtrees and |
| 616 // excluded_subtrees state variables from RFC 5280. | 676 // excluded_subtrees state variables from RFC 5280. |
| 617 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; | 677 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; |
| 618 | 678 |
| 619 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: | 679 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: |
| 620 // * working_public_key | 680 // * working_public_key |
| 621 // * working_public_key_algorithm | 681 // * working_public_key_algorithm |
| 622 // * working_public_key_parameters | 682 // * working_public_key_parameters |
| 623 // | 683 // |
| 624 // They are combined for simplicity since the signature verification takes an | 684 // They are combined for simplicity since the signature verification takes an |
| 625 // SPKI, and the parameter inheritence is not applicable for the supported | 685 // SPKI, and the parameter inheritence is not applicable for the supported |
| 626 // key types. | 686 // key types. |
| 627 // | 687 // |
| 628 // An approximate explanation of |working_spki| is this description from RFC | 688 // An approximate explanation of |working_spki| is this description from RFC |
| 629 // 5280 section 6.1.2: | 689 // 5280 section 6.1.2: |
| 630 // | 690 // |
| 631 // working_public_key: the public key used to verify the | 691 // working_public_key: the public key used to verify the |
| 632 // signature of a certificate. | 692 // signature of a certificate. |
| 633 der::Input working_spki; | 693 der::Input working_spki; |
| 634 | 694 |
| 635 // |working_issuer_name| corresponds with the same named variable in RFC 5280 | 695 // |working_normalized_issuer_name| is the normalized value of the |
| 636 // section 6.1.2: | 696 // working_issuer_name variable in RFC 5280 section 6.1.2: |
| 637 // | 697 // |
| 638 // working_issuer_name: the issuer distinguished name expected | 698 // working_issuer_name: the issuer distinguished name expected |
| 639 // in the next certificate in the chain. | 699 // in the next certificate in the chain. |
| 640 der::Input working_issuer_name; | 700 der::Input working_normalized_issuer_name; |
| 641 | 701 |
| 642 // |max_path_length| corresponds with the same named variable in RFC 5280 | 702 // |max_path_length| corresponds with the same named variable in RFC 5280 |
| 643 // section 6.1.2: | 703 // section 6.1.2: |
| 644 // | 704 // |
| 645 // max_path_length: this integer is initialized to n, is | 705 // max_path_length: this integer is initialized to n, is |
| 646 // decremented for each non-self-issued certificate in the path, | 706 // decremented for each non-self-issued certificate in the path, |
| 647 // and may be reduced to the value in the path length constraint | 707 // and may be reduced to the value in the path length constraint |
| 648 // field within the basic constraints extension of a CA | 708 // field within the basic constraints extension of a CA |
| 649 // certificate. | 709 // certificate. |
| 650 size_t max_path_length = certs_der.size(); | 710 size_t max_path_length = certs.size(); |
| 651 | 711 |
| 652 // Iterate over all the certificates in the reverse direction: starting from | 712 // Iterate over all the certificates in the reverse direction: starting from |
| 653 // the trust anchor and progressing towards the target certificate. | 713 // the trust anchor and progressing towards the target certificate. |
| 654 // | 714 // |
| 655 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. | 715 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. |
| 656 // | 716 // |
| 657 // * i=0 : Trust anchor. | 717 // * i=0 : Trust anchor. |
| 658 // * i=N-1 : Target certificate. | 718 // * i=N-1 : Target certificate. |
| 659 for (size_t i = 0; i < certs_der.size(); ++i) { | 719 for (size_t i = 0; i < certs.size(); ++i) { |
| 660 const size_t index_into_certs_der = certs_der.size() - i - 1; | 720 const size_t index_into_certs = certs.size() - i - 1; |
| 661 | 721 |
| 662 // |is_target_cert| is true if the current certificate is the target | 722 // |is_target_cert| is true if the current certificate is the target |
| 663 // certificate being verified. The target certificate isn't necessarily an | 723 // certificate being verified. The target certificate isn't necessarily an |
| 664 // end-entity certificate. | 724 // end-entity certificate. |
| 665 const bool is_target_cert = index_into_certs_der == 0; | 725 const bool is_target_cert = index_into_certs == 0; |
| 666 | 726 |
| 667 // |is_trust_anchor| is true if the current certificate is the trust | 727 // |is_trust_anchor| is true if the current certificate is the trust |
| 668 // anchor. This certificate is implicitly trusted. | 728 // anchor. This certificate is implicitly trusted. |
| 669 const bool is_trust_anchor = i == 0; | 729 const bool is_trust_anchor = i == 0; |
| 670 | 730 |
| 671 // Parse the current certificate into |cert|. | 731 // Parse the current certificate into |cert|. |
| 672 FullyParsedCert cert; | 732 FullyParsedCert cert; |
| 673 const der::Input& cert_der = certs_der[index_into_certs_der]; | 733 const CertThing& cert_thing = *certs[index_into_certs]; |
| 674 if (!FullyParseCertificate(cert_der, &cert)) | 734 if (!FullyParseCertificate(cert_thing, &cert)) |
| 675 return false; | 735 return false; |
| 676 | 736 |
| 677 // Per RFC 5280 section 6.1: | 737 // Per RFC 5280 section 6.1: |
| 678 // * Do basic processing for each certificate | 738 // * Do basic processing for each certificate |
| 679 // * If it is the last certificate in the path (target certificate) | 739 // * If it is the last certificate in the path (target certificate) |
| 680 // - Then run "Wrap up" | 740 // - Then run "Wrap up" |
| 681 // - Otherwise run "Prepare for Next cert" | 741 // - Otherwise run "Prepare for Next cert" |
| 682 if (!BasicCertificateProcessing( | 742 if (!BasicCertificateProcessing(cert, is_target_cert, is_trust_anchor, |
| 683 cert, is_target_cert, is_trust_anchor, signature_policy, time, | 743 signature_policy, time, working_spki, |
| 684 working_spki, working_issuer_name, name_constraints_list)) { | 744 working_normalized_issuer_name, |
| 745 name_constraints_list)) { |
| 685 return false; | 746 return false; |
| 686 } | 747 } |
| 687 if (!is_target_cert) { | 748 if (!is_target_cert) { |
| 688 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, | 749 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, |
| 689 &working_issuer_name, | 750 &working_normalized_issuer_name, |
| 690 &name_constraints_list)) { | 751 &name_constraints_list)) { |
| 691 return false; | 752 return false; |
| 692 } | 753 } |
| 693 } else { | 754 } else { |
| 694 if (!WrapUp(cert)) | 755 if (!WrapUp(cert)) |
| 695 return false; | 756 return false; |
| 696 } | 757 } |
| 697 } | 758 } |
| 698 | 759 |
| 699 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 760 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
| 700 // | 761 // |
| 701 // A certificate MUST NOT appear more than once in a prospective | 762 // A certificate MUST NOT appear more than once in a prospective |
| 702 // certification path. | 763 // certification path. |
| 703 | 764 |
| 704 return true; | 765 return true; |
| 705 } | 766 } |
| 706 | 767 |
| 768 // TODO(eroman): Move this into existing anonymous namespace. |
| 769 namespace { |
| 770 |
| 707 // TODO(eroman): This function is a temporary hack in the absence of full | 771 // TODO(eroman): This function is a temporary hack in the absence of full |
| 708 // path building. It may insert 1 certificate at the root of the | 772 // path building. It may insert 1 certificate at the root of the |
| 709 // chain to ensure that the path's root certificate is a trust anchor. | 773 // chain to ensure that the path's root certificate is a trust anchor. |
| 710 // | 774 // |
| 711 // Beyond this no other verification is done on the chain. The caller is | 775 // Beyond this no other verification is done on the chain. The caller is |
| 712 // responsible for verifying the subsequent chain's correctness. | 776 // responsible for verifying the subsequent chain's correctness. |
| 713 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( | 777 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( |
| 714 const std::vector<der::Input>& certs_der, | 778 const std::vector<der::Input>& certs_der, |
| 715 const TrustStore& trust_store, | 779 const TrustStore& trust_store, |
| 716 std::vector<der::Input>* certs_der_trusted_root) { | 780 std::vector<der::Input>* certs_der_trusted_root) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 731 ParsedCertificate cert; | 795 ParsedCertificate cert; |
| 732 ParsedTbsCertificate tbs; | 796 ParsedTbsCertificate tbs; |
| 733 if (!ParseCertificate(certs_der.back(), &cert) || | 797 if (!ParseCertificate(certs_der.back(), &cert) || |
| 734 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { | 798 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { |
| 735 return false; | 799 return false; |
| 736 } | 800 } |
| 737 | 801 |
| 738 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); | 802 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); |
| 739 if (!trust_anchor) | 803 if (!trust_anchor) |
| 740 return false; | 804 return false; |
| 741 certs_der_trusted_root->push_back(trust_anchor->cert()); | 805 certs_der_trusted_root->push_back(trust_anchor->der_cert()); |
| 742 return true; | 806 return true; |
| 743 } | 807 } |
| 744 | 808 |
| 745 } // namespace | 809 } // namespace |
| 746 | 810 |
| 747 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, | 811 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, |
| 748 const TrustStore& trust_store, | 812 const TrustStore& trust_store, |
| 749 const SignaturePolicy* signature_policy, | 813 const SignaturePolicy* signature_policy, |
| 750 const der::GeneralizedTime& time) { | 814 const der::GeneralizedTime& time) { |
| 751 // Modify the certificate chain so that its root is a trusted certificate. | 815 // Modify the certificate chain so that its root is a trusted certificate. |
| 752 std::vector<der::Input> certs_der_trusted_root; | 816 std::vector<der::Input> certs_der_trusted_root; |
| 753 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, | 817 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, |
| 754 &certs_der_trusted_root)) { | 818 &certs_der_trusted_root)) { |
| 755 return false; | 819 return false; |
| 756 } | 820 } |
| 757 | 821 |
| 822 std::vector<std::unique_ptr<CertThing>> certs_trusted_root; |
| 823 for (const auto& cert_der : certs_der_trusted_root) { |
| 824 std::unique_ptr<CertThing> cert(CertThing::CreateFromCertificateData( |
| 825 cert_der.UnsafeData(), cert_der.Length(), |
| 826 CertThing::DataSource::EXTERNAL_REFERENCE)); |
| 827 if (!cert) |
| 828 return false; |
| 829 certs_trusted_root.push_back(std::move(cert)); |
| 830 } |
| 831 |
| 758 // Verify the chain. | 832 // Verify the chain. |
| 759 return VerifyCertificateChainAssumingTrustedRoot( | 833 return VerifyCertificateChainAssumingTrustedRoot( |
| 760 certs_der_trusted_root, trust_store, signature_policy, time); | 834 certs_trusted_root, trust_store, signature_policy, time); |
| 761 } | 835 } |
| 762 | 836 |
| 763 } // namespace net | 837 } // namespace net |
| OLD | NEW |