xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/certificate_policies.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 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 <algorithm>
6 
7 #include "certificate_policies.h"
8 
9 #include <openssl/base.h>
10 #include "cert_error_params.h"
11 #include "cert_errors.h"
12 #include "input.h"
13 #include "parse_values.h"
14 #include "parser.h"
15 
16 namespace bssl {
17 
18 namespace {
19 
20 // ---------------------------------------------------------------
21 // Errors
22 // ---------------------------------------------------------------
23 
24 DEFINE_CERT_ERROR_ID(kPolicyQualifiersEmptySequence,
25                      "The policy qualifiers SEQUENCE is empty");
26 DEFINE_CERT_ERROR_ID(kUnknownPolicyQualifierOid,
27                      "Unknown policy qualifier OID (not CPS or User Notice)");
28 DEFINE_CERT_ERROR_ID(kPoliciesEmptySequence, "Policies is an empty SEQUENCE");
29 DEFINE_CERT_ERROR_ID(kPoliciesDuplicateOid, "Policies contains duplicate OIDs");
30 DEFINE_CERT_ERROR_ID(kPolicyInformationTrailingData,
31                      "PolicyInformation has trailing data");
32 DEFINE_CERT_ERROR_ID(kFailedParsingPolicyQualifiers,
33                      "Failed parsing policy qualifiers");
34 DEFINE_CERT_ERROR_ID(kMissingQualifier,
35                      "PolicyQualifierInfo is missing qualifier");
36 DEFINE_CERT_ERROR_ID(kPolicyQualifierInfoTrailingData,
37                      "PolicyQualifierInfo has trailing data");
38 
39 // Minimally parse policyQualifiers, storing in |policy_qualifiers| if non-null.
40 // If a policy qualifier other than User Notice/CPS is present, parsing
41 // will fail if |restrict_to_known_qualifiers| was set to true.
ParsePolicyQualifiers(bool restrict_to_known_qualifiers,der::Parser * policy_qualifiers_sequence_parser,std::vector<PolicyQualifierInfo> * policy_qualifiers,CertErrors * errors)42 bool ParsePolicyQualifiers(bool restrict_to_known_qualifiers,
43                            der::Parser *policy_qualifiers_sequence_parser,
44                            std::vector<PolicyQualifierInfo> *policy_qualifiers,
45                            CertErrors *errors) {
46   BSSL_CHECK(errors);
47 
48   // If it is present, the policyQualifiers sequence should have at least 1
49   // element.
50   //
51   //      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
52   //                              PolicyQualifierInfo OPTIONAL }
53   if (!policy_qualifiers_sequence_parser->HasMore()) {
54     errors->AddError(kPolicyQualifiersEmptySequence);
55     return false;
56   }
57   while (policy_qualifiers_sequence_parser->HasMore()) {
58     // PolicyQualifierInfo ::= SEQUENCE {
59     der::Parser policy_information_parser;
60     if (!policy_qualifiers_sequence_parser->ReadSequence(
61             &policy_information_parser)) {
62       return false;
63     }
64     //      policyQualifierId  PolicyQualifierId,
65     der::Input qualifier_oid;
66     if (!policy_information_parser.ReadTag(CBS_ASN1_OBJECT, &qualifier_oid)) {
67       return false;
68     }
69     if (restrict_to_known_qualifiers &&
70         qualifier_oid != der::Input(kCpsPointerId) &&
71         qualifier_oid != der::Input(kUserNoticeId)) {
72       errors->AddError(kUnknownPolicyQualifierOid,
73                        CreateCertErrorParams1Der("oid", qualifier_oid));
74       return false;
75     }
76     //      qualifier          ANY DEFINED BY policyQualifierId }
77     der::Input qualifier_tlv;
78     if (!policy_information_parser.ReadRawTLV(&qualifier_tlv)) {
79       errors->AddError(kMissingQualifier);
80       return false;
81     }
82     // Should not have trailing data after qualifier.
83     if (policy_information_parser.HasMore()) {
84       errors->AddError(kPolicyQualifierInfoTrailingData);
85       return false;
86     }
87 
88     if (policy_qualifiers) {
89       policy_qualifiers->push_back({qualifier_oid, qualifier_tlv});
90     }
91   }
92   return true;
93 }
94 
95 // RFC 5280 section 4.2.1.4.  Certificate Policies:
96 //
97 // certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
98 //
99 // PolicyInformation ::= SEQUENCE {
100 //      policyIdentifier   CertPolicyId,
101 //      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
102 //                              PolicyQualifierInfo OPTIONAL }
103 //
104 // CertPolicyId ::= OBJECT IDENTIFIER
105 //
106 // PolicyQualifierInfo ::= SEQUENCE {
107 //      policyQualifierId  PolicyQualifierId,
108 //      qualifier          ANY DEFINED BY policyQualifierId }
109 //
110 // PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
111 //
112 // Qualifier ::= CHOICE {
113 //      cPSuri           CPSuri,
114 //      userNotice       UserNotice }
115 //
116 // CPSuri ::= IA5String
117 //
118 // UserNotice ::= SEQUENCE {
119 //      noticeRef        NoticeReference OPTIONAL,
120 //      explicitText     DisplayText OPTIONAL }
121 //
122 // NoticeReference ::= SEQUENCE {
123 //      organization     DisplayText,
124 //      noticeNumbers    SEQUENCE OF INTEGER }
125 //
126 // DisplayText ::= CHOICE {
127 //      ia5String        IA5String      (SIZE (1..200)),
128 //      visibleString    VisibleString  (SIZE (1..200)),
129 //      bmpString        BMPString      (SIZE (1..200)),
130 //      utf8String       UTF8String     (SIZE (1..200)) }
ParseCertificatePoliciesExtensionImpl(der::Input extension_value,bool fail_parsing_unknown_qualifier_oids,std::vector<der::Input> * policy_oids,std::vector<PolicyInformation> * policy_informations,CertErrors * errors)131 bool ParseCertificatePoliciesExtensionImpl(
132     der::Input extension_value, bool fail_parsing_unknown_qualifier_oids,
133     std::vector<der::Input> *policy_oids,
134     std::vector<PolicyInformation> *policy_informations, CertErrors *errors) {
135   BSSL_CHECK(policy_oids);
136   BSSL_CHECK(errors);
137   // certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
138   der::Parser extension_parser(extension_value);
139   der::Parser policies_sequence_parser;
140   if (!extension_parser.ReadSequence(&policies_sequence_parser)) {
141     return false;
142   }
143   // Should not have trailing data after certificatePolicies sequence.
144   if (extension_parser.HasMore()) {
145     return false;
146   }
147   // The certificatePolicies sequence should have at least 1 element.
148   if (!policies_sequence_parser.HasMore()) {
149     errors->AddError(kPoliciesEmptySequence);
150     return false;
151   }
152 
153   policy_oids->clear();
154   if (policy_informations) {
155     policy_informations->clear();
156   }
157 
158   while (policies_sequence_parser.HasMore()) {
159     // PolicyInformation ::= SEQUENCE {
160     der::Parser policy_information_parser;
161     if (!policies_sequence_parser.ReadSequence(&policy_information_parser)) {
162       return false;
163     }
164     //      policyIdentifier   CertPolicyId,
165     der::Input policy_oid;
166     if (!policy_information_parser.ReadTag(CBS_ASN1_OBJECT, &policy_oid)) {
167       return false;
168     }
169 
170     policy_oids->push_back(policy_oid);
171 
172     std::vector<PolicyQualifierInfo> *policy_qualifiers = nullptr;
173     if (policy_informations) {
174       policy_informations->emplace_back();
175       policy_informations->back().policy_oid = policy_oid;
176       policy_qualifiers = &policy_informations->back().policy_qualifiers;
177     }
178 
179     if (!policy_information_parser.HasMore()) {
180       continue;
181     }
182 
183     //      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
184     //                              PolicyQualifierInfo OPTIONAL }
185     der::Parser policy_qualifiers_sequence_parser;
186     if (!policy_information_parser.ReadSequence(
187             &policy_qualifiers_sequence_parser)) {
188       return false;
189     }
190     // Should not have trailing data after policyQualifiers sequence.
191     if (policy_information_parser.HasMore()) {
192       errors->AddError(kPolicyInformationTrailingData);
193       return false;
194     }
195 
196     // RFC 5280 section 4.2.1.4: When qualifiers are used with the special
197     // policy anyPolicy, they MUST be limited to the qualifiers identified in
198     // this section.
199     if (!ParsePolicyQualifiers(fail_parsing_unknown_qualifier_oids ||
200                                    policy_oid == der::Input(kAnyPolicyOid),
201                                &policy_qualifiers_sequence_parser,
202                                policy_qualifiers, errors)) {
203       errors->AddError(kFailedParsingPolicyQualifiers);
204       return false;
205     }
206   }
207 
208   // RFC 5280 section 4.2.1.4: A certificate policy OID MUST NOT appear more
209   // than once in a certificate policies extension.
210   std::sort(policy_oids->begin(), policy_oids->end());
211   auto dupe_policy_iter =
212       std::adjacent_find(policy_oids->begin(), policy_oids->end());
213   if (dupe_policy_iter != policy_oids->end()) {
214     errors->AddError(kPoliciesDuplicateOid,
215                      CreateCertErrorParams1Der("oid", *dupe_policy_iter));
216     return false;
217   }
218 
219   return true;
220 }
221 
222 }  // namespace
223 
224 PolicyInformation::PolicyInformation() = default;
225 PolicyInformation::~PolicyInformation() = default;
226 PolicyInformation::PolicyInformation(const PolicyInformation &) = default;
227 PolicyInformation::PolicyInformation(PolicyInformation &&) = default;
228 
ParseCertificatePoliciesExtension(der::Input extension_value,std::vector<PolicyInformation> * policies,CertErrors * errors)229 bool ParseCertificatePoliciesExtension(der::Input extension_value,
230                                        std::vector<PolicyInformation> *policies,
231                                        CertErrors *errors) {
232   std::vector<der::Input> unused_policy_oids;
233   return ParseCertificatePoliciesExtensionImpl(
234       extension_value, /*fail_parsing_unknown_qualifier_oids=*/false,
235       &unused_policy_oids, policies, errors);
236 }
237 
ParseCertificatePoliciesExtensionOids(der::Input extension_value,bool fail_parsing_unknown_qualifier_oids,std::vector<der::Input> * policy_oids,CertErrors * errors)238 bool ParseCertificatePoliciesExtensionOids(
239     der::Input extension_value, bool fail_parsing_unknown_qualifier_oids,
240     std::vector<der::Input> *policy_oids, CertErrors *errors) {
241   return ParseCertificatePoliciesExtensionImpl(
242       extension_value, fail_parsing_unknown_qualifier_oids, policy_oids,
243       nullptr, errors);
244 }
245 
246 // From RFC 5280:
247 //
248 //   PolicyConstraints ::= SEQUENCE {
249 //        requireExplicitPolicy           [0] SkipCerts OPTIONAL,
250 //        inhibitPolicyMapping            [1] SkipCerts OPTIONAL }
251 //
252 //   SkipCerts ::= INTEGER (0..MAX)
ParsePolicyConstraints(der::Input policy_constraints_tlv,ParsedPolicyConstraints * out)253 bool ParsePolicyConstraints(der::Input policy_constraints_tlv,
254                             ParsedPolicyConstraints *out) {
255   der::Parser parser(policy_constraints_tlv);
256 
257   //   PolicyConstraints ::= SEQUENCE {
258   der::Parser sequence_parser;
259   if (!parser.ReadSequence(&sequence_parser)) {
260     return false;
261   }
262 
263   // RFC 5280 prohibits CAs from issuing PolicyConstraints as an empty sequence:
264   //
265   //   Conforming CAs MUST NOT issue certificates where policy constraints
266   //   is an empty sequence.  That is, either the inhibitPolicyMapping field
267   //   or the requireExplicitPolicy field MUST be present.  The behavior of
268   //   clients that encounter an empty policy constraints field is not
269   //   addressed in this profile.
270   if (!sequence_parser.HasMore()) {
271     return false;
272   }
273 
274   std::optional<der::Input> require_value;
275   if (!sequence_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 0,
276                                        &require_value)) {
277     return false;
278   }
279 
280   if (require_value) {
281     uint8_t require_explicit_policy;
282     if (!ParseUint8(require_value.value(), &require_explicit_policy)) {
283       // TODO(eroman): Surface reason for failure if length was longer than
284       // uint8.
285       return false;
286     }
287     out->require_explicit_policy = require_explicit_policy;
288   }
289 
290   std::optional<der::Input> inhibit_value;
291   if (!sequence_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1,
292                                        &inhibit_value)) {
293     return false;
294   }
295 
296   if (inhibit_value) {
297     uint8_t inhibit_policy_mapping;
298     if (!ParseUint8(inhibit_value.value(), &inhibit_policy_mapping)) {
299       // TODO(eroman): Surface reason for failure if length was longer than
300       // uint8.
301       return false;
302     }
303     out->inhibit_policy_mapping = inhibit_policy_mapping;
304   }
305 
306   // There should be no remaining data.
307   if (sequence_parser.HasMore() || parser.HasMore()) {
308     return false;
309   }
310 
311   return true;
312 }
313 
314 // From RFC 5280:
315 //
316 //   InhibitAnyPolicy ::= SkipCerts
317 //
318 //   SkipCerts ::= INTEGER (0..MAX)
ParseInhibitAnyPolicy(der::Input inhibit_any_policy_tlv)319 std::optional<uint8_t> ParseInhibitAnyPolicy(
320     der::Input inhibit_any_policy_tlv) {
321   der::Parser parser(inhibit_any_policy_tlv);
322   std::optional<uint8_t> num_certs = std::make_optional<uint8_t>();
323 
324   // TODO(eroman): Surface reason for failure if length was longer than uint8.
325   if (!parser.ReadUint8(&num_certs.value())) {
326     return std::nullopt;
327   }
328 
329   // There should be no remaining data.
330   if (parser.HasMore()) {
331     return std::nullopt;
332   }
333 
334   return num_certs;
335 }
336 
337 // From RFC 5280:
338 //
339 //   PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
340 //        issuerDomainPolicy      CertPolicyId,
341 //        subjectDomainPolicy     CertPolicyId }
ParsePolicyMappings(der::Input policy_mappings_tlv,std::vector<ParsedPolicyMapping> * mappings)342 bool ParsePolicyMappings(der::Input policy_mappings_tlv,
343                          std::vector<ParsedPolicyMapping> *mappings) {
344   mappings->clear();
345 
346   der::Parser parser(policy_mappings_tlv);
347 
348   //   PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
349   der::Parser sequence_parser;
350   if (!parser.ReadSequence(&sequence_parser)) {
351     return false;
352   }
353 
354   // Must be at least 1 mapping.
355   if (!sequence_parser.HasMore()) {
356     return false;
357   }
358 
359   while (sequence_parser.HasMore()) {
360     der::Parser mapping_parser;
361     if (!sequence_parser.ReadSequence(&mapping_parser)) {
362       return false;
363     }
364 
365     ParsedPolicyMapping mapping;
366     if (!mapping_parser.ReadTag(CBS_ASN1_OBJECT,
367                                 &mapping.issuer_domain_policy)) {
368       return false;
369     }
370     if (!mapping_parser.ReadTag(CBS_ASN1_OBJECT,
371                                 &mapping.subject_domain_policy)) {
372       return false;
373     }
374 
375     // There shouldn't be extra unconsumed data.
376     if (mapping_parser.HasMore()) {
377       return false;
378     }
379 
380     mappings->push_back(mapping);
381   }
382 
383   // There shouldn't be extra unconsumed data.
384   if (parser.HasMore()) {
385     return false;
386   }
387 
388   return true;
389 }
390 
391 }  // namespace bssl
392