| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/parsed_certificate.h" | 5 #include "net/cert/internal/parsed_certificate.h" |
| 6 | 6 |
| 7 #include "net/cert/internal/certificate_policies.h" |
| 8 #include "net/cert/internal/extended_key_usage.h" |
| 7 #include "net/cert/internal/name_constraints.h" | 9 #include "net/cert/internal/name_constraints.h" |
| 8 #include "net/cert/internal/signature_algorithm.h" | 10 #include "net/cert/internal/signature_algorithm.h" |
| 9 #include "net/cert/internal/verify_name_match.h" | 11 #include "net/cert/internal/verify_name_match.h" |
| 10 #include "net/der/parser.h" | 12 #include "net/der/parser.h" |
| 11 #include "third_party/boringssl/src/include/openssl/pool.h" | 13 #include "third_party/boringssl/src/include/openssl/pool.h" |
| 12 | 14 |
| 13 namespace net { | 15 namespace net { |
| 14 | 16 |
| 15 namespace { | 17 namespace { |
| 16 | 18 |
| 17 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, | 19 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, |
| 18 der::Input* value) { | 20 der::Input* value) { |
| 19 der::Parser parser(tlv); | 21 der::Parser parser(tlv); |
| 20 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); | 22 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
| 21 } | 23 } |
| 22 | 24 |
| 23 } // namespace | 25 } // namespace |
| 24 | 26 |
| 27 bool ParsedCertificate::GetExtension(const der::Input& extension_oid, |
| 28 ParsedExtension* parsed_extension) const { |
| 29 if (!tbs_.has_extensions) |
| 30 return false; |
| 31 |
| 32 auto it = extensions_.find(extension_oid); |
| 33 if (it == extensions_.end()) { |
| 34 *parsed_extension = ParsedExtension(); |
| 35 return false; |
| 36 } |
| 37 |
| 38 *parsed_extension = it->second; |
| 39 return true; |
| 40 } |
| 41 |
| 25 ParsedCertificate::ParsedCertificate() {} | 42 ParsedCertificate::ParsedCertificate() {} |
| 26 ParsedCertificate::~ParsedCertificate() {} | 43 ParsedCertificate::~ParsedCertificate() {} |
| 27 | 44 |
| 28 // static | 45 // static |
| 29 scoped_refptr<ParsedCertificate> ParsedCertificate::Create( | 46 scoped_refptr<ParsedCertificate> ParsedCertificate::Create( |
| 30 bssl::UniquePtr<CRYPTO_BUFFER> cert_data, | 47 bssl::UniquePtr<CRYPTO_BUFFER> cert_data, |
| 31 const ParseCertificateOptions& options, | 48 const ParseCertificateOptions& options, |
| 32 CertErrors* errors) { | 49 CertErrors* errors) { |
| 33 return CreateInternal(std::move(cert_data), der::Input(), options, errors); | 50 return CreateInternal(std::move(cert_data), der::Input(), options, errors); |
| 34 } | 51 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 if (!GetSequenceValue(result->tbs_.subject_tlv, &subject_value) || | 112 if (!GetSequenceValue(result->tbs_.subject_tlv, &subject_value) || |
| 96 !NormalizeName(subject_value, &result->normalized_subject_)) { | 113 !NormalizeName(subject_value, &result->normalized_subject_)) { |
| 97 return nullptr; | 114 return nullptr; |
| 98 } | 115 } |
| 99 der::Input issuer_value; | 116 der::Input issuer_value; |
| 100 if (!GetSequenceValue(result->tbs_.issuer_tlv, &issuer_value) || | 117 if (!GetSequenceValue(result->tbs_.issuer_tlv, &issuer_value) || |
| 101 !NormalizeName(issuer_value, &result->normalized_issuer_)) { | 118 !NormalizeName(issuer_value, &result->normalized_issuer_)) { |
| 102 return nullptr; | 119 return nullptr; |
| 103 } | 120 } |
| 104 | 121 |
| 105 // Parse the standard X.509 extensions and remove them from | 122 // Parse the standard X.509 extensions. |
| 106 // |unparsed_extensions|. | |
| 107 if (result->tbs_.has_extensions) { | 123 if (result->tbs_.has_extensions) { |
| 108 // ParseExtensions() ensures there are no duplicates, and maps the (unique) | 124 // ParseExtensions() ensures there are no duplicates, and maps the (unique) |
| 109 // OID to the extension value. | 125 // OID to the extension value. |
| 110 if (!ParseExtensions(result->tbs_.extensions_tlv, | 126 if (!ParseExtensions(result->tbs_.extensions_tlv, &result->extensions_)) { |
| 111 &result->unparsed_extensions_)) { | |
| 112 return nullptr; | 127 return nullptr; |
| 113 } | 128 } |
| 114 | 129 |
| 115 ParsedExtension extension; | 130 ParsedExtension extension; |
| 116 | 131 |
| 117 // Basic constraints. | 132 // Basic constraints. |
| 118 if (ConsumeExtension(BasicConstraintsOid(), &result->unparsed_extensions_, | 133 if (result->GetExtension(BasicConstraintsOid(), &extension)) { |
| 119 &extension)) { | |
| 120 result->has_basic_constraints_ = true; | 134 result->has_basic_constraints_ = true; |
| 121 if (!ParseBasicConstraints(extension.value, &result->basic_constraints_)) | 135 if (!ParseBasicConstraints(extension.value, &result->basic_constraints_)) |
| 122 return nullptr; | 136 return nullptr; |
| 123 } | 137 } |
| 124 | 138 |
| 125 // KeyUsage. | 139 // Key Usage. |
| 126 if (ConsumeExtension(KeyUsageOid(), &result->unparsed_extensions_, | 140 if (result->GetExtension(KeyUsageOid(), &extension)) { |
| 127 &extension)) { | |
| 128 result->has_key_usage_ = true; | 141 result->has_key_usage_ = true; |
| 129 if (!ParseKeyUsage(extension.value, &result->key_usage_)) | 142 if (!ParseKeyUsage(extension.value, &result->key_usage_)) |
| 130 return nullptr; | 143 return nullptr; |
| 131 } | 144 } |
| 132 | 145 |
| 146 // Extended Key Usage. |
| 147 if (result->GetExtension(ExtKeyUsageOid(), &extension)) { |
| 148 result->has_extended_key_usage_ = true; |
| 149 if (!ParseEKUExtension(extension.value, &result->extended_key_usage_)) |
| 150 return nullptr; |
| 151 } |
| 152 |
| 133 // Subject alternative name. | 153 // Subject alternative name. |
| 134 if (ConsumeExtension(SubjectAltNameOid(), &result->unparsed_extensions_, | 154 if (result->GetExtension(SubjectAltNameOid(), |
| 135 &result->subject_alt_names_extension_)) { | 155 &result->subject_alt_names_extension_)) { |
| 136 // RFC 5280 section 4.2.1.6: | 156 // RFC 5280 section 4.2.1.6: |
| 137 // SubjectAltName ::= GeneralNames | 157 // SubjectAltName ::= GeneralNames |
| 138 result->subject_alt_names_ = | 158 result->subject_alt_names_ = |
| 139 GeneralNames::Create(result->subject_alt_names_extension_.value); | 159 GeneralNames::Create(result->subject_alt_names_extension_.value); |
| 140 if (!result->subject_alt_names_) | 160 if (!result->subject_alt_names_) |
| 141 return nullptr; | 161 return nullptr; |
| 142 // RFC 5280 section 4.1.2.6: | 162 // RFC 5280 section 4.1.2.6: |
| 143 // If subject naming information is present only in the subjectAltName | 163 // If subject naming information is present only in the subjectAltName |
| 144 // extension (e.g., a key bound only to an email address or URI), then the | 164 // extension (e.g., a key bound only to an email address or URI), then the |
| 145 // subject name MUST be an empty sequence and the subjectAltName extension | 165 // subject name MUST be an empty sequence and the subjectAltName extension |
| 146 // MUST be critical. | 166 // MUST be critical. |
| 147 if (subject_value.Length() == 0 && | 167 if (subject_value.Length() == 0 && |
| 148 !result->subject_alt_names_extension_.critical) { | 168 !result->subject_alt_names_extension_.critical) { |
| 149 return nullptr; | 169 return nullptr; |
| 150 } | 170 } |
| 151 } | 171 } |
| 152 | 172 |
| 153 // Name constraints. | 173 // Name constraints. |
| 154 if (ConsumeExtension(NameConstraintsOid(), &result->unparsed_extensions_, | 174 if (result->GetExtension(NameConstraintsOid(), &extension)) { |
| 155 &extension)) { | |
| 156 result->name_constraints_ = | 175 result->name_constraints_ = |
| 157 NameConstraints::Create(extension.value, extension.critical); | 176 NameConstraints::Create(extension.value, extension.critical); |
| 158 if (!result->name_constraints_) | 177 if (!result->name_constraints_) |
| 159 return nullptr; | 178 return nullptr; |
| 160 } | 179 } |
| 161 | 180 |
| 162 // Authority information access. | 181 // Authority information access. |
| 163 if (ConsumeExtension(AuthorityInfoAccessOid(), | 182 if (result->GetExtension(AuthorityInfoAccessOid(), |
| 164 &result->unparsed_extensions_, | 183 &result->authority_info_access_extension_)) { |
| 165 &result->authority_info_access_extension_)) { | |
| 166 result->has_authority_info_access_ = true; | 184 result->has_authority_info_access_ = true; |
| 167 if (!ParseAuthorityInfoAccess( | 185 if (!ParseAuthorityInfoAccess( |
| 168 result->authority_info_access_extension_.value, | 186 result->authority_info_access_extension_.value, |
| 169 &result->ca_issuers_uris_, &result->ocsp_uris_)) | 187 &result->ca_issuers_uris_, &result->ocsp_uris_)) |
| 170 return nullptr; | 188 return nullptr; |
| 171 } | 189 } |
| 172 | 190 |
| 173 // NOTE: if additional extensions are consumed here, the verification code | 191 // Policies. |
| 174 // must be updated to process those extensions, since the | 192 if (result->GetExtension(CertificatePoliciesOid(), &extension)) { |
| 175 // VerifyNoUnconsumedCriticalExtensions uses the unparsed_extensions_ | 193 result->has_policy_oids_ = true; |
| 176 // variable to tell which extensions were processed. | 194 if (!ParseCertificatePoliciesExtension(extension.value, |
| 195 &result->policy_oids_)) { |
| 196 return nullptr; |
| 197 } |
| 198 } |
| 177 } | 199 } |
| 178 | 200 |
| 179 return result; | 201 return result; |
| 180 } | 202 } |
| 181 | 203 |
| 182 } // namespace net | 204 } // namespace net |
| OLD | NEW |