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