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