• 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 #ifndef NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_H_
6 #define NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_H_
7 
8 #include <set>
9 
10 #include "net/base/net_export.h"
11 #include "net/cert/pki/cert_errors.h"
12 #include "net/cert/pki/parsed_certificate.h"
13 #include "net/cert/pki/signature_verify_cache.h"
14 #include "net/der/input.h"
15 #include "third_party/boringssl/src/include/openssl/evp.h"
16 
17 namespace net {
18 
19 namespace der {
20 struct GeneralizedTime;
21 }
22 
23 struct CertificateTrust;
24 
25 // The key purpose (extended key usage) to check for during verification.
26 enum class KeyPurpose {
27   ANY_EKU,
28   SERVER_AUTH,
29   CLIENT_AUTH,
30   SERVER_AUTH_STRICT,  // Skip ANY_EKU when checking, require EKU present in
31                        // certificate.
32   CLIENT_AUTH_STRICT,  // Skip ANY_EKU when checking, require EKU present in
33                        // certificate.
34 };
35 
36 enum class InitialExplicitPolicy {
37   kFalse,
38   kTrue,
39 };
40 
41 enum class InitialPolicyMappingInhibit {
42   kFalse,
43   kTrue,
44 };
45 
46 enum class InitialAnyPolicyInhibit {
47   kFalse,
48   kTrue,
49 };
50 
51 // VerifyCertificateChainDelegate exposes delegate methods used when verifying a
52 // chain.
53 class NET_EXPORT VerifyCertificateChainDelegate {
54  public:
55   // Implementations should return true if |signature_algorithm| is allowed for
56   // certificate signing, false otherwise. When returning false implementations
57   // can optionally add high-severity errors to |errors| with details on why it
58   // was rejected.
59   virtual bool IsSignatureAlgorithmAcceptable(
60       SignatureAlgorithm signature_algorithm,
61       CertErrors* errors) = 0;
62 
63   // Implementations should return true if |public_key| is acceptable. This is
64   // called for each certificate in the chain, including the target certificate.
65   // When returning false implementations can optionally add high-severity
66   // errors to |errors| with details on why it was rejected.
67   //
68   // |public_key| can be assumed to be non-null.
69   virtual bool IsPublicKeyAcceptable(EVP_PKEY* public_key,
70                                      CertErrors* errors) = 0;
71 
72   // This is called during verification to obtain a pointer to a signature
73   // verification cache if one exists. nullptr may be returned indicating there
74   // is no verification cache.
75   virtual SignatureVerifyCache* GetVerifyCache() = 0;
76 
77   virtual ~VerifyCertificateChainDelegate();
78 };
79 
80 // VerifyCertificateChain() verifies an ordered certificate path in accordance
81 // with RFC 5280's "Certification Path Validation" algorithm (section 6).
82 //
83 // -----------------------------------------
84 // Deviations from RFC 5280
85 // -----------------------------------------
86 //
87 //   * If Extended Key Usage appears on intermediates, it is treated as
88 //     a restriction on subordinate certificates.
89 //   * No revocation checking is performed.
90 //
91 // -----------------------------------------
92 // Additional responsibilities of the caller
93 // -----------------------------------------
94 //
95 // After successful path verification, the caller is responsible for
96 // subsequently checking:
97 //
98 //  * The end-entity's KeyUsage before using its SPKI.
99 //  * The end-entity's name/subjectAltName. Name constraints from intermediates
100 //    will have already been applied, so it is sufficient to check the
101 //    end-entity for a match. The caller MUST NOT check hostnames on the
102 //    commonName field because this implementation does not apply dnsName
103 //    constraints on commonName.
104 //
105 // ---------
106 // Inputs
107 // ---------
108 //
109 //   certs:
110 //     A non-empty chain of DER-encoded certificates, listed in the
111 //     "forward" direction. The first certificate is the target
112 //     certificate to verify, and the last certificate has trustedness
113 //     given by |last_cert_trust| (generally a trust anchor).
114 //
115 //      * certs[0] is the target certificate to verify.
116 //      * certs[i+1] holds the certificate that issued cert_chain[i].
117 //      * certs[N-1] the root certificate
118 //
119 //     Note that THIS IS NOT identical in meaning to the same named
120 //     "certs" input defined in RFC 5280 section 6.1.1.a. The differences
121 //     are:
122 //
123 //      * The order of certificates is reversed
124 //      * In RFC 5280 "certs" DOES NOT include the trust anchor
125 //
126 //   last_cert_trust:
127 //     Trustedness of |certs.back()|. The trustedness of |certs.back()|
128 //     MUST BE decided by the caller -- this function takes it purely as
129 //     an input. Moreover, the CertificateTrust can be used to specify
130 //     trust anchor constraints.
131 //
132 //     This combined with |certs.back()| (the root certificate) fills a
133 //     similar role to "trust anchor information" defined in RFC 5280
134 //     section 6.1.1.d.
135 //
136 //   delegate:
137 //     |delegate| must be non-null. It is used to answer policy questions such
138 //     as whether a signature algorithm is acceptable, or a public key is strong
139 //     enough.
140 //
141 //   time:
142 //     The UTC time to use for expiration checks. This is equivalent to
143 //     the input from RFC 5280 section 6.1.1:
144 //
145 //       (b)  the current date/time.
146 //
147 //   required_key_purpose:
148 //     The key purpose that the target certificate needs to be valid for.
149 //
150 //   user_initial_policy_set:
151 //     This is equivalent to the same named input in RFC 5280 section
152 //     6.1.1:
153 //
154 //       (c)  user-initial-policy-set: A set of certificate policy
155 //            identifiers naming the policies that are acceptable to the
156 //            certificate user. The user-initial-policy-set contains the
157 //            special value any-policy if the user is not concerned about
158 //            certificate policy.
159 //
160 //   initial_policy_mapping_inhibit:
161 //     This is equivalent to the same named input in RFC 5280 section
162 //     6.1.1:
163 //
164 //       (e)  initial-policy-mapping-inhibit, which indicates if policy
165 //            mapping is allowed in the certification path.
166 //
167 //   initial_explicit_policy:
168 //     This is equivalent to the same named input in RFC 5280 section
169 //     6.1.1:
170 //
171 //       (f)  initial-explicit-policy, which indicates if the path must be
172 //            valid for at least one of the certificate policies in the
173 //            user-initial-policy-set.
174 //
175 //   initial_any_policy_inhibit:
176 //     This is equivalent to the same named input in RFC 5280 section
177 //     6.1.1:
178 //
179 //       (g)  initial-any-policy-inhibit, which indicates whether the
180 //            anyPolicy OID should be processed if it is included in a
181 //            certificate.
182 //
183 // ---------
184 // Outputs
185 // ---------
186 //
187 //   user_constrained_policy_set:
188 //     Can be null. If non-null, |user_constrained_policy_set| will be filled
189 //     with the matching policies (intersected with user_initial_policy_set).
190 //     This is equivalent to the same named output in X.509 section 10.2.
191 //     Note that it is OK for this to point to input user_initial_policy_set.
192 //
193 //   errors:
194 //     Must be non-null. The set of errors/warnings encountered while
195 //     validating the path are appended to this structure. If verification
196 //     failed, then there is guaranteed to be at least 1 high severity error
197 //     written to |errors|.
198 //
199 // -------------------------
200 // Trust Anchor constraints
201 // -------------------------
202 //
203 // Conceptually, VerifyCertificateChain() sets RFC 5937's
204 // "enforceTrustAnchorConstraints" to true.
205 //
206 // One specifies trust anchor constraints using the |last_cert_trust|
207 // parameter in conjunction with extensions appearing in |certs.back()|.
208 //
209 // The trust anchor |certs.back()| is always passed as a certificate to
210 // this function, however the manner in which that certificate is
211 // interpreted depends on |last_cert_trust|:
212 //
213 // TRUSTED_ANCHOR:
214 //
215 // No properties from the root certificate, other than its Subject and
216 // SPKI, are checked during verification. This is the usual
217 // interpretation for a "trust anchor".
218 //
219 // enforce_anchor_expiry=true:
220 //
221 // The validity period of the root is checked, in addition to Subject and SPKI.
222 //
223 // enforce_anchor_constraints=true:
224 //
225 // Only a subset of extensions and properties from the certificate are checked.
226 // In general, constraints encoded by extensions are only enforced if the
227 // extension is present.
228 //
229 //  * Signature:             No
230 //  * Validity (expiration): No
231 //  * Key usage:             Yes
232 //  * Extended key usage:    Yes (required if required_key_purpose is STRICT)
233 //  * Basic constraints:     Yes
234 //  * Name constraints:      Yes
235 //  * Certificate policies:  Yes
236 //  * Policy Mappings:       Yes
237 //  * inhibitAnyPolicy:      Yes
238 //  * PolicyConstraints:     Yes
239 //
240 // The presence of any other unrecognized extension marked as critical fails
241 // validation.
242 NET_EXPORT void VerifyCertificateChain(
243     const ParsedCertificateList& certs,
244     const CertificateTrust& last_cert_trust,
245     VerifyCertificateChainDelegate* delegate,
246     const der::GeneralizedTime& time,
247     KeyPurpose required_key_purpose,
248     InitialExplicitPolicy initial_explicit_policy,
249     const std::set<der::Input>& user_initial_policy_set,
250     InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
251     InitialAnyPolicyInhibit initial_any_policy_inhibit,
252     std::set<der::Input>* user_constrained_policy_set,
253     CertPathErrors* errors);
254 
255 // Returns true if `cert` is self-signed. Returns false `cert` is not
256 // self-signed or there was an error. If `errors` is non-null, it will contain
257 // additional information about the problem. If `cache` is non-null, it will be
258 // used to cache the signature verification step.
259 NET_EXPORT bool VerifyCertificateIsSelfSigned(const ParsedCertificate& cert,
260                                               SignatureVerifyCache* cache,
261                                               CertErrors* errors);
262 
263 }  // namespace net
264 
265 #endif  // NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_H_
266