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