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