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