| Index: net/cert/internal/parsed_certificate.cc
|
| diff --git a/net/cert/internal/parsed_certificate.cc b/net/cert/internal/parsed_certificate.cc
|
| index 0c655079e3cf9a02e7b71de6116681cd3bc89d2c..97a432aa6d28426ed35cce92c123e622926fe302 100644
|
| --- a/net/cert/internal/parsed_certificate.cc
|
| +++ b/net/cert/internal/parsed_certificate.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "net/cert/internal/parsed_certificate.h"
|
|
|
| +#include "net/cert/internal/certificate_policies.h"
|
| +#include "net/cert/internal/extended_key_usage.h"
|
| #include "net/cert/internal/name_constraints.h"
|
| #include "net/cert/internal/signature_algorithm.h"
|
| #include "net/cert/internal/verify_name_match.h"
|
| @@ -22,6 +24,21 @@ WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
|
|
|
| } // namespace
|
|
|
| +bool ParsedCertificate::GetExtension(const der::Input& extension_oid,
|
| + ParsedExtension* parsed_extension) const {
|
| + if (!tbs_.has_extensions)
|
| + return false;
|
| +
|
| + auto it = extensions_.find(extension_oid);
|
| + if (it == extensions_.end()) {
|
| + *parsed_extension = ParsedExtension();
|
| + return false;
|
| + }
|
| +
|
| + *parsed_extension = it->second;
|
| + return true;
|
| +}
|
| +
|
| ParsedCertificate::ParsedCertificate() {}
|
| ParsedCertificate::~ParsedCertificate() {}
|
|
|
| @@ -102,37 +119,40 @@ scoped_refptr<ParsedCertificate> ParsedCertificate::CreateInternal(
|
| return nullptr;
|
| }
|
|
|
| - // Parse the standard X.509 extensions and remove them from
|
| - // |unparsed_extensions|.
|
| + // Parse the standard X.509 extensions.
|
| if (result->tbs_.has_extensions) {
|
| // ParseExtensions() ensures there are no duplicates, and maps the (unique)
|
| // OID to the extension value.
|
| - if (!ParseExtensions(result->tbs_.extensions_tlv,
|
| - &result->unparsed_extensions_)) {
|
| + if (!ParseExtensions(result->tbs_.extensions_tlv, &result->extensions_)) {
|
| return nullptr;
|
| }
|
|
|
| ParsedExtension extension;
|
|
|
| // Basic constraints.
|
| - if (ConsumeExtension(BasicConstraintsOid(), &result->unparsed_extensions_,
|
| - &extension)) {
|
| + if (result->GetExtension(BasicConstraintsOid(), &extension)) {
|
| result->has_basic_constraints_ = true;
|
| if (!ParseBasicConstraints(extension.value, &result->basic_constraints_))
|
| return nullptr;
|
| }
|
|
|
| - // KeyUsage.
|
| - if (ConsumeExtension(KeyUsageOid(), &result->unparsed_extensions_,
|
| - &extension)) {
|
| + // Key Usage.
|
| + if (result->GetExtension(KeyUsageOid(), &extension)) {
|
| result->has_key_usage_ = true;
|
| if (!ParseKeyUsage(extension.value, &result->key_usage_))
|
| return nullptr;
|
| }
|
|
|
| + // Extended Key Usage.
|
| + if (result->GetExtension(ExtKeyUsageOid(), &extension)) {
|
| + result->has_extended_key_usage_ = true;
|
| + if (!ParseEKUExtension(extension.value, &result->extended_key_usage_))
|
| + return nullptr;
|
| + }
|
| +
|
| // Subject alternative name.
|
| - if (ConsumeExtension(SubjectAltNameOid(), &result->unparsed_extensions_,
|
| - &result->subject_alt_names_extension_)) {
|
| + if (result->GetExtension(SubjectAltNameOid(),
|
| + &result->subject_alt_names_extension_)) {
|
| // RFC 5280 section 4.2.1.6:
|
| // SubjectAltName ::= GeneralNames
|
| result->subject_alt_names_ =
|
| @@ -151,8 +171,7 @@ scoped_refptr<ParsedCertificate> ParsedCertificate::CreateInternal(
|
| }
|
|
|
| // Name constraints.
|
| - if (ConsumeExtension(NameConstraintsOid(), &result->unparsed_extensions_,
|
| - &extension)) {
|
| + if (result->GetExtension(NameConstraintsOid(), &extension)) {
|
| result->name_constraints_ =
|
| NameConstraints::Create(extension.value, extension.critical);
|
| if (!result->name_constraints_)
|
| @@ -160,9 +179,8 @@ scoped_refptr<ParsedCertificate> ParsedCertificate::CreateInternal(
|
| }
|
|
|
| // Authority information access.
|
| - if (ConsumeExtension(AuthorityInfoAccessOid(),
|
| - &result->unparsed_extensions_,
|
| - &result->authority_info_access_extension_)) {
|
| + if (result->GetExtension(AuthorityInfoAccessOid(),
|
| + &result->authority_info_access_extension_)) {
|
| result->has_authority_info_access_ = true;
|
| if (!ParseAuthorityInfoAccess(
|
| result->authority_info_access_extension_.value,
|
| @@ -170,10 +188,14 @@ scoped_refptr<ParsedCertificate> ParsedCertificate::CreateInternal(
|
| return nullptr;
|
| }
|
|
|
| - // NOTE: if additional extensions are consumed here, the verification code
|
| - // must be updated to process those extensions, since the
|
| - // VerifyNoUnconsumedCriticalExtensions uses the unparsed_extensions_
|
| - // variable to tell which extensions were processed.
|
| + // Policies.
|
| + if (result->GetExtension(CertificatePoliciesOid(), &extension)) {
|
| + result->has_policy_oids_ = true;
|
| + if (!ParseCertificatePoliciesExtension(extension.value,
|
| + &result->policy_oids_)) {
|
| + return nullptr;
|
| + }
|
| + }
|
| }
|
|
|
| return result;
|
|
|