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