// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BSSL_PKI_CRL_H_ #define BSSL_PKI_CRL_H_ #include <optional> #include <openssl/base.h> #include "general_names.h" #include "input.h" #include "parse_values.h" #include "parsed_certificate.h" BSSL_NAMESPACE_BEGIN struct ParsedCrlTbsCertList; struct ParsedDistributionPoint; // TODO(https://crbug.com/749276): This is the same enum with the same meaning // as OCSPRevocationStatus, maybe they should be merged? enum class CRLRevocationStatus { … }; // Parses a DER-encoded CRL "CertificateList" as specified by RFC 5280 Section // 5.1. Returns true on success and sets the results in the |out_*| parameters. // The contents of the output data is not validated. // // Note that on success the out parameters alias data from the input |crl_tlv|. // Hence the output values are only valid as long as |crl_tlv| remains valid. // // On failure the out parameters have an undefined state. Some of them may have // been updated during parsing, whereas others may not have been changed. // // CertificateList ::= SEQUENCE { // tbsCertList TBSCertList, // signatureAlgorithm AlgorithmIdentifier, // signatureValue BIT STRING } [[nodiscard]] OPENSSL_EXPORT bool ParseCrlCertificateList( der::Input crl_tlv, der::Input *out_tbs_cert_list_tlv, der::Input *out_signature_algorithm_tlv, der::BitString *out_signature_value); // Parses a DER-encoded "TBSCertList" as specified by RFC 5280 Section 5.1. // Returns true on success and sets the results in |out|. // // Note that on success |out| aliases data from the input |tbs_tlv|. // Hence the fields of the ParsedCrlTbsCertList are only valid as long as // |tbs_tlv| remains valid. // // On failure |out| has an undefined state. Some of its fields may have been // updated during parsing, whereas others may not have been changed. // // Refer to the per-field documentation of ParsedCrlTbsCertList for details on // what validity checks parsing performs. // // TBSCertList ::= SEQUENCE { // version Version OPTIONAL, // -- if present, MUST be v2 // signature AlgorithmIdentifier, // issuer Name, // thisUpdate Time, // nextUpdate Time OPTIONAL, // revokedCertificates SEQUENCE OF SEQUENCE { // userCertificate CertificateSerialNumber, // revocationDate Time, // crlEntryExtensions Extensions OPTIONAL // -- if present, version MUST be v2 // } OPTIONAL, // crlExtensions [0] EXPLICIT Extensions OPTIONAL // -- if present, version MUST be v2 // } [[nodiscard]] OPENSSL_EXPORT bool ParseCrlTbsCertList( der::Input tbs_tlv, ParsedCrlTbsCertList *out); // Represents a CRL "Version" from RFC 5280. TBSCertList reuses the same // Version definition from TBSCertificate, however only v1(not present) and // v2(1) are valid values, so a unique enum is used to avoid confusion. enum class CrlVersion { … }; // Corresponds with "TBSCertList" from RFC 5280 Section 5.1: struct OPENSSL_EXPORT ParsedCrlTbsCertList { … }; // Represents the IssuingDistributionPoint certificate type constraints: enum class ContainedCertsType { … }; // Parses a DER-encoded IssuingDistributionPoint extension value. // Returns true on success and sets the results in the |out_*| parameters. // // If the IssuingDistributionPoint contains a distributionPoint fullName field, // |out_distribution_point_names| will contain the parsed representation. // If the distributionPoint type is nameRelativeToCRLIssuer, parsing will fail. // // |out_only_contains_cert_type| will contain the logical representation of the // onlyContainsUserCerts and onlyContainsCACerts fields (or their absence). // // indirectCRL and onlyContainsAttributeCerts are not supported and parsing will // fail if they are present. // // Note that on success |out_distribution_point_names| aliases data from the // input |extension_value|. // // On failure the |out_*| parameters have undefined state. // // IssuingDistributionPoint ::= SEQUENCE { // distributionPoint [0] DistributionPointName OPTIONAL, // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, // onlySomeReasons [3] ReasonFlags OPTIONAL, // indirectCRL [4] BOOLEAN DEFAULT FALSE, // onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } [[nodiscard]] OPENSSL_EXPORT bool ParseIssuingDistributionPoint( der::Input extension_value, std::unique_ptr<GeneralNames> *out_distribution_point_names, ContainedCertsType *out_only_contains_cert_type); OPENSSL_EXPORT CRLRevocationStatus GetCRLStatusForCert(der::Input cert_serial, CrlVersion crl_version, const std::optional<der::Input> &revoked_certificates_tlv); // Checks the revocation status of the certificate |cert| by using the // DER-encoded |raw_crl|. |cert| must already have passed certificate path // validation. // // Returns GOOD if the CRL indicates the certificate is not revoked, // REVOKED if it indicates it is revoked, or UNKNOWN for all other cases. // // * |raw_crl|: A DER encoded CRL CertificateList. // * |valid_chain|: The validated certificate chain containing the target cert. // * |target_cert_index|: The index into |valid_chain| of the certificate being // checked for revocation. // * |cert_dp|: The distribution point from the target certificate's CRL // distribution points extension that |raw_crl| corresponds to. If // |raw_crl| was not specified in a distribution point, the caller must // synthesize a ParsedDistributionPoint object as specified by RFC 5280 // 6.3.3. // * |verify_time_epoch_seconds|: The time as the difference in seconds from // the POSIX epoch to use when checking revocation status. // * |max_age_seconds|: If present, the maximum age in seconds for a CRL, // implemented as time since the |thisUpdate| field in the CRL // TBSCertList. Responses older than |max_age_seconds| will be // considered invalid. [[nodiscard]] OPENSSL_EXPORT CRLRevocationStatus CheckCRL( std::string_view raw_crl, const ParsedCertificateList &valid_chain, size_t target_cert_index, const ParsedDistributionPoint &cert_dp, int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds); BSSL_NAMESPACE_END #endif // BSSL_PKI_CRL_H_