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