| 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" | |
| 11 #include "net/cert/internal/parse_certificate.h" | 10 #include "net/cert/internal/parse_certificate.h" |
| 12 #include "net/cert/internal/signature_algorithm.h" | 11 #include "net/cert/internal/signature_algorithm.h" |
| 13 #include "net/cert/internal/signature_policy.h" | 12 #include "net/cert/internal/signature_policy.h" |
| 14 #include "net/cert/internal/verify_name_match.h" | 13 #include "net/cert/internal/verify_name_match.h" |
| 15 #include "net/cert/internal/verify_signed_data.h" | 14 #include "net/cert/internal/verify_signed_data.h" |
| 16 #include "net/der/input.h" | 15 #include "net/der/input.h" |
| 17 #include "net/der/parser.h" | 16 #include "net/der/parser.h" |
| 18 | 17 |
| 19 namespace net { | 18 namespace net { |
| 20 | 19 |
| 21 namespace { | 20 namespace { |
| 22 | 21 |
| 23 // Map from OID to ParsedExtension. | |
| 24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; | |
| 25 | |
| 26 // Describes all parsed properties of a certificate that are relevant for | 22 // Describes all parsed properties of a certificate that are relevant for |
| 27 // certificate verification. | 23 // certificate verification. |
| 28 struct FullyParsedCert { | 24 struct FullyParsedCert { |
| 29 ParsedCertificate cert; | 25 // XXX better naming.. this results in lots of non-obvious cert.cert->foo code |
| 30 ParsedTbsCertificate tbs; | 26 scoped_refptr<CertThing> cert; |
| 27 |
| 28 // XXX should some of this be moved into CertThing? |
| 31 | 29 |
| 32 std::unique_ptr<SignatureAlgorithm> signature_algorithm; | 30 std::unique_ptr<SignatureAlgorithm> signature_algorithm; |
| 33 | 31 |
| 34 // Standard extensions that were parsed. | 32 // Standard extensions that were parsed. |
| 35 bool has_basic_constraints = false; | 33 bool has_basic_constraints = false; |
| 36 ParsedBasicConstraints basic_constraints; | 34 ParsedBasicConstraints basic_constraints; |
| 37 | 35 |
| 38 bool has_key_usage = false; | 36 bool has_key_usage = false; |
| 39 der::BitString key_usage; | 37 der::BitString key_usage; |
| 40 | 38 |
| 41 std::unique_ptr<GeneralNames> subject_alt_names; | |
| 42 | |
| 43 bool has_name_constraints = false; | 39 bool has_name_constraints = false; |
| 44 ParsedExtension name_constraints_extension; | 40 ParsedExtension name_constraints_extension; |
| 45 | 41 |
| 46 // The remaining extensions (excludes the standard ones above). | 42 // The remaining extensions (excludes the standard ones above). |
| 47 ExtensionsMap unconsumed_extensions; | 43 CertThing::ExtensionsMap unconsumed_extensions; |
| 48 }; | 44 }; |
| 49 | 45 |
| 50 // Removes the extension with OID |oid| from |unconsumed_extensions| and fills | 46 // Removes the extension with OID |oid| from |unconsumed_extensions| and fills |
| 51 // |extension| with the matching extension value. If there was no extension | 47 // |extension| with the matching extension value. If there was no extension |
| 52 // matching |oid| then returns |false|. | 48 // matching |oid| then returns |false|. |
| 53 WARN_UNUSED_RESULT bool ConsumeExtension(const der::Input& oid, | 49 WARN_UNUSED_RESULT bool ConsumeExtension( |
| 54 ExtensionsMap* unconsumed_extensions, | 50 const der::Input& oid, |
| 55 ParsedExtension* extension) { | 51 CertThing::ExtensionsMap* unconsumed_extensions, |
| 52 ParsedExtension* extension) { |
| 56 auto it = unconsumed_extensions->find(oid); | 53 auto it = unconsumed_extensions->find(oid); |
| 57 if (it == unconsumed_extensions->end()) | 54 if (it == unconsumed_extensions->end()) |
| 58 return false; | 55 return false; |
| 59 | 56 |
| 60 *extension = it->second; | 57 *extension = it->second; |
| 61 unconsumed_extensions->erase(it); | 58 unconsumed_extensions->erase(it); |
| 62 return true; | 59 return true; |
| 63 } | 60 } |
| 64 | 61 |
| 65 // Returns true if the certificate does not contain any unconsumed _critical_ | 62 // Returns true if the certificate does not contain any unconsumed _critical_ |
| 66 // extensions. | 63 // extensions. |
| 67 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( | 64 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( |
| 68 const FullyParsedCert& cert) { | 65 const FullyParsedCert& cert) { |
| 69 for (const auto& entry : cert.unconsumed_extensions) { | 66 for (const auto& entry : cert.unconsumed_extensions) { |
| 70 if (entry.second.critical) | 67 if (entry.second.critical) |
| 71 return false; | 68 return false; |
| 72 } | 69 } |
| 73 return true; | 70 return true; |
| 74 } | 71 } |
| 75 | 72 |
| 76 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, | 73 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, |
| 77 der::Input* value) { | 74 der::Input* value) { |
| 78 der::Parser parser(tlv); | 75 der::Parser parser(tlv); |
| 79 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); | 76 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
| 80 } | 77 } |
| 81 | 78 |
| 79 // XXX update doc |
| 82 // Parses an X.509 Certificate fully (including the TBSCertificate and | 80 // Parses an X.509 Certificate fully (including the TBSCertificate and |
| 83 // standard extensions), saving all the properties to |out_|. | 81 // standard extensions), saving all the properties to |out_|. |
| 84 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, | 82 WARN_UNUSED_RESULT bool FullyParseCertificate(scoped_refptr<CertThing> cert, |
| 85 FullyParsedCert* out) { | 83 FullyParsedCert* out) { |
| 86 // Parse the outer Certificate. | 84 // XXX move more of this into CertThing? |
| 87 if (!ParseCertificate(cert_tlv, &out->cert)) | 85 |
| 88 return false; | 86 out->cert = std::move(cert); |
| 89 | 87 |
| 90 // Parse the signature algorithm contained in the Certificate (there is | 88 // Parse the signature algorithm contained in the Certificate (there is |
| 91 // another one in the TBSCertificate, which is checked later by | 89 // another one in the TBSCertificate, which is checked later by |
| 92 // VerifySignatureAlgorithmsMatch) | 90 // VerifySignatureAlgorithmsMatch) |
| 93 out->signature_algorithm = | 91 out->signature_algorithm = SignatureAlgorithm::CreateFromDer( |
| 94 SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv); | 92 out->cert->parsed_cert().signature_algorithm_tlv); |
| 95 if (!out->signature_algorithm) | 93 if (!out->signature_algorithm) |
| 96 return false; | 94 return false; |
| 97 | 95 |
| 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 | 96 // Reset state relating to extensions (which may not get overwritten). This is |
| 103 // just a precaution, since in practice |out| will already be default | 97 // just a precaution, since in practice |out| will already be default |
| 104 // initialize. | 98 // initialize. |
| 105 out->has_basic_constraints = false; | 99 out->has_basic_constraints = false; |
| 106 out->has_key_usage = false; | 100 out->has_key_usage = false; |
| 107 out->unconsumed_extensions.clear(); | |
| 108 out->subject_alt_names.reset(); | |
| 109 out->has_name_constraints = false; | 101 out->has_name_constraints = false; |
| 110 | 102 |
| 103 out->unconsumed_extensions = out->cert->unconsumed_extensions(); |
| 111 // Parse the standard X.509 extensions and remove them from | 104 // Parse the standard X.509 extensions and remove them from |
| 112 // |unconsumed_extensions|. | 105 // |unconsumed_extensions|. |
| 113 if (out->tbs.has_extensions) { | 106 if (!out->unconsumed_extensions.empty()) { |
| 114 // ParseExtensions() ensures there are no duplicates, and maps the (unique) | |
| 115 // OID to the extension value. | |
| 116 if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions)) | |
| 117 return false; | |
| 118 | |
| 119 ParsedExtension extension; | 107 ParsedExtension extension; |
| 120 | 108 |
| 121 // Basic constraints. | 109 // Basic constraints. |
| 122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, | 110 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, |
| 123 &extension)) { | 111 &extension)) { |
| 124 out->has_basic_constraints = true; | 112 out->has_basic_constraints = true; |
| 125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) | 113 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) |
| 126 return false; | 114 return false; |
| 127 } | 115 } |
| 128 | 116 |
| 129 // KeyUsage. | 117 // KeyUsage. |
| 130 if (ConsumeExtension(KeyUsageOid(), &out->unconsumed_extensions, | 118 if (ConsumeExtension(KeyUsageOid(), &out->unconsumed_extensions, |
| 131 &extension)) { | 119 &extension)) { |
| 132 out->has_key_usage = true; | 120 out->has_key_usage = true; |
| 133 if (!ParseKeyUsage(extension.value, &out->key_usage)) | 121 if (!ParseKeyUsage(extension.value, &out->key_usage)) |
| 134 return false; | 122 return false; |
| 135 } | 123 } |
| 136 | 124 |
| 137 // Subject alternative name. | |
| 138 if (ConsumeExtension(SubjectAltNameOid(), &out->unconsumed_extensions, | |
| 139 &extension)) { | |
| 140 // RFC 5280 section 4.2.1.6: | |
| 141 // SubjectAltName ::= GeneralNames | |
| 142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value); | |
| 143 if (!out->subject_alt_names) | |
| 144 return false; | |
| 145 // RFC 5280 section 4.1.2.6: | |
| 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 | |
| 148 // subject name MUST be an empty sequence and the subjectAltName extension | |
| 149 // MUST be critical. | |
| 150 if (!extension.critical) { | |
| 151 der::Input subject_value; | |
| 152 if (!GetSequenceValue(out->tbs.subject_tlv, &subject_value)) | |
| 153 return false; | |
| 154 if (subject_value.Length() == 0) | |
| 155 return false; | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 // Name constraints. | 125 // Name constraints. |
| 160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, | 126 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, |
| 161 &out->name_constraints_extension)) { | 127 &out->name_constraints_extension)) { |
| 162 out->has_name_constraints = true; | 128 out->has_name_constraints = true; |
| 163 } | 129 } |
| 164 } | 130 } |
| 165 | 131 |
| 166 return true; | 132 return true; |
| 167 } | 133 } |
| 168 | 134 |
| 169 // Returns true if |name1_tlv| matches |name2_tlv|. The two inputs must be | |
| 170 // tag-length-value for RFC 5280's Name. | |
| 171 WARN_UNUSED_RESULT bool NameMatches(const der::Input& name1_tlv, | |
| 172 const der::Input& name2_tlv) { | |
| 173 der::Input name1_value; | |
| 174 der::Input name2_value; | |
| 175 | |
| 176 // Assume that the Name is an RDNSequence. VerifyNameMatch() expects the | |
| 177 // value from a SEQUENCE, so strip off the tag. | |
| 178 if (!GetSequenceValue(name1_tlv, &name1_value) || | |
| 179 !GetSequenceValue(name2_tlv, &name2_value)) { | |
| 180 return false; | |
| 181 } | |
| 182 | |
| 183 return VerifyNameMatch(name1_value, name2_value); | |
| 184 } | |
| 185 | |
| 186 // Returns true if |cert| was self-issued. The definition of self-issuance | 135 // Returns true if |cert| was self-issued. The definition of self-issuance |
| 187 // comes from RFC 5280 section 6.1: | 136 // comes from RFC 5280 section 6.1: |
| 188 // | 137 // |
| 189 // A certificate is self-issued if the same DN appears in the subject | 138 // 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 | 139 // 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 | 140 // 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 | 141 // 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 | 142 // each certificate. However, a CA may issue a certificate to itself to |
| 194 // support key rollover or changes in certificate policies. These | 143 // support key rollover or changes in certificate policies. These |
| 195 // self-issued certificates are not counted when evaluating path length | 144 // self-issued certificates are not counted when evaluating path length |
| 196 // or name constraints. | 145 // or name constraints. |
| 197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { | 146 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { |
| 198 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); | 147 return cert.cert->normalized_subject() == cert.cert->normalized_issuer(); |
| 199 } | 148 } |
| 200 | 149 |
| 201 // Returns true if |cert| is valid at time |time|. | 150 // Returns true if |cert| is valid at time |time|. |
| 202 // | 151 // |
| 203 // The certificate's validity requirements are described by RFC 5280 section | 152 // The certificate's validity requirements are described by RFC 5280 section |
| 204 // 4.1.2.5: | 153 // 4.1.2.5: |
| 205 // | 154 // |
| 206 // The validity period for a certificate is the period of time from | 155 // The validity period for a certificate is the period of time from |
| 207 // notBefore through notAfter, inclusive. | 156 // notBefore through notAfter, inclusive. |
| 208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, | 157 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, |
| 209 const der::GeneralizedTime time) { | 158 const der::GeneralizedTime time) { |
| 210 return !(time < cert.tbs.validity_not_before) && | 159 return !(time < cert.cert->parsed_tbs().validity_not_before) && |
| 211 !(cert.tbs.validity_not_after < time); | 160 !(cert.cert->parsed_tbs().validity_not_after < time); |
| 212 } | 161 } |
| 213 | 162 |
| 214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for | 163 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for |
| 215 // RSA with SHA1. | 164 // RSA with SHA1. |
| 216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( | 165 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( |
| 217 const der::Input& signature_algorithm_tlv) { | 166 const der::Input& signature_algorithm_tlv) { |
| 218 std::unique_ptr<SignatureAlgorithm> algorithm = | 167 std::unique_ptr<SignatureAlgorithm> algorithm = |
| 219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); | 168 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); |
| 220 | 169 |
| 221 return algorithm && | 170 return algorithm && |
| (...skipping 15 matching lines...) Expand all Loading... |
| 237 // | 186 // |
| 238 // The spec is not explicit about what "the same algorithm identifier" means. | 187 // 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 | 188 // Our interpretation is that the two DER-encoded fields must be byte-for-byte |
| 240 // identical. | 189 // identical. |
| 241 // | 190 // |
| 242 // In practice however there are certificates which use different encodings for | 191 // In practice however there are certificates which use different encodings for |
| 243 // specifying RSA with SHA1 (different OIDs). This is special-cased for | 192 // specifying RSA with SHA1 (different OIDs). This is special-cased for |
| 244 // compatibility sake. | 193 // compatibility sake. |
| 245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( | 194 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( |
| 246 const FullyParsedCert& cert) { | 195 const FullyParsedCert& cert) { |
| 247 const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv; | 196 const der::Input& alg1_tlv = cert.cert->parsed_cert().signature_algorithm_tlv; |
| 248 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; | 197 const der::Input& alg2_tlv = cert.cert->parsed_tbs().signature_algorithm_tlv; |
| 249 | 198 |
| 250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 199 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
| 251 // equal, but make a compatibility concession for RSA with SHA1. | 200 // equal, but make a compatibility concession for RSA with SHA1. |
| 252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 201 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
| 253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); | 202 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); |
| 254 } | 203 } |
| 255 | 204 |
| 256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 205 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
| 257 // Processing" procedure. | 206 // Processing" procedure. |
| 258 // | 207 // |
| 259 // |skip_issuer_checks| controls whether the function will skip: | 208 // |skip_issuer_checks| controls whether the function will skip: |
| 260 // - Checking that |cert|'s signature using |working_spki| | 209 // - Checking that |cert|'s signature using |working_spki| |
| 261 // - Checkinging that |cert|'s issuer matches |working_issuer_name| | 210 // - Checkinging that |cert|'s issuer matches |working_normalized_issuer_name| |
| 262 // This should be set to true only when verifying a trusted root certificate. | 211 // This should be set to true only when verifying a trusted root certificate. |
| 263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( | 212 WARN_UNUSED_RESULT bool BasicCertificateProcessing( |
| 264 const FullyParsedCert& cert, | 213 const FullyParsedCert& cert, |
| 265 bool is_target_cert, | 214 bool is_target_cert, |
| 266 bool skip_issuer_checks, | 215 bool skip_issuer_checks, |
| 267 const SignaturePolicy* signature_policy, | 216 const SignaturePolicy* signature_policy, |
| 268 const der::GeneralizedTime& time, | 217 const der::GeneralizedTime& time, |
| 269 const der::Input& working_spki, | 218 const der::Input& working_spki, |
| 270 const der::Input& working_issuer_name, | 219 const der::Input& working_normalized_issuer_name, |
| 271 const std::vector<std::unique_ptr<NameConstraints>>& | 220 const std::vector<std::unique_ptr<NameConstraints>>& |
| 272 name_constraints_list) { | 221 name_constraints_list) { |
| 273 // Check that the signature algorithms in Certificate vs TBSCertificate | 222 // 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 | 223 // 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. | 224 // sections 4.1.1.2 and 4.1.2.3. |
| 276 if (!VerifySignatureAlgorithmsMatch(cert)) | 225 if (!VerifySignatureAlgorithmsMatch(cert)) |
| 277 return false; | 226 return false; |
| 278 | 227 |
| 279 // Verify the digital signature using the previous certificate's key (RFC | 228 // Verify the digital signature using the previous certificate's key (RFC |
| 280 // 5280 section 6.1.3 step a.1). | 229 // 5280 section 6.1.3 step a.1). |
| 281 if (!skip_issuer_checks) { | 230 if (!skip_issuer_checks) { |
| 282 if (!VerifySignedData( | 231 if (!VerifySignedData(*cert.signature_algorithm, |
| 283 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, | 232 cert.cert->parsed_cert().tbs_certificate_tlv, |
| 284 cert.cert.signature_value, working_spki, signature_policy)) { | 233 cert.cert->parsed_cert().signature_value, |
| 234 working_spki, signature_policy)) { |
| 285 return false; | 235 return false; |
| 286 } | 236 } |
| 287 } | 237 } |
| 288 | 238 |
| 289 // Check the time range for the certificate's validity, ensuring it is valid | 239 // Check the time range for the certificate's validity, ensuring it is valid |
| 290 // at |time|. | 240 // at |time|. |
| 291 // (RFC 5280 section 6.1.3 step a.2) | 241 // (RFC 5280 section 6.1.3 step a.2) |
| 292 if (!VerifyTimeValidity(cert, time)) | 242 if (!VerifyTimeValidity(cert, time)) |
| 293 return false; | 243 return false; |
| 294 | 244 |
| 295 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) | 245 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) |
| 296 | 246 |
| 297 // Verify the certificate's issuer name matches the issuing certificate's | 247 // Verify the certificate's issuer name matches the issuing certificate's |
| 298 // subject name. (RFC 5280 section 6.1.3 step a.4) | 248 // subject name. (RFC 5280 section 6.1.3 step a.4) |
| 299 if (!skip_issuer_checks) { | 249 if (!skip_issuer_checks) { |
| 300 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) | 250 if (der::Input(&cert.cert->normalized_issuer()) != |
| 251 working_normalized_issuer_name) |
| 301 return false; | 252 return false; |
| 302 } | 253 } |
| 303 | 254 |
| 304 // Name constraints (RFC 5280 section 6.1.3 step b & c) | 255 // 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 | 256 // If certificate i is self-issued and it is not the final certificate in the |
| 306 // path, skip this step for certificate i. | 257 // path, skip this step for certificate i. |
| 307 if (!name_constraints_list.empty() && | 258 if (!name_constraints_list.empty() && |
| 308 (!IsSelfIssued(cert) || is_target_cert)) { | 259 (!IsSelfIssued(cert) || is_target_cert)) { |
| 260 // XXX used normalized_subject here |
| 309 der::Input subject_value; | 261 der::Input subject_value; |
| 310 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) | 262 if (!GetSequenceValue(cert.cert->parsed_tbs().subject_tlv, &subject_value)) |
| 311 return false; | 263 return false; |
| 312 for (const auto& nc : name_constraints_list) { | 264 for (const auto& nc : name_constraints_list) { |
| 313 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get())) | 265 if (!nc->IsPermittedCert(subject_value, cert.cert->subject_alt_names())) |
| 314 return false; | 266 return false; |
| 315 } | 267 } |
| 316 } | 268 } |
| 317 | 269 |
| 318 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet | 270 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet |
| 319 // implemented. | 271 // implemented. |
| 320 | 272 |
| 321 return true; | 273 return true; |
| 322 } | 274 } |
| 323 | 275 |
| 324 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for | 276 // 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. | 277 // Certificate i+1" procedure. |cert| is expected to be an intermediary. |
| 326 WARN_UNUSED_RESULT bool PrepareForNextCertificate( | 278 WARN_UNUSED_RESULT bool PrepareForNextCertificate( |
| 327 const FullyParsedCert& cert, | 279 const FullyParsedCert& cert, |
| 328 size_t* max_path_length_ptr, | 280 size_t* max_path_length_ptr, |
| 329 der::Input* working_spki, | 281 der::Input* working_spki, |
| 330 der::Input* working_issuer_name, | 282 der::Input* working_normalized_issuer_name, |
| 331 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { | 283 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { |
| 332 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet | 284 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet |
| 333 // implemented. | 285 // implemented. |
| 334 | 286 |
| 335 // From RFC 5280 section 6.1.4 step c: | 287 // From RFC 5280 section 6.1.4 step c: |
| 336 // | 288 // |
| 337 // Assign the certificate subject name to working_issuer_name. | 289 // Assign the certificate subject name to working_normalized_issuer_name. |
| 338 *working_issuer_name = cert.tbs.subject_tlv; | 290 *working_normalized_issuer_name = |
| 291 der::Input(&cert.cert->normalized_subject()); |
| 339 | 292 |
| 340 // From RFC 5280 section 6.1.4 step d: | 293 // From RFC 5280 section 6.1.4 step d: |
| 341 // | 294 // |
| 342 // Assign the certificate subjectPublicKey to working_public_key. | 295 // Assign the certificate subjectPublicKey to working_public_key. |
| 343 *working_spki = cert.tbs.spki_tlv; | 296 *working_spki = cert.cert->parsed_tbs().spki_tlv; |
| 344 | 297 |
| 345 // Note that steps e and f are omitted as they are handled by | 298 // Note that steps e and f are omitted as they are handled by |
| 346 // the assignment to |working_spki| above. See the definition | 299 // the assignment to |working_spki| above. See the definition |
| 347 // of |working_spki|. | 300 // of |working_spki|. |
| 348 | 301 |
| 349 // From RFC 5280 section 6.1.4 step g: | 302 // From RFC 5280 section 6.1.4 step g: |
| 350 if (cert.has_name_constraints) { | 303 if (cert.has_name_constraints) { |
| 351 std::unique_ptr<NameConstraints> name_constraints( | 304 std::unique_ptr<NameConstraints> name_constraints( |
| 352 NameConstraints::CreateFromDer( | 305 NameConstraints::CreateFromDer( |
| 353 cert.name_constraints_extension.value, | 306 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", | 440 // 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. | 441 // however is implied by RFC 5280 section 4.2.1.9. |
| 489 if (!VerifyTargetCertHasConsistentCaBits(cert)) | 442 if (!VerifyTargetCertHasConsistentCaBits(cert)) |
| 490 return false; | 443 return false; |
| 491 | 444 |
| 492 return true; | 445 return true; |
| 493 } | 446 } |
| 494 | 447 |
| 495 } // namespace | 448 } // namespace |
| 496 | 449 |
| 497 TrustAnchor::TrustAnchor() {} | 450 CertThing::CertThing() {} |
| 498 TrustAnchor::~TrustAnchor() {} | 451 CertThing::~CertThing() {} |
| 499 | 452 |
| 500 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData( | 453 scoped_refptr<CertThing> CertThing::CreateFromCertificateData( |
| 501 const uint8_t* data, | 454 const uint8_t* data, |
| 502 size_t length, | 455 size_t length, |
| 503 DataSource source) { | 456 DataSource source) { |
| 504 std::unique_ptr<TrustAnchor> result(new TrustAnchor); | 457 scoped_refptr<CertThing> result(new CertThing); |
| 505 | 458 |
| 506 switch (source) { | 459 switch (source) { |
| 507 case DataSource::INTERNAL_COPY: | 460 case DataSource::INTERNAL_COPY: |
| 508 result->cert_data_.assign(data, data + length); | 461 result->cert_data_.assign(data, data + length); |
| 509 result->cert_ = | 462 result->cert_ = |
| 510 der::Input(result->cert_data_.data(), result->cert_data_.size()); | 463 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
| 511 break; | 464 break; |
| 512 case DataSource::EXTERNAL_REFERENCE: | 465 case DataSource::EXTERNAL_REFERENCE: |
| 513 result->cert_ = der::Input(data, length); | 466 result->cert_ = der::Input(data, length); |
| 514 break; | 467 break; |
| 515 } | 468 } |
| 516 | 469 |
| 517 // Parse the certificate to get its name. | 470 // Parse the certificate to get its name. |
| 518 ParsedCertificate cert; | 471 if (!ParseCertificate(result->cert_, &result->parsed_cert_)) |
| 519 if (!ParseCertificate(result->cert(), &cert)) | |
| 520 return nullptr; | 472 return nullptr; |
| 521 | 473 |
| 522 ParsedTbsCertificate tbs; | 474 if (!ParseTbsCertificate(result->parsed_cert_.tbs_certificate_tlv, |
| 523 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) | 475 &result->parsed_tbs_)) |
| 524 return nullptr; | 476 return nullptr; |
| 525 | 477 |
| 526 result->name_ = tbs.subject_tlv; | 478 der::Input subject_value; |
| 479 if (!GetSequenceValue(result->parsed_tbs_.subject_tlv, &subject_value) || |
| 480 !NormalizeName(subject_value, &result->normalized_subject_)) |
| 481 return nullptr; |
| 482 der::Input issuer_value; |
| 483 if (!GetSequenceValue(result->parsed_tbs_.issuer_tlv, &issuer_value) || |
| 484 !NormalizeName(issuer_value, &result->normalized_issuer_)) |
| 485 return nullptr; |
| 527 | 486 |
| 528 // TODO(eroman): If adding a self-signed certificate, check that its | 487 // Parse the standard X.509 extensions and remove them from |
| 529 // signature is correct? This check will not otherwise be done during | 488 // |unconsumed_extensions|. |
| 530 // verification. | 489 if (result->parsed_tbs_.has_extensions) { |
| 490 // ParseExtensions() ensures there are no duplicates, and maps the (unique) |
| 491 // OID to the extension value. |
| 492 if (!ParseExtensions(result->parsed_tbs_.extensions_tlv, |
| 493 &result->unconsumed_extensions_)) |
| 494 return nullptr; |
| 495 |
| 496 // Subject alternative name. |
| 497 if (ConsumeExtension(SubjectAltNameOid(), &result->unconsumed_extensions_, |
| 498 &result->subject_alt_names_extension_)) { |
| 499 // RFC 5280 section 4.2.1.6: |
| 500 // SubjectAltName ::= GeneralNames |
| 501 result->subject_alt_names_ = GeneralNames::CreateFromDer( |
| 502 result->subject_alt_names_extension_.value); |
| 503 if (!result->subject_alt_names_) |
| 504 return nullptr; |
| 505 // RFC 5280 section 4.1.2.6: |
| 506 // If subject naming information is present only in the subjectAltName |
| 507 // extension (e.g., a key bound only to an email address or URI), then the |
| 508 // subject name MUST be an empty sequence and the subjectAltName extension |
| 509 // MUST be critical. |
| 510 if (!result->subject_alt_names_extension_.critical) { |
| 511 der::Input subject_value; |
| 512 // XXX can we use normalized_subject_ here? |
| 513 if (!GetSequenceValue(result->parsed_tbs().subject_tlv, &subject_value)) |
| 514 return nullptr; |
| 515 if (subject_value.Length() == 0) |
| 516 return nullptr; |
| 517 } |
| 518 } |
| 519 } |
| 531 | 520 |
| 532 return result; | 521 return result; |
| 533 } | 522 } |
| 534 | 523 |
| 535 bool TrustAnchor::MatchesName(const der::Input& name) const { | 524 scoped_refptr<CertThing> CertThing::CreateFromCertificateCopy( |
| 536 return NameMatches(name, name_); | 525 const base::StringPiece& data) { |
| 526 return CertThing::CreateFromCertificateData( |
| 527 reinterpret_cast<const uint8_t*>(data.data()), data.size(), |
| 528 DataSource::INTERNAL_COPY); |
| 537 } | 529 } |
| 538 | 530 |
| 539 TrustStore::TrustStore() {} | 531 TrustStore::TrustStore() {} |
| 540 TrustStore::~TrustStore() {} | 532 TrustStore::~TrustStore() {} |
| 541 | 533 |
| 542 void TrustStore::Clear() { | 534 void TrustStore::Clear() { |
| 543 anchors_.clear(); | 535 anchors_.clear(); |
| 544 } | 536 } |
| 545 | 537 |
| 546 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { | 538 void TrustStore::AddTrustedCertificate(scoped_refptr<CertThing> anchor) { |
| 547 return AddTrustedCertificate(data, length, | 539 // XXX should this check for duplicate certs? |
| 548 TrustAnchor::DataSource::INTERNAL_COPY); | 540 anchors_.insert( |
| 541 std::make_pair(anchor->normalized_subject(), std::move(anchor))); |
| 549 } | 542 } |
| 550 | 543 |
| 551 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { | 544 void TrustStore::FindTrustAnchorsByNormalizedName( |
| 552 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), | 545 const std::string& normalized_name, |
| 553 data.size()); | 546 CertVector* matches) const { |
| 547 auto range = anchors_.equal_range(normalized_name); |
| 548 for (auto it = range.first; it != range.second; ++it) |
| 549 matches->push_back(it->second); |
| 554 } | 550 } |
| 555 | 551 |
| 556 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, | 552 bool TrustStore::IsTrustedCertificate(const CertThing* cert) const { |
| 557 size_t length) { | 553 auto range = anchors_.equal_range(cert->normalized_subject()); |
| 558 return AddTrustedCertificate(data, length, | 554 for (auto it = range.first; it != range.second; ++it) { |
| 559 TrustAnchor::DataSource::EXTERNAL_REFERENCE); | 555 if (it->second == cert || it->second->der_cert() == cert->der_cert()) |
| 560 } | |
| 561 | |
| 562 const TrustAnchor* TrustStore::FindTrustAnchorByName( | |
| 563 const der::Input& name) const { | |
| 564 for (const auto& anchor : anchors_) { | |
| 565 if (anchor->MatchesName(name)) { | |
| 566 return anchor.get(); | |
| 567 } | |
| 568 } | |
| 569 return nullptr; | |
| 570 } | |
| 571 | |
| 572 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { | |
| 573 for (const auto& anchor : anchors_) { | |
| 574 if (anchor->cert() == cert_der) | |
| 575 return true; | 556 return true; |
| 576 } | 557 } |
| 577 return false; | 558 return false; |
| 578 } | 559 } |
| 579 | 560 |
| 580 bool TrustStore::AddTrustedCertificate(const uint8_t* data, | |
| 581 size_t length, | |
| 582 TrustAnchor::DataSource source) { | |
| 583 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source); | |
| 584 if (!anchor) | |
| 585 return false; | |
| 586 anchors_.push_back(std::move(anchor)); | |
| 587 return true; | |
| 588 } | |
| 589 | |
| 590 // TODO(eroman): Move this into existing anonymous namespace. | |
| 591 namespace { | |
| 592 | |
| 593 // This implementation is structured to mimic the description of certificate | 561 // This implementation is structured to mimic the description of certificate |
| 594 // path verification given by RFC 5280 section 6.1. | 562 // path verification given by RFC 5280 section 6.1. |
| 595 // | 563 // |
| 596 // Unlike RFC 5280, the trust anchor is specified as the root certificate in | 564 // 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 | 565 // 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). | 566 // signature nor issuer name are verified. (It needn't be self-signed). |
| 599 bool VerifyCertificateChainAssumingTrustedRoot( | 567 bool VerifyCertificateChainAssumingTrustedRoot( |
| 600 const std::vector<der::Input>& certs_der, | 568 const std::vector<scoped_refptr<CertThing>>& certs, |
| 601 // The trust store is only used for assertions. | 569 // The trust store is only used for assertions. |
| 602 const TrustStore& trust_store, | 570 const TrustStore& trust_store, |
| 603 const SignaturePolicy* signature_policy, | 571 const SignaturePolicy* signature_policy, |
| 604 const der::GeneralizedTime& time) { | 572 const der::GeneralizedTime& time) { |
| 605 // An empty chain is necessarily invalid. | 573 // An empty chain is necessarily invalid. |
| 606 if (certs_der.empty()) | 574 if (certs.empty()) |
| 607 return false; | 575 return false; |
| 608 | 576 |
| 609 // IMPORTANT: the assumption being made is that the root certificate in | 577 // 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 | 578 // the given path is the trust anchor (and has already been verified as |
| 611 // such). | 579 // such). |
| 612 DCHECK(trust_store.IsTrustedCertificate(certs_der.back())); | 580 DCHECK(trust_store.IsTrustedCertificate(certs.back().get())); |
| 613 | 581 |
| 614 // Will contain a NameConstraints for each previous cert in the chain which | 582 // Will contain a NameConstraints for each previous cert in the chain which |
| 615 // had nameConstraints. This corresponds to the permitted_subtrees and | 583 // had nameConstraints. This corresponds to the permitted_subtrees and |
| 616 // excluded_subtrees state variables from RFC 5280. | 584 // excluded_subtrees state variables from RFC 5280. |
| 617 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; | 585 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; |
| 618 | 586 |
| 619 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: | 587 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: |
| 620 // * working_public_key | 588 // * working_public_key |
| 621 // * working_public_key_algorithm | 589 // * working_public_key_algorithm |
| 622 // * working_public_key_parameters | 590 // * working_public_key_parameters |
| 623 // | 591 // |
| 624 // They are combined for simplicity since the signature verification takes an | 592 // They are combined for simplicity since the signature verification takes an |
| 625 // SPKI, and the parameter inheritence is not applicable for the supported | 593 // SPKI, and the parameter inheritence is not applicable for the supported |
| 626 // key types. | 594 // key types. |
| 627 // | 595 // |
| 628 // An approximate explanation of |working_spki| is this description from RFC | 596 // An approximate explanation of |working_spki| is this description from RFC |
| 629 // 5280 section 6.1.2: | 597 // 5280 section 6.1.2: |
| 630 // | 598 // |
| 631 // working_public_key: the public key used to verify the | 599 // working_public_key: the public key used to verify the |
| 632 // signature of a certificate. | 600 // signature of a certificate. |
| 633 der::Input working_spki; | 601 der::Input working_spki; |
| 634 | 602 |
| 635 // |working_issuer_name| corresponds with the same named variable in RFC 5280 | 603 // |working_normalized_issuer_name| is the normalized value of the |
| 636 // section 6.1.2: | 604 // working_issuer_name variable in RFC 5280 section 6.1.2: |
| 637 // | 605 // |
| 638 // working_issuer_name: the issuer distinguished name expected | 606 // working_issuer_name: the issuer distinguished name expected |
| 639 // in the next certificate in the chain. | 607 // in the next certificate in the chain. |
| 640 der::Input working_issuer_name; | 608 der::Input working_normalized_issuer_name; |
| 641 | 609 |
| 642 // |max_path_length| corresponds with the same named variable in RFC 5280 | 610 // |max_path_length| corresponds with the same named variable in RFC 5280 |
| 643 // section 6.1.2: | 611 // section 6.1.2: |
| 644 // | 612 // |
| 645 // max_path_length: this integer is initialized to n, is | 613 // max_path_length: this integer is initialized to n, is |
| 646 // decremented for each non-self-issued certificate in the path, | 614 // decremented for each non-self-issued certificate in the path, |
| 647 // and may be reduced to the value in the path length constraint | 615 // and may be reduced to the value in the path length constraint |
| 648 // field within the basic constraints extension of a CA | 616 // field within the basic constraints extension of a CA |
| 649 // certificate. | 617 // certificate. |
| 650 size_t max_path_length = certs_der.size(); | 618 size_t max_path_length = certs.size(); |
| 651 | 619 |
| 652 // Iterate over all the certificates in the reverse direction: starting from | 620 // Iterate over all the certificates in the reverse direction: starting from |
| 653 // the trust anchor and progressing towards the target certificate. | 621 // the trust anchor and progressing towards the target certificate. |
| 654 // | 622 // |
| 655 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. | 623 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. |
| 656 // | 624 // |
| 657 // * i=0 : Trust anchor. | 625 // * i=0 : Trust anchor. |
| 658 // * i=N-1 : Target certificate. | 626 // * i=N-1 : Target certificate. |
| 659 for (size_t i = 0; i < certs_der.size(); ++i) { | 627 for (size_t i = 0; i < certs.size(); ++i) { |
| 660 const size_t index_into_certs_der = certs_der.size() - i - 1; | 628 const size_t index_into_certs = certs.size() - i - 1; |
| 661 | 629 |
| 662 // |is_target_cert| is true if the current certificate is the target | 630 // |is_target_cert| is true if the current certificate is the target |
| 663 // certificate being verified. The target certificate isn't necessarily an | 631 // certificate being verified. The target certificate isn't necessarily an |
| 664 // end-entity certificate. | 632 // end-entity certificate. |
| 665 const bool is_target_cert = index_into_certs_der == 0; | 633 const bool is_target_cert = index_into_certs == 0; |
| 666 | 634 |
| 667 // |is_trust_anchor| is true if the current certificate is the trust | 635 // |is_trust_anchor| is true if the current certificate is the trust |
| 668 // anchor. This certificate is implicitly trusted. | 636 // anchor. This certificate is implicitly trusted. |
| 669 const bool is_trust_anchor = i == 0; | 637 const bool is_trust_anchor = i == 0; |
| 670 | 638 |
| 671 // Parse the current certificate into |cert|. | 639 // Parse the current certificate into |cert|. |
| 672 FullyParsedCert cert; | 640 FullyParsedCert cert; |
| 673 const der::Input& cert_der = certs_der[index_into_certs_der]; | 641 if (!FullyParseCertificate(certs[index_into_certs], &cert)) |
| 674 if (!FullyParseCertificate(cert_der, &cert)) | |
| 675 return false; | 642 return false; |
| 676 | 643 |
| 677 // Per RFC 5280 section 6.1: | 644 // Per RFC 5280 section 6.1: |
| 678 // * Do basic processing for each certificate | 645 // * Do basic processing for each certificate |
| 679 // * If it is the last certificate in the path (target certificate) | 646 // * If it is the last certificate in the path (target certificate) |
| 680 // - Then run "Wrap up" | 647 // - Then run "Wrap up" |
| 681 // - Otherwise run "Prepare for Next cert" | 648 // - Otherwise run "Prepare for Next cert" |
| 682 if (!BasicCertificateProcessing( | 649 if (!BasicCertificateProcessing(cert, is_target_cert, is_trust_anchor, |
| 683 cert, is_target_cert, is_trust_anchor, signature_policy, time, | 650 signature_policy, time, working_spki, |
| 684 working_spki, working_issuer_name, name_constraints_list)) { | 651 working_normalized_issuer_name, |
| 652 name_constraints_list)) { |
| 685 return false; | 653 return false; |
| 686 } | 654 } |
| 687 if (!is_target_cert) { | 655 if (!is_target_cert) { |
| 688 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, | 656 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, |
| 689 &working_issuer_name, | 657 &working_normalized_issuer_name, |
| 690 &name_constraints_list)) { | 658 &name_constraints_list)) { |
| 691 return false; | 659 return false; |
| 692 } | 660 } |
| 693 } else { | 661 } else { |
| 694 if (!WrapUp(cert)) | 662 if (!WrapUp(cert)) |
| 695 return false; | 663 return false; |
| 696 } | 664 } |
| 697 } | 665 } |
| 698 | 666 |
| 699 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 667 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
| 700 // | 668 // |
| 701 // A certificate MUST NOT appear more than once in a prospective | 669 // A certificate MUST NOT appear more than once in a prospective |
| 702 // certification path. | 670 // certification path. |
| 703 | 671 |
| 704 return true; | 672 return true; |
| 705 } | 673 } |
| 706 | 674 |
| 707 // TODO(eroman): This function is a temporary hack in the absence of full | 675 } // namespace net |
| 708 // 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. | |
| 710 // | |
| 711 // Beyond this no other verification is done on the chain. The caller is | |
| 712 // responsible for verifying the subsequent chain's correctness. | |
| 713 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( | |
| 714 const std::vector<der::Input>& certs_der, | |
| 715 const TrustStore& trust_store, | |
| 716 std::vector<der::Input>* certs_der_trusted_root) { | |
| 717 // Copy the input chain. | |
| 718 *certs_der_trusted_root = certs_der; | |
| 719 | 676 |
| 720 if (certs_der.empty()) | 677 // XXX this is ick that verify_certificate_chain.cc uses path_builder.h |
| 721 return false; | 678 // and path_builder.cc uses verify_certificate_chain.h. Reorganize some things |
| 679 // or remove this entirely. |
| 680 #include "base/memory/ptr_util.h" |
| 681 #include "path_builder.h" |
| 722 | 682 |
| 723 // Check if the current root certificate is trusted. If it is then no | 683 namespace net { |
| 724 // extra work is needed. | |
| 725 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back())) | |
| 726 return true; | |
| 727 | |
| 728 // Otherwise if it is not trusted, check whether its issuer is trusted. If | |
| 729 // so, make *that* trusted certificate the root. If the issuer is not in | |
| 730 // the trust store then give up and fail (this is not full path building). | |
| 731 ParsedCertificate cert; | |
| 732 ParsedTbsCertificate tbs; | |
| 733 if (!ParseCertificate(certs_der.back(), &cert) || | |
| 734 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { | |
| 735 return false; | |
| 736 } | |
| 737 | |
| 738 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); | |
| 739 if (!trust_anchor) | |
| 740 return false; | |
| 741 certs_der_trusted_root->push_back(trust_anchor->cert()); | |
| 742 return true; | |
| 743 } | |
| 744 | |
| 745 } // namespace | |
| 746 | 684 |
| 747 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, | 685 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, |
| 748 const TrustStore& trust_store, | 686 const TrustStore& trust_store, |
| 749 const SignaturePolicy* signature_policy, | 687 const SignaturePolicy* signature_policy, |
| 750 const der::GeneralizedTime& time) { | 688 const der::GeneralizedTime& time) { |
| 751 // Modify the certificate chain so that its root is a trusted certificate. | 689 if (certs_der.empty()) |
| 752 std::vector<der::Input> certs_der_trusted_root; | |
| 753 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, | |
| 754 &certs_der_trusted_root)) { | |
| 755 return false; | 690 return false; |
| 691 |
| 692 scoped_refptr<CertThing> target_cert(CertThing::CreateFromCertificateData( |
| 693 certs_der.front().UnsafeData(), certs_der.front().Length(), |
| 694 CertThing::DataSource::EXTERNAL_REFERENCE)); |
| 695 if (!target_cert) |
| 696 return false; |
| 697 |
| 698 CertPathBuilder::CertSources cert_sources; |
| 699 std::unique_ptr<StaticCertSource> intermediate_cert_source; |
| 700 std::vector<scoped_refptr<CertThing>> intermediates; |
| 701 for (size_t i = 1; i < certs_der.size(); ++i) { |
| 702 const auto& cert_der = certs_der[i]; |
| 703 scoped_refptr<CertThing> cert(CertThing::CreateFromCertificateData( |
| 704 cert_der.UnsafeData(), cert_der.Length(), |
| 705 CertThing::DataSource::EXTERNAL_REFERENCE)); |
| 706 if (!cert) |
| 707 return false; |
| 708 intermediates.push_back(std::move(cert)); |
| 709 } |
| 710 if (!intermediates.empty()) { |
| 711 intermediate_cert_source = |
| 712 base::WrapUnique(new StaticCertSource(intermediates)); |
| 713 cert_sources.push_back(intermediate_cert_source.get()); |
| 756 } | 714 } |
| 757 | 715 |
| 758 // Verify the chain. | 716 // Verify the chain. |
| 759 return VerifyCertificateChainAssumingTrustedRoot( | 717 CertPathBuilder::Result result; |
| 760 certs_der_trusted_root, trust_store, signature_policy, time); | 718 CertPathBuilder path_builder(target_cert, cert_sources, trust_store, |
| 719 signature_policy, time, &result); |
| 720 int rv = path_builder.Run(CompletionCallback()); |
| 721 // Assume that CertPathBuilder will complete synchronously since only a |
| 722 // StaticCertSource was passed in. If it did return ERR_IO_PENDING, just |
| 723 // return failure here. |
| 724 return rv == OK; |
| 761 } | 725 } |
| 762 | 726 |
| 763 } // namespace net | 727 } // namespace net |
| OLD | NEW |