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 "verify_certificate_chain.h"
6
7 #include <algorithm>
8 #include <cassert>
9
10 #include "cert_error_params.h"
11 #include "cert_errors.h"
12 #include "common_cert_errors.h"
13 #include "extended_key_usage.h"
14 #include "name_constraints.h"
15 #include "parse_certificate.h"
16 #include "signature_algorithm.h"
17 #include "trust_store.h"
18 #include "verify_signed_data.h"
19 #include "input.h"
20 #include <openssl/base.h>
21
22 namespace bssl {
23
24 namespace {
25
IsHandledCriticalExtension(const ParsedExtension & extension,const ParsedCertificate & cert)26 bool IsHandledCriticalExtension(const ParsedExtension& extension,
27 const ParsedCertificate& cert) {
28 if (extension.oid == der::Input(kBasicConstraintsOid))
29 return true;
30 // Key Usage is NOT processed for end-entity certificates (this is the
31 // responsibility of callers), however it is considered "handled" here in
32 // order to allow being marked as critical.
33 if (extension.oid == der::Input(kKeyUsageOid))
34 return true;
35 if (extension.oid == der::Input(kExtKeyUsageOid))
36 return true;
37 if (extension.oid == der::Input(kNameConstraintsOid))
38 return true;
39 if (extension.oid == der::Input(kSubjectAltNameOid))
40 return true;
41 if (extension.oid == der::Input(kCertificatePoliciesOid)) {
42 // Policy qualifiers are skipped during processing, so if the
43 // extension is marked critical need to ensure there weren't any
44 // qualifiers other than User Notice / CPS.
45 //
46 // This follows from RFC 5280 section 4.2.1.4:
47 //
48 // If this extension is critical, the path validation software MUST
49 // be able to interpret this extension (including the optional
50 // qualifier), or MUST reject the certificate.
51 std::vector<der::Input> unused_policies;
52 CertErrors unused_errors;
53 return ParseCertificatePoliciesExtensionOids(
54 extension.value, true /*fail_parsing_unknown_qualifier_oids*/,
55 &unused_policies, &unused_errors);
56
57 // TODO(eroman): Give a better error message.
58 }
59 if (extension.oid == der::Input(kPolicyMappingsOid))
60 return true;
61 if (extension.oid == der::Input(kPolicyConstraintsOid))
62 return true;
63 if (extension.oid == der::Input(kInhibitAnyPolicyOid))
64 return true;
65 if (extension.oid == der::Input(kMSApplicationPoliciesOid)) {
66 // Per https://crbug.com/1439638 and
67 // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/supported-extensions#msapplicationpolicies
68 // The MSApplicationPolicies extension may be ignored if the
69 // extendedKeyUsage extension is also present.
70 return cert.has_extended_key_usage();
71 }
72
73 return false;
74 }
75
76 // Adds errors to |errors| if the certificate contains unconsumed _critical_
77 // extensions.
VerifyNoUnconsumedCriticalExtensions(const ParsedCertificate & cert,CertErrors * errors)78 void VerifyNoUnconsumedCriticalExtensions(const ParsedCertificate& cert,
79 CertErrors* errors) {
80 for (const auto& it : cert.extensions()) {
81 const ParsedExtension& extension = it.second;
82 if (extension.critical && !IsHandledCriticalExtension(extension, cert)) {
83 errors->AddError(cert_errors::kUnconsumedCriticalExtension,
84 CreateCertErrorParams2Der("oid", extension.oid, "value",
85 extension.value));
86 }
87 }
88 }
89
90 // Returns true if |cert| was self-issued. The definition of self-issuance
91 // comes from RFC 5280 section 6.1:
92 //
93 // A certificate is self-issued if the same DN appears in the subject
94 // and issuer fields (the two DNs are the same if they match according
95 // to the rules specified in Section 7.1). In general, the issuer and
96 // subject of the certificates that make up a path are different for
97 // each certificate. However, a CA may issue a certificate to itself to
98 // support key rollover or changes in certificate policies. These
99 // self-issued certificates are not counted when evaluating path length
100 // or name constraints.
IsSelfIssued(const ParsedCertificate & cert)101 [[nodiscard]] bool IsSelfIssued(const ParsedCertificate& cert) {
102 return cert.normalized_subject() == cert.normalized_issuer();
103 }
104
105 // Adds errors to |errors| if |cert| is not valid at time |time|.
106 //
107 // The certificate's validity requirements are described by RFC 5280 section
108 // 4.1.2.5:
109 //
110 // The validity period for a certificate is the period of time from
111 // notBefore through notAfter, inclusive.
VerifyTimeValidity(const ParsedCertificate & cert,const der::GeneralizedTime & time,CertErrors * errors)112 void VerifyTimeValidity(const ParsedCertificate& cert,
113 const der::GeneralizedTime& time,
114 CertErrors* errors) {
115 if (time < cert.tbs().validity_not_before)
116 errors->AddError(cert_errors::kValidityFailedNotBefore);
117
118 if (cert.tbs().validity_not_after < time)
119 errors->AddError(cert_errors::kValidityFailedNotAfter);
120 }
121
122 // Adds errors to |errors| if |cert| has internally inconsistent signature
123 // algorithms.
124 //
125 // X.509 certificates contain two different signature algorithms:
126 // (1) The signatureAlgorithm field of Certificate
127 // (2) The signature field of TBSCertificate
128 //
129 // According to RFC 5280 section 4.1.1.2 and 4.1.2.3 these two fields must be
130 // equal:
131 //
132 // This field MUST contain the same algorithm identifier as the
133 // signature field in the sequence tbsCertificate (Section 4.1.2.3).
134 //
135 // The spec is not explicit about what "the same algorithm identifier" means.
136 // Our interpretation is that the two DER-encoded fields must be byte-for-byte
137 // identical.
138 //
139 // In practice however there are certificates which use different encodings for
140 // specifying RSA with SHA1 (different OIDs). This is special-cased for
141 // compatibility sake.
VerifySignatureAlgorithmsMatch(const ParsedCertificate & cert,CertErrors * errors)142 bool VerifySignatureAlgorithmsMatch(const ParsedCertificate& cert,
143 CertErrors* errors) {
144 const der::Input& alg1_tlv = cert.signature_algorithm_tlv();
145 const der::Input& alg2_tlv = cert.tbs().signature_algorithm_tlv;
146
147 // Ensure that the two DER-encoded signature algorithms are byte-for-byte
148 // equal.
149 if (alg1_tlv == alg2_tlv)
150 return true;
151
152 // But make a compatibility concession if alternate encodings are used
153 // TODO(eroman): Turn this warning into an error.
154 // TODO(eroman): Add a unit-test that exercises this case.
155 std::optional<SignatureAlgorithm> alg1 = ParseSignatureAlgorithm(alg1_tlv);
156 if (!alg1) {
157 errors->AddError(cert_errors::kUnacceptableSignatureAlgorithm);
158 return false;
159 }
160 std::optional<SignatureAlgorithm> alg2 = ParseSignatureAlgorithm(alg2_tlv);
161 if (!alg2) {
162 errors->AddError(cert_errors::kUnacceptableSignatureAlgorithm);
163 return false;
164 }
165
166 if (*alg1 == *alg2) {
167 errors->AddWarning(
168 cert_errors::kSignatureAlgorithmsDifferentEncoding,
169 CreateCertErrorParams2Der("Certificate.algorithm", alg1_tlv,
170 "TBSCertificate.signature", alg2_tlv));
171 return true;
172 }
173
174 errors->AddError(
175 cert_errors::kSignatureAlgorithmMismatch,
176 CreateCertErrorParams2Der("Certificate.algorithm", alg1_tlv,
177 "TBSCertificate.signature", alg2_tlv));
178 return false;
179 }
180
181 // Verify that |cert| can be used for |required_key_purpose|.
VerifyExtendedKeyUsage(const ParsedCertificate & cert,KeyPurpose required_key_purpose,CertErrors * errors,bool is_target_cert,bool is_target_cert_issuer)182 void VerifyExtendedKeyUsage(const ParsedCertificate& cert,
183 KeyPurpose required_key_purpose,
184 CertErrors* errors,
185 bool is_target_cert,
186 bool is_target_cert_issuer) {
187 // We treat a required KeyPurpose of ANY_EKU to mean "Do not check EKU"
188 if (required_key_purpose == KeyPurpose::ANY_EKU) {
189 return;
190 }
191 bool has_any_eku = false;
192 bool has_server_auth_eku = false;
193 bool has_client_auth_eku = false;
194 bool has_code_signing_eku = false;
195 bool has_time_stamping_eku = false;
196 bool has_ocsp_signing_eku = false;
197 bool has_nsgc = false;
198 if (cert.has_extended_key_usage()) {
199 for (const auto& key_purpose_oid : cert.extended_key_usage()) {
200 if (key_purpose_oid == der::Input(kAnyEKU)) {
201 has_any_eku = true;
202 }
203 if (key_purpose_oid == der::Input(kServerAuth)) {
204 has_server_auth_eku = true;
205 }
206 if (key_purpose_oid == der::Input(kClientAuth)) {
207 has_client_auth_eku = true;
208 }
209 if (key_purpose_oid == der::Input(kCodeSigning)) {
210 has_code_signing_eku = true;
211 }
212 if (key_purpose_oid == der::Input(kTimeStamping)) {
213 has_time_stamping_eku = true;
214 }
215 if (key_purpose_oid == der::Input(kOCSPSigning)) {
216 has_ocsp_signing_eku = true;
217 }
218 if (key_purpose_oid == der::Input(kNetscapeServerGatedCrypto)) {
219 has_nsgc = true;
220 }
221 }
222 }
223
224 auto add_error_if_strict = [&](CertErrorId id) {
225 if (required_key_purpose == KeyPurpose::SERVER_AUTH_STRICT ||
226 required_key_purpose == KeyPurpose::CLIENT_AUTH_STRICT) {
227 errors->AddError(id);
228 } else {
229 errors->AddWarning(id);
230 }
231 };
232 if (is_target_cert) {
233 // Loosely based upon CABF BR version 1.8.4, 7.1.2.3(f). We are more
234 // permissive in that we still allow EKU any to be present in a leaf
235 // certificate, but we ignore it for purposes of server or client auth. We
236 // are less permissive in that we prohibit Code Signing, OCSP Signing, and
237 // Time Stamping which are currently only a SHOULD NOT. The BR does
238 // explicitly allow Email authentication to be present, as this still exists
239 // in the wild (2022), so we do not prohibit Email authentication here (and
240 // by extension must allow it to be present in the signer, below).
241 if (!cert.has_extended_key_usage()) {
242 // This is added as a warning, an error will be added in STRICT modes
243 // if we then lack client or server auth due to this not being present.
244 errors->AddWarning(cert_errors::kEkuNotPresent);
245 } else {
246 if (has_code_signing_eku) {
247 add_error_if_strict(cert_errors::kEkuHasProhibitedCodeSigning);
248 }
249 if (has_ocsp_signing_eku) {
250 add_error_if_strict(cert_errors::kEkuHasProhibitedOCSPSigning);
251 }
252 if (has_time_stamping_eku) {
253 add_error_if_strict(cert_errors::kEkuHasProhibitedTimeStamping);
254 }
255 }
256 } else if (is_target_cert_issuer) {
257 // Handle the decision to overload EKU as a constraint on issuers.
258 //
259 // CABF BR version 1.8.4, 7.1.2.2(g) pertains to the case of "Certs used to
260 // issue TLS certificates", While the BR refers to the entire chain of
261 // intermediates, there are a number of exceptions regarding CA ownership
262 // and cross signing which are impossible for us to know or enforce here.
263 // Therefore, we can only enforce at the level of the intermediate that
264 // issued our target certificate. This means we we differ in the following
265 // ways:
266 // - We only enforce at the issuer of the TLS certificate.
267 // - We allow email protection to exist in the issuer, since without
268 // this it can not be allowed in the client (other than via EKU any))
269 // - As in the leaf certificate case, we allow EKU any to be present, but
270 // we ignore it for the purposes of server or client auth.
271 //
272 // At this time (until at least 2023) some intermediates are lacking EKU in
273 // the world at large from common CA's, so we allow the noEKU case to permit
274 // everything.
275 // TODO(bbe): enforce requiring EKU in the issuer when we can manage it.
276 if (cert.has_extended_key_usage()) {
277 if (has_code_signing_eku) {
278 add_error_if_strict(cert_errors::kEkuHasProhibitedCodeSigning);
279 }
280 if (has_time_stamping_eku) {
281 add_error_if_strict(cert_errors::kEkuHasProhibitedTimeStamping);
282 }
283 }
284 }
285 // Otherwise, we are a parent of an issuer of a TLS certificate. The CABF
286 // BR version 1.8.4, 7.1.2.2(g) goes as far as permitting EKU any in certain
287 // cases of Cross Signing and CA Ownership, having permitted cases where EKU
288 // is permitted to not be present at all. These cases are not practical to
289 // differentiate here and therefore we don't attempt to enforce any further
290 // EKU "constraints" on such certificates. Unlike the above cases we also
291 // allow the use of EKU any for client or server auth constraint purposes.
292
293 switch (required_key_purpose) {
294 case KeyPurpose::ANY_EKU:
295 assert(0); // NOTREACHED
296 return;
297 case KeyPurpose::SERVER_AUTH:
298 case KeyPurpose::SERVER_AUTH_STRICT: {
299 bool nsgc_hack = false;
300 if (has_any_eku && !has_server_auth_eku) {
301 if (is_target_cert || is_target_cert_issuer) {
302 errors->AddWarning(cert_errors::kEkuLacksServerAuthButHasAnyEKU);
303 } else {
304 // Accept anyEKU for server auth below target issuer.
305 has_server_auth_eku = true;
306 }
307 }
308 if (is_target_cert_issuer && !cert.has_extended_key_usage()) {
309 // Accept noEKU for server auth in target issuer.
310 // TODO(bbe): remove this once BR requirements catch up with CA's.
311 has_server_auth_eku = true;
312 }
313 if (has_nsgc && !has_server_auth_eku) {
314 errors->AddWarning(cert_errors::kEkuLacksServerAuthButHasGatedCrypto);
315
316 // Allow NSGC for legacy RSA SHA1 intermediates, for compatibility
317 // with platform verifiers.
318 //
319 // In practice the chain will be rejected with or without this
320 // compatibility hack. The difference is whether the final error will
321 // be ERR_CERT_WEAK_SIGNATURE_ALGORITHM (with compatibility hack) vs
322 // ERR_CERT_INVALID (without hack).
323 //
324 // TODO(https://crbug.com/843735): Remove this once error-for-error
325 // equivalence between builtin verifier and platform verifier is less
326 // important.
327 if ((cert.has_basic_constraints() && cert.basic_constraints().is_ca) &&
328 cert.signature_algorithm() == SignatureAlgorithm::kRsaPkcs1Sha1) {
329 nsgc_hack = true;
330 }
331 }
332 if (required_key_purpose == KeyPurpose::SERVER_AUTH) {
333 // Legacy compatible.
334 if (cert.has_extended_key_usage() && !has_server_auth_eku &&
335 !has_any_eku && !nsgc_hack) {
336 errors->AddError(cert_errors::kEkuLacksServerAuth);
337 }
338 } else {
339 if (!has_server_auth_eku) {
340 errors->AddError(cert_errors::kEkuLacksServerAuth);
341 }
342 }
343 break;
344 }
345 case KeyPurpose::CLIENT_AUTH:
346 case KeyPurpose::CLIENT_AUTH_STRICT: {
347 if (has_any_eku && !has_client_auth_eku) {
348 if (is_target_cert || is_target_cert_issuer) {
349 errors->AddWarning(cert_errors::kEkuLacksClientAuthButHasAnyEKU);
350 } else {
351 // accept anyEKU for client auth.
352 has_client_auth_eku = true;
353 }
354 }
355 if (required_key_purpose == KeyPurpose::CLIENT_AUTH) {
356 // Legacy-compatible.
357 if (cert.has_extended_key_usage() && !has_client_auth_eku &&
358 !has_any_eku) {
359 errors->AddError(cert_errors::kEkuLacksClientAuth);
360 }
361 } else {
362 if (!has_client_auth_eku) {
363 errors->AddError(cert_errors::kEkuLacksClientAuth);
364 }
365 }
366 break;
367 }
368 }
369 }
370
371 // Representation of RFC 5280's "valid_policy_tree", used to keep track of the
372 // valid policies and policy re-mappings. This structure is defined in
373 // section 6.1.2.
374 //
375 // ValidPolicyGraph differs from RFC 5280's description in that:
376 //
377 // (1) It does not track "qualifier_set". This is not needed as it is not
378 // output by this implementation.
379 //
380 // (2) It builds a directed acyclic graph, rather than a tree. When a given
381 // policy matches multiple parents, RFC 5280 makes a separate node for
382 // each parent. This representation condenses them into one node with
383 // multiple parents.
384 //
385 // (3) It does not track "expected_policy_set" or anyPolicy nodes directly.
386 // Rather it maintains, only for the most recent level, whether there is an
387 // anyPolicy node and an inverted map of all "expected_policy_set" values.
388 //
389 // (4) Some pruning steps are deferred to when policies are evaluated, as a
390 // reachability pass.
391 class ValidPolicyGraph {
392 public:
393 ValidPolicyGraph() = default;
394
395 ValidPolicyGraph(const ValidPolicyGraph&) = delete;
396 ValidPolicyGraph& operator=(const ValidPolicyGraph&) = delete;
397
398 // A Node is an entry in the policy graph. It contains information about some
399 // policy asserted by a certificate in the chain. The policy OID itself is
400 // omitted because it is the key in the Level map.
401 struct Node {
402 // The list of "valid_policy" values for all nodes which are a parent of
403 // this node, other than anyPolicy. If empty, this node has a single parent,
404 // anyPolicy.
405 //
406 // Nodes whose parent is anyPolicy are root policies, and may be returned
407 // in the authorities-constrained-policy-set. Nodes with a concrete policy
408 // as a parent are derived from that policy in the issuer certificate,
409 // possibly with a policy mapping applied.
410 //
411 // Note it is not possible for a policy to have both anyPolicy and a
412 // concrete policy as a parent. Section 6.1.3, step d.1.ii only runs if
413 // there was no match in step d.1.i.
414 std::vector<der::Input> parent_policies;
415
416 // Whether this node matches a policy mapping in the certificate. If true,
417 // its "expected_policy_set" comes from the policy mappings extension. If
418 // false, its "expected_policy_set" is itself.
419 bool mapped = false;
420
421 // Whether this node is reachable from some valid policy in the end-entity
422 // certificate. Computed during GetValidRootPolicySet().
423 bool reachable = false;
424 };
425
426 // The policy graph is organized into "levels", each corresponding to a
427 // certificate in the chain. We maintain a map from "valid_policy" to the
428 // corresponding Node. This is the set of policies asserted by this
429 // certificate. The special anyPolicy OID is handled separately below.
430 using Level = std::map<der::Input, Node>;
431
432 // Additional per-level information that only needs to be maintained for the
433 // bottom-most level.
434 struct LevelDetails {
435 // Maintains the "expected_policy_set" values for nodes in a level of the
436 // graph, but the map is inverted from RFC 5280's formulation. For a given
437 // policy OID P, other than anyPolicy, this map gives the set of nodes where
438 // P appears in the node's "expected_policy_set". anyPolicy is handled
439 // separately below.
440 std::map<der::Input, std::vector<der::Input>> expected_policy_map;
441
442 // Whether there is a node at this level whose "valid_policy" is anyPolicy.
443 //
444 // Note anyPolicy's "expected_policy_set" always {anyPolicy}, and anyPolicy
445 // will never appear in the "expected_policy_set" of any other policy. That
446 // means this field also captures how anyPolicy appears in
447 // "expected_policy_set".
448 bool has_any_policy = false;
449 };
450
451 // Initializes the ValidPolicyGraph.
Init()452 void Init() {
453 SetNull();
454 StartLevel();
455 AddAnyPolicyNode();
456 }
457
458 // In RFC 5280 valid_policy_tree may be set to null. That is represented here
459 // by emptiness.
IsNull() const460 bool IsNull() const {
461 return !current_level_.has_any_policy &&
462 (levels_.empty() || levels_.back().empty());
463 }
SetNull()464 void SetNull() {
465 levels_.clear();
466 current_level_ = LevelDetails{};
467 }
468
469 // Completes the previous level, returning a corresponding LevelDetails
470 // structure, and starts a new level.
StartLevel()471 LevelDetails StartLevel() {
472 // Finish building expected_policy_map for the previous level.
473 if (!levels_.empty()) {
474 for (const auto& [policy, node] : levels_.back()) {
475 if (!node.mapped) {
476 current_level_.expected_policy_map[policy].push_back(policy);
477 }
478 }
479 }
480
481 LevelDetails prev_level = std::move(current_level_);
482 levels_.emplace_back();
483 current_level_ = LevelDetails{};
484 return prev_level;
485 }
486
487 // Gets the set of policies (in terms of root authority's policy domain) that
488 // are valid at the bottom level of the policy graph, intersected with
489 // |user_initial_policy_set|. This is what X.509 calls
490 // "user-constrained-policy-set".
491 //
492 // This method may only be called once, after the policy graph is constructed.
GetUserConstrainedPolicySet(const std::set<der::Input> & user_initial_policy_set)493 std::set<der::Input> GetUserConstrainedPolicySet(
494 const std::set<der::Input>& user_initial_policy_set) {
495 if (levels_.empty()) {
496 return {};
497 }
498
499 bool user_has_any_policy =
500 user_initial_policy_set.count(der::Input(kAnyPolicyOid)) != 0;
501 if (current_level_.has_any_policy) {
502 if (user_has_any_policy) {
503 return {der::Input(kAnyPolicyOid)};
504 }
505 return user_initial_policy_set;
506 }
507
508 // The root's policy domain is determined by nodes with anyPolicy as a
509 // parent. However, we must limit to those which are reachable from the
510 // end-entity certificate because we defer some pruning steps.
511 for (auto& [policy, node] : levels_.back()) {
512 // GCC before 8.1 tracks individual unused bindings and does not support
513 // marking them [[maybe_unused]].
514 (void)policy;
515 node.reachable = true;
516 }
517 std::set<der::Input> policy_set;
518 for (size_t i = levels_.size() - 1; i < levels_.size(); i--) {
519 for (auto& [policy, node] : levels_[i]) {
520 if (!node.reachable) {
521 continue;
522 }
523 if (node.parent_policies.empty()) {
524 // |node|'s parent is anyPolicy, so this is in the root policy domain.
525 // Add it to the set if it is also in user's list.
526 if (user_has_any_policy ||
527 user_initial_policy_set.count(policy) > 0) {
528 policy_set.insert(policy);
529 }
530 } else if (i > 0) {
531 // Otherwise, continue searching the previous level.
532 for (der::Input parent : node.parent_policies) {
533 auto iter = levels_[i - 1].find(parent);
534 if (iter != levels_[i - 1].end()) {
535 iter->second.reachable = true;
536 }
537 }
538 }
539 }
540 }
541 return policy_set;
542 }
543
544 // Adds a node with policy anyPolicy to the current level.
AddAnyPolicyNode()545 void AddAnyPolicyNode() {
546 assert(!levels_.empty());
547 current_level_.has_any_policy = true;
548 }
549
550 // Adds a node to the current level which is a child of |parent_policies| with
551 // the specified policy.
AddNode(der::Input policy,std::vector<der::Input> parent_policies)552 void AddNode(der::Input policy, std::vector<der::Input> parent_policies) {
553 assert(policy != der::Input(kAnyPolicyOid));
554 AddNodeReturningIterator(policy, std::move(parent_policies));
555 }
556
557 // Adds a node to the current level which is a child of anyPolicy with the
558 // specified policy.
AddNodeWithParentAnyPolicy(der::Input policy)559 void AddNodeWithParentAnyPolicy(der::Input policy) {
560 // An empty parent set represents a node parented by anyPolicy.
561 AddNode(policy, {});
562 }
563
564 // Maps |issuer_policy| to |subject_policy|, as in RFC 5280, section 6.1.4,
565 // step b.1.
AddPolicyMapping(der::Input issuer_policy,der::Input subject_policy)566 void AddPolicyMapping(der::Input issuer_policy, der::Input subject_policy) {
567 assert(issuer_policy != der::Input(kAnyPolicyOid));
568 assert(subject_policy != der::Input(kAnyPolicyOid));
569 if (levels_.empty()) {
570 return;
571 }
572
573 // The mapping only applies if |issuer_policy| exists in the current level.
574 auto issuer_policy_iter = levels_.back().find(issuer_policy);
575 if (issuer_policy_iter == levels_.back().end()) {
576 // If there is no match, it can instead match anyPolicy.
577 if (!current_level_.has_any_policy) {
578 return;
579 }
580
581 // From RFC 5280, section 6.1.4, step b.1:
582 //
583 // If no node of depth i in the valid_policy_tree has a
584 // valid_policy of ID-P but there is a node of depth i with a
585 // valid_policy of anyPolicy, then generate a child node of
586 // the node of depth i-1 that has a valid_policy of anyPolicy
587 // as follows: [...]
588 //
589 // The anyPolicy node of depth i-1 is referring to the parent of the
590 // anyPolicy node of depth i. The parent of anyPolicy is always anyPolicy.
591 issuer_policy_iter = AddNodeReturningIterator(issuer_policy, {});
592 }
593
594 // Unmapped nodes have a singleton "expected_policy_set" containing their
595 // valid_policy. Track whether nodes have been mapped so this can be filled
596 // in at StartLevel().
597 issuer_policy_iter->second.mapped = true;
598
599 // Add |subject_policy| to |issuer_policy|'s "expected_policy_set".
600 current_level_.expected_policy_map[subject_policy].push_back(issuer_policy);
601 }
602
603 // Removes the node with the specified policy from the current level.
DeleteNode(der::Input policy)604 void DeleteNode(der::Input policy) {
605 if (!levels_.empty()) {
606 levels_.back().erase(policy);
607 }
608 }
609
610 private:
AddNodeReturningIterator(der::Input policy,std::vector<der::Input> parent_policies)611 Level::iterator AddNodeReturningIterator(
612 der::Input policy,
613 std::vector<der::Input> parent_policies) {
614 assert(policy != der::Input(kAnyPolicyOid));
615 auto [iter, inserted] = levels_.back().insert(
616 std::pair{policy, Node{std::move(parent_policies)}});
617 // GCC before 8.1 tracks individual unused bindings and does not support
618 // marking them [[maybe_unused]].
619 (void)inserted;
620 assert(inserted);
621 return iter;
622 }
623
624 // The list of levels, starting from the root.
625 std::vector<Level> levels_;
626 // Additional information about the current level.
627 LevelDetails current_level_;
628 };
629
630 // Class that encapsulates the state variables used by certificate path
631 // validation.
632 class PathVerifier {
633 public:
634 // Same parameters and meaning as VerifyCertificateChain().
635 void Run(const ParsedCertificateList& certs,
636 const CertificateTrust& last_cert_trust,
637 VerifyCertificateChainDelegate* delegate,
638 const der::GeneralizedTime& time,
639 KeyPurpose required_key_purpose,
640 InitialExplicitPolicy initial_explicit_policy,
641 const std::set<der::Input>& user_initial_policy_set,
642 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
643 InitialAnyPolicyInhibit initial_any_policy_inhibit,
644 std::set<der::Input>* user_constrained_policy_set,
645 CertPathErrors* errors);
646
647 private:
648 // Verifies and updates the valid policies. This corresponds with RFC 5280
649 // section 6.1.3 steps d-f.
650 void VerifyPolicies(const ParsedCertificate& cert,
651 bool is_target_cert,
652 CertErrors* errors);
653
654 // Applies the policy mappings. This corresponds with RFC 5280 section 6.1.4
655 // steps a-b.
656 void VerifyPolicyMappings(const ParsedCertificate& cert, CertErrors* errors);
657
658 // Applies policyConstraints and inhibitAnyPolicy. This corresponds with RFC
659 // 5280 section 6.1.4 steps i-j.
660 void ApplyPolicyConstraints(const ParsedCertificate& cert);
661
662 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
663 // Processing" procedure.
664 void BasicCertificateProcessing(const ParsedCertificate& cert,
665 bool is_target_cert,
666 bool is_target_cert_issuer,
667 const der::GeneralizedTime& time,
668 KeyPurpose required_key_purpose,
669 CertErrors* errors,
670 bool* shortcircuit_chain_validation);
671
672 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for
673 // Certificate i+1" procedure. |cert| is expected to be an intermediate.
674 void PrepareForNextCertificate(const ParsedCertificate& cert,
675 CertErrors* errors);
676
677 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up
678 // Procedure". It does processing for the final certificate (the target cert).
679 void WrapUp(const ParsedCertificate& cert,
680 KeyPurpose required_key_purpose,
681 const std::set<der::Input>& user_initial_policy_set,
682 CertErrors* errors);
683
684 // Enforces trust anchor constraints compatibile with RFC 5937.
685 //
686 // Note that the anchor constraints are encoded via the attached certificate
687 // itself.
688 void ApplyTrustAnchorConstraints(const ParsedCertificate& cert,
689 KeyPurpose required_key_purpose,
690 CertErrors* errors);
691
692 // Initializes the path validation algorithm given anchor constraints. This
693 // follows the description in RFC 5937
694 void ProcessRootCertificate(const ParsedCertificate& cert,
695 const CertificateTrust& trust,
696 const der::GeneralizedTime& time,
697 KeyPurpose required_key_purpose,
698 CertErrors* errors,
699 bool* shortcircuit_chain_validation);
700
701 // Processes verification when the input is a single certificate. This is not
702 // defined by any standard. We attempt to match the de-facto behaviour of
703 // Operating System verifiers.
704 void ProcessSingleCertChain(const ParsedCertificate& cert,
705 const CertificateTrust& trust,
706 const der::GeneralizedTime& time,
707 KeyPurpose required_key_purpose,
708 CertErrors* errors);
709
710 // Parses |spki| to an EVP_PKEY and checks whether the public key is accepted
711 // by |delegate_|. On failure parsing returns nullptr. If either parsing the
712 // key or key policy failed, adds a high-severity error to |errors|.
713 bssl::UniquePtr<EVP_PKEY> ParseAndCheckPublicKey(const der::Input& spki,
714 CertErrors* errors);
715
716 ValidPolicyGraph valid_policy_graph_;
717
718 std::set<der::Input> user_constrained_policy_set_;
719
720 // Will contain a NameConstraints for each previous cert in the chain which
721 // had nameConstraints. This corresponds to the permitted_subtrees and
722 // excluded_subtrees state variables from RFC 5280.
723 std::vector<const NameConstraints*> name_constraints_list_;
724
725 // |explicit_policy_| corresponds with the same named variable from RFC 5280
726 // section 6.1.2:
727 //
728 // explicit_policy: an integer that indicates if a non-NULL
729 // valid_policy_tree is required. The integer indicates the
730 // number of non-self-issued certificates to be processed before
731 // this requirement is imposed. Once set, this variable may be
732 // decreased, but may not be increased. That is, if a certificate in the
733 // path requires a non-NULL valid_policy_tree, a later certificate cannot
734 // remove this requirement. If initial-explicit-policy is set, then the
735 // initial value is 0, otherwise the initial value is n+1.
736 size_t explicit_policy_;
737
738 // |inhibit_any_policy_| corresponds with the same named variable from RFC
739 // 5280 section 6.1.2:
740 //
741 // inhibit_anyPolicy: an integer that indicates whether the
742 // anyPolicy policy identifier is considered a match. The
743 // integer indicates the number of non-self-issued certificates
744 // to be processed before the anyPolicy OID, if asserted in a
745 // certificate other than an intermediate self-issued
746 // certificate, is ignored. Once set, this variable may be
747 // decreased, but may not be increased. That is, if a
748 // certificate in the path inhibits processing of anyPolicy, a
749 // later certificate cannot permit it. If initial-any-policy-
750 // inhibit is set, then the initial value is 0, otherwise the
751 // initial value is n+1.
752 size_t inhibit_any_policy_;
753
754 // |policy_mapping_| corresponds with the same named variable from RFC 5280
755 // section 6.1.2:
756 //
757 // policy_mapping: an integer that indicates if policy mapping
758 // is permitted. The integer indicates the number of non-self-
759 // issued certificates to be processed before policy mapping is
760 // inhibited. Once set, this variable may be decreased, but may
761 // not be increased. That is, if a certificate in the path
762 // specifies that policy mapping is not permitted, it cannot be
763 // overridden by a later certificate. If initial-policy-
764 // mapping-inhibit is set, then the initial value is 0,
765 // otherwise the initial value is n+1.
766 size_t policy_mapping_;
767
768 // |working_public_key_| is an amalgamation of 3 separate variables from RFC
769 // 5280:
770 // * working_public_key
771 // * working_public_key_algorithm
772 // * working_public_key_parameters
773 //
774 // They are combined for simplicity since the signature verification takes an
775 // EVP_PKEY, and the parameter inheritence is not applicable for the supported
776 // key types. |working_public_key_| may be null if parsing failed.
777 //
778 // An approximate explanation of |working_public_key_| is this description
779 // from RFC 5280 section 6.1.2:
780 //
781 // working_public_key: the public key used to verify the
782 // signature of a certificate.
783 bssl::UniquePtr<EVP_PKEY> working_public_key_;
784
785 // |working_normalized_issuer_name_| is the normalized value of the
786 // working_issuer_name variable in RFC 5280 section 6.1.2:
787 //
788 // working_issuer_name: the issuer distinguished name expected
789 // in the next certificate in the chain.
790 der::Input working_normalized_issuer_name_;
791
792 // |max_path_length_| corresponds with the same named variable in RFC 5280
793 // section 6.1.2.
794 //
795 // max_path_length: this integer is initialized to n, is
796 // decremented for each non-self-issued certificate in the path,
797 // and may be reduced to the value in the path length constraint
798 // field within the basic constraints extension of a CA
799 // certificate.
800 size_t max_path_length_;
801
802 VerifyCertificateChainDelegate* delegate_;
803 };
804
VerifyPolicies(const ParsedCertificate & cert,bool is_target_cert,CertErrors * errors)805 void PathVerifier::VerifyPolicies(const ParsedCertificate& cert,
806 bool is_target_cert,
807 CertErrors* errors) {
808 // From RFC 5280 section 6.1.3:
809 //
810 // (d) If the certificate policies extension is present in the
811 // certificate and the valid_policy_tree is not NULL, process
812 // the policy information by performing the following steps in
813 // order:
814 if (cert.has_policy_oids() && !valid_policy_graph_.IsNull()) {
815 ValidPolicyGraph::LevelDetails previous_level =
816 valid_policy_graph_.StartLevel();
817
818 // (1) For each policy P not equal to anyPolicy in the
819 // certificate policies extension, let P-OID denote the OID
820 // for policy P and P-Q denote the qualifier set for policy
821 // P. Perform the following steps in order:
822 bool cert_has_any_policy = false;
823 for (const der::Input& p_oid : cert.policy_oids()) {
824 if (p_oid == der::Input(kAnyPolicyOid)) {
825 cert_has_any_policy = true;
826 continue;
827 }
828
829 // (i) For each node of depth i-1 in the valid_policy_tree
830 // where P-OID is in the expected_policy_set, create a
831 // child node as follows: set the valid_policy to P-OID,
832 // set the qualifier_set to P-Q, and set the
833 // expected_policy_set to {P-OID}.
834 auto iter = previous_level.expected_policy_map.find(p_oid);
835 if (iter != previous_level.expected_policy_map.end()) {
836 valid_policy_graph_.AddNode(
837 p_oid, /*parent_policies=*/std::move(iter->second));
838 previous_level.expected_policy_map.erase(iter);
839 } else if (previous_level.has_any_policy) {
840 // (ii) If there was no match in step (i) and the
841 // valid_policy_tree includes a node of depth i-1 with
842 // the valid_policy anyPolicy, generate a child node with
843 // the following values: set the valid_policy to P-OID,
844 // set the qualifier_set to P-Q, and set the
845 // expected_policy_set to {P-OID}.
846 valid_policy_graph_.AddNodeWithParentAnyPolicy(p_oid);
847 }
848 }
849
850 // (2) If the certificate policies extension includes the policy
851 // anyPolicy with the qualifier set AP-Q and either (a)
852 // inhibit_anyPolicy is greater than 0 or (b) i<n and the
853 // certificate is self-issued, then:
854 //
855 // For each node in the valid_policy_tree of depth i-1, for
856 // each value in the expected_policy_set (including
857 // anyPolicy) that does not appear in a child node, create a
858 // child node with the following values: set the valid_policy
859 // to the value from the expected_policy_set in the parent
860 // node, set the qualifier_set to AP-Q, and set the
861 // expected_policy_set to the value in the valid_policy from
862 // this node.
863 if (cert_has_any_policy && ((inhibit_any_policy_ > 0) ||
864 (!is_target_cert && IsSelfIssued(cert)))) {
865 for (auto& [p_oid, parent_policies] :
866 previous_level.expected_policy_map) {
867 valid_policy_graph_.AddNode(p_oid, std::move(parent_policies));
868 }
869 if (previous_level.has_any_policy) {
870 valid_policy_graph_.AddAnyPolicyNode();
871 }
872 }
873
874 // (3) If there is a node in the valid_policy_tree of depth i-1
875 // or less without any child nodes, delete that node. Repeat
876 // this step until there are no nodes of depth i-1 or less
877 // without children.
878 //
879 // This implementation does this as part of GetUserConstrainedPolicySet().
880 // Only the current level needs to be pruned to compute the policy graph.
881 }
882
883 // (e) If the certificate policies extension is not present, set the
884 // valid_policy_tree to NULL.
885 if (!cert.has_policy_oids())
886 valid_policy_graph_.SetNull();
887
888 // (f) Verify that either explicit_policy is greater than 0 or the
889 // valid_policy_tree is not equal to NULL;
890 if (!((explicit_policy_ > 0) || !valid_policy_graph_.IsNull()))
891 errors->AddError(cert_errors::kNoValidPolicy);
892 }
893
VerifyPolicyMappings(const ParsedCertificate & cert,CertErrors * errors)894 void PathVerifier::VerifyPolicyMappings(const ParsedCertificate& cert,
895 CertErrors* errors) {
896 if (!cert.has_policy_mappings())
897 return;
898
899 // From RFC 5280 section 6.1.4:
900 //
901 // (a) If a policy mappings extension is present, verify that the
902 // special value anyPolicy does not appear as an
903 // issuerDomainPolicy or a subjectDomainPolicy.
904 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
905 if (mapping.issuer_domain_policy == der::Input(kAnyPolicyOid) ||
906 mapping.subject_domain_policy == der::Input(kAnyPolicyOid)) {
907 // Because this implementation continues processing certificates after
908 // this error, clear the valid policy graph to ensure the
909 // "user_constrained_policy_set" output upon failure is empty.
910 valid_policy_graph_.SetNull();
911 errors->AddError(cert_errors::kPolicyMappingAnyPolicy);
912 return;
913 }
914 }
915
916 // (b) If a policy mappings extension is present, then for each
917 // issuerDomainPolicy ID-P in the policy mappings extension:
918 //
919 // (1) If the policy_mapping variable is greater than 0, for each
920 // node in the valid_policy_tree of depth i where ID-P is the
921 // valid_policy, set expected_policy_set to the set of
922 // subjectDomainPolicy values that are specified as
923 // equivalent to ID-P by the policy mappings extension.
924 //
925 // If no node of depth i in the valid_policy_tree has a
926 // valid_policy of ID-P but there is a node of depth i with a
927 // valid_policy of anyPolicy, then generate a child node of
928 // the node of depth i-1 that has a valid_policy of anyPolicy
929 // as follows:
930 //
931 // (i) set the valid_policy to ID-P;
932 //
933 // (ii) set the qualifier_set to the qualifier set of the
934 // policy anyPolicy in the certificate policies
935 // extension of certificate i; and
936 //
937 // (iii) set the expected_policy_set to the set of
938 // subjectDomainPolicy values that are specified as
939 // equivalent to ID-P by the policy mappings extension.
940 //
941 if (policy_mapping_ > 0) {
942 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
943 valid_policy_graph_.AddPolicyMapping(mapping.issuer_domain_policy,
944 mapping.subject_domain_policy);
945 }
946 }
947
948 // (b) If a policy mappings extension is present, then for each
949 // issuerDomainPolicy ID-P in the policy mappings extension:
950 //
951 // ...
952 //
953 // (2) If the policy_mapping variable is equal to 0:
954 //
955 // (i) delete each node of depth i in the valid_policy_tree
956 // where ID-P is the valid_policy.
957 //
958 // (ii) If there is a node in the valid_policy_tree of depth
959 // i-1 or less without any child nodes, delete that
960 // node. Repeat this step until there are no nodes of
961 // depth i-1 or less without children.
962 //
963 // Step (ii) is deferred to part of GetUserConstrainedPolicySet().
964 if (policy_mapping_ == 0) {
965 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
966 valid_policy_graph_.DeleteNode(mapping.issuer_domain_policy);
967 }
968 }
969 }
970
ApplyPolicyConstraints(const ParsedCertificate & cert)971 void PathVerifier::ApplyPolicyConstraints(const ParsedCertificate& cert) {
972 // RFC 5280 section 6.1.4 step i-j:
973 // (i) If a policy constraints extension is included in the
974 // certificate, modify the explicit_policy and policy_mapping
975 // state variables as follows:
976 if (cert.has_policy_constraints()) {
977 // (1) If requireExplicitPolicy is present and is less than
978 // explicit_policy, set explicit_policy to the value of
979 // requireExplicitPolicy.
980 if (cert.policy_constraints().require_explicit_policy &&
981 cert.policy_constraints().require_explicit_policy.value() <
982 explicit_policy_) {
983 explicit_policy_ =
984 cert.policy_constraints().require_explicit_policy.value();
985 }
986
987 // (2) If inhibitPolicyMapping is present and is less than
988 // policy_mapping, set policy_mapping to the value of
989 // inhibitPolicyMapping.
990 if (cert.policy_constraints().inhibit_policy_mapping &&
991 cert.policy_constraints().inhibit_policy_mapping.value() <
992 policy_mapping_) {
993 policy_mapping_ =
994 cert.policy_constraints().inhibit_policy_mapping.value();
995 }
996 }
997
998 // (j) If the inhibitAnyPolicy extension is included in the
999 // certificate and is less than inhibit_anyPolicy, set
1000 // inhibit_anyPolicy to the value of inhibitAnyPolicy.
1001 if (cert.inhibit_any_policy() &&
1002 cert.inhibit_any_policy().value() < inhibit_any_policy_) {
1003 inhibit_any_policy_ = cert.inhibit_any_policy().value();
1004 }
1005 }
1006
BasicCertificateProcessing(const ParsedCertificate & cert,bool is_target_cert,bool is_target_cert_issuer,const der::GeneralizedTime & time,KeyPurpose required_key_purpose,CertErrors * errors,bool * shortcircuit_chain_validation)1007 void PathVerifier::BasicCertificateProcessing(
1008 const ParsedCertificate& cert,
1009 bool is_target_cert,
1010 bool is_target_cert_issuer,
1011 const der::GeneralizedTime& time,
1012 KeyPurpose required_key_purpose,
1013 CertErrors* errors,
1014 bool* shortcircuit_chain_validation) {
1015 *shortcircuit_chain_validation = false;
1016 // Check that the signature algorithms in Certificate vs TBSCertificate
1017 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by
1018 // sections 4.1.1.2 and 4.1.2.3.
1019 if (!VerifySignatureAlgorithmsMatch(cert, errors)) {
1020 BSSL_CHECK(errors->ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH));
1021 *shortcircuit_chain_validation = true;
1022 }
1023
1024 // Check whether this signature algorithm is allowed.
1025 if (!cert.signature_algorithm().has_value() ||
1026 !delegate_->IsSignatureAlgorithmAcceptable(*cert.signature_algorithm(),
1027 errors)) {
1028 *shortcircuit_chain_validation = true;
1029 errors->AddError(cert_errors::kUnacceptableSignatureAlgorithm);
1030 return;
1031 }
1032
1033 if (working_public_key_) {
1034 // Verify the digital signature using the previous certificate's key (RFC
1035 // 5280 section 6.1.3 step a.1).
1036 if (!VerifySignedData(*cert.signature_algorithm(),
1037 cert.tbs_certificate_tlv(), cert.signature_value(),
1038 working_public_key_.get(),
1039 delegate_->GetVerifyCache())) {
1040 *shortcircuit_chain_validation = true;
1041 errors->AddError(cert_errors::kVerifySignedDataFailed);
1042 }
1043 }
1044 if (*shortcircuit_chain_validation)
1045 return;
1046
1047 // Check the time range for the certificate's validity, ensuring it is valid
1048 // at |time|.
1049 // (RFC 5280 section 6.1.3 step a.2)
1050 VerifyTimeValidity(cert, time, errors);
1051
1052 // RFC 5280 section 6.1.3 step a.3 calls for checking the certificate's
1053 // revocation status here. In this implementation revocation checking is
1054 // implemented separately from path validation.
1055
1056 // Verify the certificate's issuer name matches the issuing certificate's
1057 // subject name. (RFC 5280 section 6.1.3 step a.4)
1058 if (cert.normalized_issuer() != working_normalized_issuer_name_)
1059 errors->AddError(cert_errors::kSubjectDoesNotMatchIssuer);
1060
1061 // Name constraints (RFC 5280 section 6.1.3 step b & c)
1062 // If certificate i is self-issued and it is not the final certificate in the
1063 // path, skip this step for certificate i.
1064 if (!name_constraints_list_.empty() &&
1065 (!IsSelfIssued(cert) || is_target_cert)) {
1066 for (const NameConstraints* nc : name_constraints_list_) {
1067 nc->IsPermittedCert(cert.normalized_subject(), cert.subject_alt_names(),
1068 errors);
1069 }
1070 }
1071
1072 // RFC 5280 section 6.1.3 step d - f.
1073 VerifyPolicies(cert, is_target_cert, errors);
1074
1075 // The key purpose is checked not just for the end-entity certificate, but
1076 // also interpreted as a constraint when it appears in intermediates. This
1077 // goes beyond what RFC 5280 describes, but is the de-facto standard. See
1078 // https://wiki.mozilla.org/CA:CertificatePolicyV2.1#Frequently_Asked_Questions
1079 VerifyExtendedKeyUsage(cert, required_key_purpose, errors, is_target_cert,
1080 is_target_cert_issuer);
1081 }
1082
PrepareForNextCertificate(const ParsedCertificate & cert,CertErrors * errors)1083 void PathVerifier::PrepareForNextCertificate(const ParsedCertificate& cert,
1084 CertErrors* errors) {
1085 // RFC 5280 section 6.1.4 step a-b
1086 VerifyPolicyMappings(cert, errors);
1087
1088 // From RFC 5280 section 6.1.4 step c:
1089 //
1090 // Assign the certificate subject name to working_normalized_issuer_name.
1091 working_normalized_issuer_name_ = cert.normalized_subject();
1092
1093 // From RFC 5280 section 6.1.4 step d:
1094 //
1095 // Assign the certificate subjectPublicKey to working_public_key.
1096 working_public_key_ = ParseAndCheckPublicKey(cert.tbs().spki_tlv, errors);
1097
1098 // Note that steps e and f are omitted as they are handled by
1099 // the assignment to |working_spki| above. See the definition
1100 // of |working_spki|.
1101
1102 // From RFC 5280 section 6.1.4 step g:
1103 if (cert.has_name_constraints())
1104 name_constraints_list_.push_back(&cert.name_constraints());
1105
1106 // (h) If certificate i is not self-issued:
1107 if (!IsSelfIssued(cert)) {
1108 // (1) If explicit_policy is not 0, decrement explicit_policy by
1109 // 1.
1110 if (explicit_policy_ > 0)
1111 explicit_policy_ -= 1;
1112
1113 // (2) If policy_mapping is not 0, decrement policy_mapping by 1.
1114 if (policy_mapping_ > 0)
1115 policy_mapping_ -= 1;
1116
1117 // (3) If inhibit_anyPolicy is not 0, decrement inhibit_anyPolicy
1118 // by 1.
1119 if (inhibit_any_policy_ > 0)
1120 inhibit_any_policy_ -= 1;
1121 }
1122
1123 // RFC 5280 section 6.1.4 step i-j:
1124 ApplyPolicyConstraints(cert);
1125
1126 // From RFC 5280 section 6.1.4 step k:
1127 //
1128 // If certificate i is a version 3 certificate, verify that the
1129 // basicConstraints extension is present and that cA is set to
1130 // TRUE. (If certificate i is a version 1 or version 2
1131 // certificate, then the application MUST either verify that
1132 // certificate i is a CA certificate through out-of-band means
1133 // or reject the certificate. Conforming implementations may
1134 // choose to reject all version 1 and version 2 intermediate
1135 // certificates.)
1136 //
1137 // This code implicitly rejects non version 3 intermediates, since they
1138 // can't contain a BasicConstraints extension.
1139 if (!cert.has_basic_constraints()) {
1140 errors->AddError(cert_errors::kMissingBasicConstraints);
1141 } else if (!cert.basic_constraints().is_ca) {
1142 errors->AddError(cert_errors::kBasicConstraintsIndicatesNotCa);
1143 }
1144
1145 // From RFC 5280 section 6.1.4 step l:
1146 //
1147 // If the certificate was not self-issued, verify that
1148 // max_path_length is greater than zero and decrement
1149 // max_path_length by 1.
1150 if (!IsSelfIssued(cert)) {
1151 if (max_path_length_ == 0) {
1152 errors->AddError(cert_errors::kMaxPathLengthViolated);
1153 } else {
1154 --max_path_length_;
1155 }
1156 }
1157
1158 // From RFC 5280 section 6.1.4 step m:
1159 //
1160 // If pathLenConstraint is present in the certificate and is
1161 // less than max_path_length, set max_path_length to the value
1162 // of pathLenConstraint.
1163 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len &&
1164 cert.basic_constraints().path_len < max_path_length_) {
1165 max_path_length_ = cert.basic_constraints().path_len;
1166 }
1167
1168 // From RFC 5280 section 6.1.4 step n:
1169 //
1170 // If a key usage extension is present, verify that the
1171 // keyCertSign bit is set.
1172 if (cert.has_key_usage() &&
1173 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
1174 errors->AddError(cert_errors::kKeyCertSignBitNotSet);
1175 }
1176
1177 // From RFC 5280 section 6.1.4 step o:
1178 //
1179 // Recognize and process any other critical extension present in
1180 // the certificate. Process any other recognized non-critical
1181 // extension present in the certificate that is relevant to path
1182 // processing.
1183 VerifyNoUnconsumedCriticalExtensions(cert, errors);
1184 }
1185
1186 // Checks if the target certificate has the CA bit set. If it does, add
1187 // the appropriate error or warning to |errors|.
VerifyTargetCertIsNotCA(const ParsedCertificate & cert,KeyPurpose required_key_purpose,CertErrors * errors)1188 void VerifyTargetCertIsNotCA(const ParsedCertificate& cert,
1189 KeyPurpose required_key_purpose,
1190 CertErrors* errors) {
1191 if (cert.has_basic_constraints() && cert.basic_constraints().is_ca) {
1192 // In spite of RFC 5280 4.2.1.9 which says the CA properties MAY exist in
1193 // an end entity certificate, the CABF Baseline Requirements version
1194 // 1.8.4, 7.1.2.3(d) prohibit the CA bit being set in an end entity
1195 // certificate.
1196 switch (required_key_purpose) {
1197 case KeyPurpose::ANY_EKU:
1198 break;
1199 case KeyPurpose::SERVER_AUTH:
1200 case KeyPurpose::CLIENT_AUTH:
1201 errors->AddWarning(cert_errors::kTargetCertShouldNotBeCa);
1202 break;
1203 case KeyPurpose::SERVER_AUTH_STRICT:
1204 case KeyPurpose::CLIENT_AUTH_STRICT:
1205 errors->AddError(cert_errors::kTargetCertShouldNotBeCa);
1206 break;
1207 }
1208 }
1209 }
1210
WrapUp(const ParsedCertificate & cert,KeyPurpose required_key_purpose,const std::set<der::Input> & user_initial_policy_set,CertErrors * errors)1211 void PathVerifier::WrapUp(const ParsedCertificate& cert,
1212 KeyPurpose required_key_purpose,
1213 const std::set<der::Input>& user_initial_policy_set,
1214 CertErrors* errors) {
1215 // From RFC 5280 section 6.1.5:
1216 // (a) If explicit_policy is not 0, decrement explicit_policy by 1.
1217 if (explicit_policy_ > 0)
1218 explicit_policy_ -= 1;
1219
1220 // (b) If a policy constraints extension is included in the
1221 // certificate and requireExplicitPolicy is present and has a
1222 // value of 0, set the explicit_policy state variable to 0.
1223 if (cert.has_policy_constraints() &&
1224 cert.policy_constraints().require_explicit_policy.has_value() &&
1225 cert.policy_constraints().require_explicit_policy == 0) {
1226 explicit_policy_ = 0;
1227 }
1228
1229 // Note step c-e are omitted as the verification function does
1230 // not output the working public key.
1231
1232 // From RFC 5280 section 6.1.5 step f:
1233 //
1234 // Recognize and process any other critical extension present in
1235 // the certificate n. Process any other recognized non-critical
1236 // extension present in certificate n that is relevant to path
1237 // processing.
1238 //
1239 // Note that this is duplicated by PrepareForNextCertificate() so as to
1240 // directly match the procedures in RFC 5280's section 6.1.
1241 VerifyNoUnconsumedCriticalExtensions(cert, errors);
1242
1243 // This calculates the intersection from RFC 5280 section 6.1.5 step g, as
1244 // well as applying the deferred recursive node that were skipped earlier in
1245 // the process.
1246 user_constrained_policy_set_ =
1247 valid_policy_graph_.GetUserConstrainedPolicySet(user_initial_policy_set);
1248
1249 // From RFC 5280 section 6.1.5 step g:
1250 //
1251 // If either (1) the value of explicit_policy variable is greater than
1252 // zero or (2) the valid_policy_tree is not NULL, then path processing
1253 // has succeeded.
1254 if (explicit_policy_ == 0 && user_constrained_policy_set_.empty()) {
1255 errors->AddError(cert_errors::kNoValidPolicy);
1256 }
1257
1258 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure",
1259 // however is implied by RFC 5280 section 4.2.1.9, as well as CABF Base
1260 // Requirements.
1261 VerifyTargetCertIsNotCA(cert, required_key_purpose, errors);
1262
1263 // Check the public key for the target certificate. The public key for the
1264 // other certificates is already checked by PrepareForNextCertificate().
1265 // Note that this step is not part of RFC 5280 6.1.5.
1266 ParseAndCheckPublicKey(cert.tbs().spki_tlv, errors);
1267 }
1268
ApplyTrustAnchorConstraints(const ParsedCertificate & cert,KeyPurpose required_key_purpose,CertErrors * errors)1269 void PathVerifier::ApplyTrustAnchorConstraints(const ParsedCertificate& cert,
1270 KeyPurpose required_key_purpose,
1271 CertErrors* errors) {
1272 // If certificatePolicies is present, process the policies. This matches the
1273 // handling for intermediates from RFC 5280 section 6.1.3.d (except that for
1274 // intermediates it is non-optional). It intentionally deviates from RFC 5937
1275 // section 3.2 which says to intersect with user-initial-policy-set, since
1276 // processing as part of user-initial-policy-set has subtly different
1277 // semantics from being handled as part of the chain processing (see
1278 // https://crbug.com/1403258).
1279 if (cert.has_policy_oids()) {
1280 VerifyPolicies(cert, /*is_target_cert=*/false, errors);
1281 }
1282
1283 // Process policyMappings, if present. This matches the handling for
1284 // intermediates from RFC 5280 section 6.1.4 step a-b.
1285 VerifyPolicyMappings(cert, errors);
1286
1287 // Process policyConstraints and inhibitAnyPolicy. This matches the
1288 // handling for intermediates from RFC 5280 section 6.1.4 step i-j.
1289 // This intentionally deviates from RFC 5937 section 3.2 which says to
1290 // initialize the initial-any-policy-inhibit, initial-explicit-policy, and/or
1291 // initial-policy-mapping-inhibit inputs to verification. Those are all
1292 // bools, so they cannot properly represent the constraints encoded in the
1293 // policyConstraints and inhibitAnyPolicy extensions.
1294 ApplyPolicyConstraints(cert);
1295
1296 // If keyUsage is present, verify that |cert| has correct keyUsage bits for a
1297 // CA. This matches the handling for intermediates from RFC 5280 section
1298 // 6.1.4 step n.
1299 if (cert.has_key_usage() &&
1300 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
1301 errors->AddError(cert_errors::kKeyCertSignBitNotSet);
1302 }
1303
1304 // This is not part of RFC 5937 nor RFC 5280, but matches the EKU handling
1305 // done for intermediates (described in Web PKI's Baseline Requirements).
1306 VerifyExtendedKeyUsage(cert, required_key_purpose, errors,
1307 /*is_target_cert=*/false,
1308 /*is_target_cert_issuer=*/false);
1309
1310 // The following enforcements follow from RFC 5937 (primarily section 3.2):
1311
1312 // Initialize name constraints initial-permitted/excluded-subtrees.
1313 if (cert.has_name_constraints())
1314 name_constraints_list_.push_back(&cert.name_constraints());
1315
1316 if (cert.has_basic_constraints()) {
1317 // Enforce CA=true if basicConstraints is present. This matches behavior of
1318 // other verifiers, and seems like a good thing to do to avoid a
1319 // certificate being used in the wrong context if it was specifically
1320 // marked as not being a CA.
1321 if (!cert.basic_constraints().is_ca) {
1322 errors->AddError(cert_errors::kBasicConstraintsIndicatesNotCa);
1323 }
1324 // From RFC 5937 section 3.2:
1325 //
1326 // If a basic constraints extension is associated with the trust
1327 // anchor and contains a pathLenConstraint value, set the
1328 // max_path_length state variable equal to the pathLenConstraint
1329 // value from the basic constraints extension.
1330 //
1331 if (cert.basic_constraints().has_path_len) {
1332 max_path_length_ = cert.basic_constraints().path_len;
1333 }
1334 }
1335
1336 // From RFC 5937 section 2:
1337 //
1338 // Extensions may be marked critical or not critical. When trust anchor
1339 // constraints are enforced, clients MUST reject certification paths
1340 // containing a trust anchor with unrecognized critical extensions.
1341 VerifyNoUnconsumedCriticalExtensions(cert, errors);
1342 }
1343
ProcessRootCertificate(const ParsedCertificate & cert,const CertificateTrust & trust,const der::GeneralizedTime & time,KeyPurpose required_key_purpose,CertErrors * errors,bool * shortcircuit_chain_validation)1344 void PathVerifier::ProcessRootCertificate(const ParsedCertificate& cert,
1345 const CertificateTrust& trust,
1346 const der::GeneralizedTime& time,
1347 KeyPurpose required_key_purpose,
1348 CertErrors* errors,
1349 bool* shortcircuit_chain_validation) {
1350 *shortcircuit_chain_validation = false;
1351 switch (trust.type) {
1352 case CertificateTrustType::UNSPECIFIED:
1353 case CertificateTrustType::TRUSTED_LEAF:
1354 // Doesn't chain to a trust anchor - implicitly distrusted
1355 errors->AddError(cert_errors::kCertIsNotTrustAnchor);
1356 *shortcircuit_chain_validation = true;
1357 break;
1358 case CertificateTrustType::DISTRUSTED:
1359 // Chains to an actively distrusted certificate.
1360 errors->AddError(cert_errors::kDistrustedByTrustStore);
1361 *shortcircuit_chain_validation = true;
1362 break;
1363 case CertificateTrustType::TRUSTED_ANCHOR:
1364 case CertificateTrustType::TRUSTED_ANCHOR_OR_LEAF:
1365 break;
1366 }
1367 if (*shortcircuit_chain_validation)
1368 return;
1369
1370 if (trust.enforce_anchor_expiry) {
1371 VerifyTimeValidity(cert, time, errors);
1372 }
1373 if (trust.enforce_anchor_constraints) {
1374 if (trust.require_anchor_basic_constraints &&
1375 !cert.has_basic_constraints()) {
1376 switch (cert.tbs().version) {
1377 case CertificateVersion::V1:
1378 case CertificateVersion::V2:
1379 break;
1380 case CertificateVersion::V3:
1381 errors->AddError(cert_errors::kMissingBasicConstraints);
1382 break;
1383 }
1384 }
1385 ApplyTrustAnchorConstraints(cert, required_key_purpose, errors);
1386 }
1387
1388 // Use the certificate's SPKI and subject when verifying the next certificate.
1389 working_public_key_ = ParseAndCheckPublicKey(cert.tbs().spki_tlv, errors);
1390 working_normalized_issuer_name_ = cert.normalized_subject();
1391 }
1392
ProcessSingleCertChain(const ParsedCertificate & cert,const CertificateTrust & trust,const der::GeneralizedTime & time,KeyPurpose required_key_purpose,CertErrors * errors)1393 void PathVerifier::ProcessSingleCertChain(const ParsedCertificate& cert,
1394 const CertificateTrust& trust,
1395 const der::GeneralizedTime& time,
1396 KeyPurpose required_key_purpose,
1397 CertErrors* errors) {
1398 switch (trust.type) {
1399 case CertificateTrustType::UNSPECIFIED:
1400 case CertificateTrustType::TRUSTED_ANCHOR:
1401 // Target doesn't have a chain and isn't a directly trusted leaf -
1402 // implicitly distrusted.
1403 errors->AddError(cert_errors::kCertIsNotTrustAnchor);
1404 return;
1405 case CertificateTrustType::DISTRUSTED:
1406 // Target is directly distrusted.
1407 errors->AddError(cert_errors::kDistrustedByTrustStore);
1408 return;
1409 case CertificateTrustType::TRUSTED_LEAF:
1410 case CertificateTrustType::TRUSTED_ANCHOR_OR_LEAF:
1411 break;
1412 }
1413
1414 // Check the public key for the target certificate regardless of whether
1415 // `require_leaf_selfsigned` is true. This matches the check in WrapUp and
1416 // fulfills the documented behavior of the IsPublicKeyAcceptable delegate.
1417 ParseAndCheckPublicKey(cert.tbs().spki_tlv, errors);
1418
1419 if (trust.require_leaf_selfsigned) {
1420 if (!VerifyCertificateIsSelfSigned(cert, delegate_->GetVerifyCache(),
1421 errors)) {
1422 // VerifyCertificateIsSelfSigned should have added an error, but just
1423 // double check to be safe.
1424 if (!errors->ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH)) {
1425 errors->AddError(cert_errors::kInternalError);
1426 }
1427 return;
1428 }
1429 }
1430
1431 // There is no standard for what it means to verify a directly trusted leaf
1432 // certificate, so this is basically just checking common sense things that
1433 // also mirror what we observed to be enforced with the Operating System
1434 // native verifiers.
1435 VerifyTimeValidity(cert, time, errors);
1436 VerifyExtendedKeyUsage(cert, required_key_purpose, errors,
1437 /*is_target_cert=*/true,
1438 /*is_target_cert_issuer=*/false);
1439
1440 // Checking for unknown critical extensions matches Windows, but is stricter
1441 // than the Mac verifier.
1442 VerifyNoUnconsumedCriticalExtensions(cert, errors);
1443 }
1444
ParseAndCheckPublicKey(const der::Input & spki,CertErrors * errors)1445 bssl::UniquePtr<EVP_PKEY> PathVerifier::ParseAndCheckPublicKey(
1446 const der::Input& spki,
1447 CertErrors* errors) {
1448 // Parse the public key.
1449 bssl::UniquePtr<EVP_PKEY> pkey;
1450 if (!ParsePublicKey(spki, &pkey)) {
1451 errors->AddError(cert_errors::kFailedParsingSpki);
1452 return nullptr;
1453 }
1454
1455 // Check if the key is acceptable by the delegate.
1456 if (!delegate_->IsPublicKeyAcceptable(pkey.get(), errors))
1457 errors->AddError(cert_errors::kUnacceptablePublicKey);
1458
1459 return pkey;
1460 }
1461
Run(const ParsedCertificateList & certs,const CertificateTrust & last_cert_trust,VerifyCertificateChainDelegate * delegate,const der::GeneralizedTime & time,KeyPurpose required_key_purpose,InitialExplicitPolicy initial_explicit_policy,const std::set<der::Input> & user_initial_policy_set,InitialPolicyMappingInhibit initial_policy_mapping_inhibit,InitialAnyPolicyInhibit initial_any_policy_inhibit,std::set<der::Input> * user_constrained_policy_set,CertPathErrors * errors)1462 void PathVerifier::Run(
1463 const ParsedCertificateList& certs,
1464 const CertificateTrust& last_cert_trust,
1465 VerifyCertificateChainDelegate* delegate,
1466 const der::GeneralizedTime& time,
1467 KeyPurpose required_key_purpose,
1468 InitialExplicitPolicy initial_explicit_policy,
1469 const std::set<der::Input>& user_initial_policy_set,
1470 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
1471 InitialAnyPolicyInhibit initial_any_policy_inhibit,
1472 std::set<der::Input>* user_constrained_policy_set,
1473 CertPathErrors* errors) {
1474 // This implementation is structured to mimic the description of certificate
1475 // path verification given by RFC 5280 section 6.1.
1476 BSSL_CHECK(delegate);
1477 BSSL_CHECK(errors);
1478
1479 delegate_ = delegate;
1480
1481 // An empty chain is necessarily invalid.
1482 if (certs.empty()) {
1483 errors->GetOtherErrors()->AddError(cert_errors::kChainIsEmpty);
1484 return;
1485 }
1486
1487 // Verifying a trusted leaf certificate isn't a well-specified operation, so
1488 // it's handled separately from the RFC 5280 defined verification process.
1489 if (certs.size() == 1) {
1490 ProcessSingleCertChain(*certs.front(), last_cert_trust, time,
1491 required_key_purpose, errors->GetErrorsForCert(0));
1492 return;
1493 }
1494
1495 // RFC 5280's "n" variable is the length of the path, which does not count
1496 // the trust anchor. (Although in practice it doesn't really change behaviors
1497 // if n is used in place of n+1).
1498 const size_t n = certs.size() - 1;
1499
1500 valid_policy_graph_.Init();
1501
1502 // RFC 5280 section section 6.1.2:
1503 //
1504 // If initial-explicit-policy is set, then the initial value
1505 // [of explicit_policy] is 0, otherwise the initial value is n+1.
1506 explicit_policy_ =
1507 initial_explicit_policy == InitialExplicitPolicy::kTrue ? 0 : n + 1;
1508
1509 // RFC 5280 section section 6.1.2:
1510 //
1511 // If initial-any-policy-inhibit is set, then the initial value
1512 // [of inhibit_anyPolicy] is 0, otherwise the initial value is n+1.
1513 inhibit_any_policy_ =
1514 initial_any_policy_inhibit == InitialAnyPolicyInhibit::kTrue ? 0 : n + 1;
1515
1516 // RFC 5280 section section 6.1.2:
1517 //
1518 // If initial-policy-mapping-inhibit is set, then the initial value
1519 // [of policy_mapping] is 0, otherwise the initial value is n+1.
1520 policy_mapping_ =
1521 initial_policy_mapping_inhibit == InitialPolicyMappingInhibit::kTrue
1522 ? 0
1523 : n + 1;
1524
1525 // RFC 5280 section section 6.1.2:
1526 //
1527 // max_path_length: this integer is initialized to n, ...
1528 max_path_length_ = n;
1529
1530 // Iterate over all the certificates in the reverse direction: starting from
1531 // the root certificate and progressing towards the target certificate.
1532 //
1533 // * i=0 : Root certificate (i.e. trust anchor)
1534 // * i=1 : Certificate issued by root
1535 // * i=x : Certificate i=x is issued by certificate i=x-1
1536 // * i=n : Target certificate.
1537 for (size_t i = 0; i < certs.size(); ++i) {
1538 const size_t index_into_certs = certs.size() - i - 1;
1539
1540 // |is_target_cert| is true if the current certificate is the target
1541 // certificate being verified. The target certificate isn't necessarily an
1542 // end-entity certificate.
1543 const bool is_target_cert = index_into_certs == 0;
1544 const bool is_target_cert_issuer = index_into_certs == 1;
1545 const bool is_root_cert = i == 0;
1546
1547 const ParsedCertificate& cert = *certs[index_into_certs];
1548
1549 // Output errors for the current certificate into an error bucket that is
1550 // associated with that certificate.
1551 CertErrors* cert_errors = errors->GetErrorsForCert(index_into_certs);
1552
1553 if (is_root_cert) {
1554 bool shortcircuit_chain_validation = false;
1555 ProcessRootCertificate(cert, last_cert_trust, time, required_key_purpose,
1556 cert_errors, &shortcircuit_chain_validation);
1557 if (shortcircuit_chain_validation) {
1558 // Chains that don't start from a trusted root should short-circuit the
1559 // rest of the verification, as accumulating more errors from untrusted
1560 // certificates would not be meaningful.
1561 BSSL_CHECK(cert_errors->ContainsAnyErrorWithSeverity(
1562 CertError::SEVERITY_HIGH));
1563 return;
1564 }
1565
1566 // Don't do any other checks for root certificates.
1567 continue;
1568 }
1569
1570 bool shortcircuit_chain_validation = false;
1571 // Per RFC 5280 section 6.1:
1572 // * Do basic processing for each certificate
1573 // * If it is the last certificate in the path (target certificate)
1574 // - Then run "Wrap up"
1575 // - Otherwise run "Prepare for Next cert"
1576 BasicCertificateProcessing(cert, is_target_cert, is_target_cert_issuer,
1577 time, required_key_purpose, cert_errors,
1578 &shortcircuit_chain_validation);
1579 if (shortcircuit_chain_validation) {
1580 // Signature errors should short-circuit the rest of the verification, as
1581 // accumulating more errors from untrusted certificates would not be
1582 // meaningful.
1583 BSSL_CHECK(
1584 cert_errors->ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH));
1585 return;
1586 }
1587 if (!is_target_cert) {
1588 PrepareForNextCertificate(cert, cert_errors);
1589 } else {
1590 WrapUp(cert, required_key_purpose, user_initial_policy_set, cert_errors);
1591 }
1592 }
1593
1594 if (user_constrained_policy_set) {
1595 *user_constrained_policy_set = user_constrained_policy_set_;
1596 }
1597
1598 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
1599 //
1600 // A certificate MUST NOT appear more than once in a prospective
1601 // certification path.
1602 }
1603
1604 } // namespace
1605
1606 VerifyCertificateChainDelegate::~VerifyCertificateChainDelegate() = default;
1607
VerifyCertificateChain(const ParsedCertificateList & certs,const CertificateTrust & last_cert_trust,VerifyCertificateChainDelegate * delegate,const der::GeneralizedTime & time,KeyPurpose required_key_purpose,InitialExplicitPolicy initial_explicit_policy,const std::set<der::Input> & user_initial_policy_set,InitialPolicyMappingInhibit initial_policy_mapping_inhibit,InitialAnyPolicyInhibit initial_any_policy_inhibit,std::set<der::Input> * user_constrained_policy_set,CertPathErrors * errors)1608 void VerifyCertificateChain(
1609 const ParsedCertificateList& certs,
1610 const CertificateTrust& last_cert_trust,
1611 VerifyCertificateChainDelegate* delegate,
1612 const der::GeneralizedTime& time,
1613 KeyPurpose required_key_purpose,
1614 InitialExplicitPolicy initial_explicit_policy,
1615 const std::set<der::Input>& user_initial_policy_set,
1616 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
1617 InitialAnyPolicyInhibit initial_any_policy_inhibit,
1618 std::set<der::Input>* user_constrained_policy_set,
1619 CertPathErrors* errors) {
1620 PathVerifier verifier;
1621 verifier.Run(certs, last_cert_trust, delegate, time, required_key_purpose,
1622 initial_explicit_policy, user_initial_policy_set,
1623 initial_policy_mapping_inhibit, initial_any_policy_inhibit,
1624 user_constrained_policy_set, errors);
1625 }
1626
VerifyCertificateIsSelfSigned(const ParsedCertificate & cert,SignatureVerifyCache * cache,CertErrors * errors)1627 bool VerifyCertificateIsSelfSigned(const ParsedCertificate& cert,
1628 SignatureVerifyCache* cache,
1629 CertErrors* errors) {
1630 if (cert.normalized_subject() != cert.normalized_issuer()) {
1631 if (errors) {
1632 errors->AddError(cert_errors::kSubjectDoesNotMatchIssuer);
1633 }
1634 return false;
1635 }
1636
1637 // Note that we do not restrict the available algorithms when determining if
1638 // something is a self-signed cert. The signature isn't very important on a
1639 // self-signed cert so just allow any supported algorithm here, to avoid
1640 // breakage.
1641 if (!cert.signature_algorithm().has_value()) {
1642 if (errors) {
1643 errors->AddError(cert_errors::kUnacceptableSignatureAlgorithm);
1644 }
1645 return false;
1646 }
1647
1648 if (!VerifySignedData(*cert.signature_algorithm(), cert.tbs_certificate_tlv(),
1649 cert.signature_value(), cert.tbs().spki_tlv, cache)) {
1650 if (errors) {
1651 errors->AddError(cert_errors::kVerifySignedDataFailed);
1652 }
1653 return false;
1654 }
1655
1656 return true;
1657 }
1658
1659 } // namespace net
1660