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