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