1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "parsed_certificate.h"
6
7 #include <openssl/bytestring.h>
8 #include <openssl/pool.h>
9
10 #include "cert_errors.h"
11 #include "certificate_policies.h"
12 #include "extended_key_usage.h"
13 #include "name_constraints.h"
14 #include "parser.h"
15 #include "signature_algorithm.h"
16 #include "verify_name_match.h"
17
18 namespace bssl {
19
20 namespace {
21
22 DEFINE_CERT_ERROR_ID(kFailedParsingCertificate, "Failed parsing Certificate");
23 DEFINE_CERT_ERROR_ID(kFailedParsingTbsCertificate,
24 "Failed parsing TBSCertificate");
25 DEFINE_CERT_ERROR_ID(kFailedReadingIssuerOrSubject,
26 "Failed reading issuer or subject");
27 DEFINE_CERT_ERROR_ID(kFailedNormalizingSubject, "Failed normalizing subject");
28 DEFINE_CERT_ERROR_ID(kFailedNormalizingIssuer, "Failed normalizing issuer");
29 DEFINE_CERT_ERROR_ID(kFailedParsingExtensions, "Failed parsing extensions");
30 DEFINE_CERT_ERROR_ID(kFailedParsingBasicConstraints,
31 "Failed parsing basic constraints");
32 DEFINE_CERT_ERROR_ID(kFailedParsingKeyUsage, "Failed parsing key usage");
33 DEFINE_CERT_ERROR_ID(kFailedParsingEku, "Failed parsing extended key usage");
34 DEFINE_CERT_ERROR_ID(kFailedParsingSubjectAltName,
35 "Failed parsing subjectAltName");
36 DEFINE_CERT_ERROR_ID(kSubjectAltNameNotCritical,
37 "Empty subject and subjectAltName is not critical");
38 DEFINE_CERT_ERROR_ID(kFailedParsingNameConstraints,
39 "Failed parsing name constraints");
40 DEFINE_CERT_ERROR_ID(kFailedParsingAia, "Failed parsing authority info access");
41 DEFINE_CERT_ERROR_ID(kFailedParsingPolicies,
42 "Failed parsing certificate policies");
43 DEFINE_CERT_ERROR_ID(kFailedParsingPolicyConstraints,
44 "Failed parsing policy constraints");
45 DEFINE_CERT_ERROR_ID(kFailedParsingPolicyMappings,
46 "Failed parsing policy mappings");
47 DEFINE_CERT_ERROR_ID(kFailedParsingInhibitAnyPolicy,
48 "Failed parsing inhibit any policy");
49 DEFINE_CERT_ERROR_ID(kFailedParsingAuthorityKeyIdentifier,
50 "Failed parsing authority key identifier");
51 DEFINE_CERT_ERROR_ID(kFailedParsingSubjectKeyIdentifier,
52 "Failed parsing subject key identifier");
53
GetSequenceValue(der::Input tlv,der::Input * value)54 [[nodiscard]] bool GetSequenceValue(der::Input tlv, der::Input *value) {
55 der::Parser parser(tlv);
56 return parser.ReadTag(CBS_ASN1_SEQUENCE, value) && !parser.HasMore();
57 }
58
59 } // namespace
60
GetExtension(der::Input extension_oid,ParsedExtension * parsed_extension) const61 bool ParsedCertificate::GetExtension(der::Input extension_oid,
62 ParsedExtension *parsed_extension) const {
63 if (!tbs_.extensions_tlv) {
64 return false;
65 }
66
67 auto it = extensions_.find(extension_oid);
68 if (it == extensions_.end()) {
69 *parsed_extension = ParsedExtension();
70 return false;
71 }
72
73 *parsed_extension = it->second;
74 return true;
75 }
76
ParsedCertificate(PrivateConstructor)77 ParsedCertificate::ParsedCertificate(PrivateConstructor) {}
78 ParsedCertificate::~ParsedCertificate() = default;
79
80 // static
Create(bssl::UniquePtr<CRYPTO_BUFFER> backing_data,const ParseCertificateOptions & options,CertErrors * errors)81 std::shared_ptr<const ParsedCertificate> ParsedCertificate::Create(
82 bssl::UniquePtr<CRYPTO_BUFFER> backing_data,
83 const ParseCertificateOptions &options, CertErrors *errors) {
84 // |errors| is an optional parameter, but to keep the code simpler, use a
85 // dummy object when one wasn't provided.
86 CertErrors unused_errors;
87 if (!errors) {
88 errors = &unused_errors;
89 }
90
91 auto result = std::make_shared<ParsedCertificate>(PrivateConstructor{});
92 result->cert_data_ = std::move(backing_data);
93 result->cert_ = der::Input(CRYPTO_BUFFER_data(result->cert_data_.get()),
94 CRYPTO_BUFFER_len(result->cert_data_.get()));
95
96 if (!ParseCertificate(result->cert_, &result->tbs_certificate_tlv_,
97 &result->signature_algorithm_tlv_,
98 &result->signature_value_, errors)) {
99 errors->AddError(kFailedParsingCertificate);
100 return nullptr;
101 }
102
103 if (!ParseTbsCertificate(result->tbs_certificate_tlv_, options, &result->tbs_,
104 errors)) {
105 errors->AddError(kFailedParsingTbsCertificate);
106 return nullptr;
107 }
108
109 // Attempt to parse the signature algorithm contained in the Certificate.
110 result->signature_algorithm_ =
111 ParseSignatureAlgorithm(result->signature_algorithm_tlv_);
112
113 der::Input subject_value;
114 if (!GetSequenceValue(result->tbs_.subject_tlv, &subject_value)) {
115 errors->AddError(kFailedReadingIssuerOrSubject);
116 return nullptr;
117 }
118 if (!NormalizeName(subject_value, &result->normalized_subject_, errors)) {
119 errors->AddError(kFailedNormalizingSubject);
120 return nullptr;
121 }
122 der::Input issuer_value;
123 if (!GetSequenceValue(result->tbs_.issuer_tlv, &issuer_value)) {
124 errors->AddError(kFailedReadingIssuerOrSubject);
125 return nullptr;
126 }
127 if (!NormalizeName(issuer_value, &result->normalized_issuer_, errors)) {
128 errors->AddError(kFailedNormalizingIssuer);
129 return nullptr;
130 }
131
132 // Parse the standard X.509 extensions.
133 if (result->tbs_.extensions_tlv) {
134 // ParseExtensions() ensures there are no duplicates, and maps the (unique)
135 // OID to the extension value.
136 if (!ParseExtensions(result->tbs_.extensions_tlv.value(),
137 &result->extensions_)) {
138 errors->AddError(kFailedParsingExtensions);
139 return nullptr;
140 }
141
142 ParsedExtension extension;
143
144 // Basic constraints.
145 if (result->GetExtension(der::Input(kBasicConstraintsOid), &extension)) {
146 result->has_basic_constraints_ = true;
147 if (!ParseBasicConstraints(extension.value,
148 &result->basic_constraints_)) {
149 errors->AddError(kFailedParsingBasicConstraints);
150 return nullptr;
151 }
152 }
153
154 // Key Usage.
155 if (result->GetExtension(der::Input(kKeyUsageOid), &extension)) {
156 result->has_key_usage_ = true;
157 if (!ParseKeyUsage(extension.value, &result->key_usage_)) {
158 errors->AddError(kFailedParsingKeyUsage);
159 return nullptr;
160 }
161 }
162
163 // Extended Key Usage.
164 if (result->GetExtension(der::Input(kExtKeyUsageOid), &extension)) {
165 result->has_extended_key_usage_ = true;
166 if (!ParseEKUExtension(extension.value, &result->extended_key_usage_)) {
167 errors->AddError(kFailedParsingEku);
168 return nullptr;
169 }
170 }
171
172 // Subject alternative name.
173 if (result->GetExtension(der::Input(kSubjectAltNameOid),
174 &result->subject_alt_names_extension_)) {
175 // RFC 5280 section 4.2.1.6:
176 // SubjectAltName ::= GeneralNames
177 result->subject_alt_names_ = GeneralNames::Create(
178 result->subject_alt_names_extension_.value, errors);
179 if (!result->subject_alt_names_) {
180 errors->AddError(kFailedParsingSubjectAltName);
181 return nullptr;
182 }
183 // RFC 5280 section 4.1.2.6:
184 // If subject naming information is present only in the subjectAltName
185 // extension (e.g., a key bound only to an email address or URI), then the
186 // subject name MUST be an empty sequence and the subjectAltName extension
187 // MUST be critical.
188 if (subject_value.empty() &&
189 !result->subject_alt_names_extension_.critical) {
190 errors->AddError(kSubjectAltNameNotCritical);
191 return nullptr;
192 }
193 }
194
195 // Name constraints.
196 if (result->GetExtension(der::Input(kNameConstraintsOid), &extension)) {
197 result->name_constraints_ =
198 NameConstraints::Create(extension.value, extension.critical, errors);
199 if (!result->name_constraints_) {
200 errors->AddError(kFailedParsingNameConstraints);
201 return nullptr;
202 }
203 }
204
205 // Authority information access.
206 if (result->GetExtension(der::Input(kAuthorityInfoAccessOid),
207 &result->authority_info_access_extension_)) {
208 result->has_authority_info_access_ = true;
209 if (!ParseAuthorityInfoAccessURIs(
210 result->authority_info_access_extension_.value,
211 &result->ca_issuers_uris_, &result->ocsp_uris_)) {
212 errors->AddError(kFailedParsingAia);
213 return nullptr;
214 }
215 }
216
217 // Policies.
218 if (result->GetExtension(der::Input(kCertificatePoliciesOid), &extension)) {
219 result->has_policy_oids_ = true;
220 if (!ParseCertificatePoliciesExtensionOids(
221 extension.value, false /*fail_parsing_unknown_qualifier_oids*/,
222 &result->policy_oids_, errors)) {
223 errors->AddError(kFailedParsingPolicies);
224 return nullptr;
225 }
226 }
227
228 // Policy constraints.
229 if (result->GetExtension(der::Input(kPolicyConstraintsOid), &extension)) {
230 result->has_policy_constraints_ = true;
231 if (!ParsePolicyConstraints(extension.value,
232 &result->policy_constraints_)) {
233 errors->AddError(kFailedParsingPolicyConstraints);
234 return nullptr;
235 }
236 }
237
238 // Policy mappings.
239 if (result->GetExtension(der::Input(kPolicyMappingsOid), &extension)) {
240 result->has_policy_mappings_ = true;
241 if (!ParsePolicyMappings(extension.value, &result->policy_mappings_)) {
242 errors->AddError(kFailedParsingPolicyMappings);
243 return nullptr;
244 }
245 }
246
247 // Inhibit Any Policy.
248 if (result->GetExtension(der::Input(kInhibitAnyPolicyOid), &extension)) {
249 result->inhibit_any_policy_ = ParseInhibitAnyPolicy(extension.value);
250 if (!result->inhibit_any_policy_) {
251 errors->AddError(kFailedParsingInhibitAnyPolicy);
252 return nullptr;
253 }
254 }
255
256 // Subject Key Identifier.
257 if (result->GetExtension(der::Input(kSubjectKeyIdentifierOid),
258 &extension)) {
259 result->subject_key_identifier_ = std::make_optional<der::Input>();
260 if (!ParseSubjectKeyIdentifier(
261 extension.value, &result->subject_key_identifier_.value())) {
262 errors->AddError(kFailedParsingSubjectKeyIdentifier);
263 return nullptr;
264 }
265 }
266
267 // Authority Key Identifier.
268 if (result->GetExtension(der::Input(kAuthorityKeyIdentifierOid),
269 &extension)) {
270 result->authority_key_identifier_ =
271 std::make_optional<ParsedAuthorityKeyIdentifier>();
272 if (!ParseAuthorityKeyIdentifier(
273 extension.value, &result->authority_key_identifier_.value())) {
274 errors->AddError(kFailedParsingAuthorityKeyIdentifier);
275 return nullptr;
276 }
277 }
278 }
279
280 return result;
281 }
282
283 // static
CreateAndAddToVector(bssl::UniquePtr<CRYPTO_BUFFER> cert_data,const ParseCertificateOptions & options,std::vector<std::shared_ptr<const bssl::ParsedCertificate>> * chain,CertErrors * errors)284 bool ParsedCertificate::CreateAndAddToVector(
285 bssl::UniquePtr<CRYPTO_BUFFER> cert_data,
286 const ParseCertificateOptions &options,
287 std::vector<std::shared_ptr<const bssl::ParsedCertificate>> *chain,
288 CertErrors *errors) {
289 std::shared_ptr<const ParsedCertificate> cert(
290 Create(std::move(cert_data), options, errors));
291 if (!cert) {
292 return false;
293 }
294 chain->push_back(std::move(cert));
295 return true;
296 }
297
298 } // namespace bssl
299