xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/parsed_certificate.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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