| // 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" | 
 |  | 
 | namespace bssl { | 
 |  | 
 | 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 { | 
 |   GOOD = 0, | 
 |   REVOKED = 1, | 
 |   UNKNOWN = 2, | 
 |   MAX_VALUE = UNKNOWN | 
 | }; | 
 |  | 
 | // 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 { | 
 |   V1, | 
 |   V2, | 
 | }; | 
 |  | 
 | // Corresponds with "TBSCertList" from RFC 5280 Section 5.1: | 
 | struct OPENSSL_EXPORT ParsedCrlTbsCertList { | 
 |   ParsedCrlTbsCertList(); | 
 |   ~ParsedCrlTbsCertList(); | 
 |  | 
 |   //         version                 Version OPTIONAL, | 
 |   //                                      -- if present, MUST be v2 | 
 |   // | 
 |   // Parsing guarantees that the version is one of v1 or v2. | 
 |   CrlVersion version = CrlVersion::V1; | 
 |  | 
 |   //         signature               AlgorithmIdentifier, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   // | 
 |   // This can be further parsed using SignatureValue::Create(). | 
 |   der::Input signature_algorithm_tlv; | 
 |  | 
 |   //         issuer               Name, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   der::Input issuer_tlv; | 
 |  | 
 |   //         thisUpdate              Time, | 
 |   //         nextUpdate              Time OPTIONAL, | 
 |   // | 
 |   // Parsing guarantees that thisUpdate and nextUpdate(if present) are valid | 
 |   // DER-encoded dates, however it DOES NOT guarantee anything about their | 
 |   // values. For instance notAfter could be before notBefore, or the dates | 
 |   // could indicate an expired CRL. | 
 |   der::GeneralizedTime this_update; | 
 |   std::optional<der::GeneralizedTime> next_update; | 
 |  | 
 |   //         revokedCertificates     SEQUENCE OF SEQUENCE  { | 
 |   //              userCertificate         CertificateSerialNumber, | 
 |   //              revocationDate          Time, | 
 |   //              crlEntryExtensions      Extensions OPTIONAL | 
 |   //                                       -- if present, version MUST be v2 | 
 |   //                                   }  OPTIONAL, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   std::optional<der::Input> revoked_certificates_tlv; | 
 |  | 
 |   //         crlExtensions           [0]  EXPLICIT Extensions OPTIONAL | 
 |   //                                       -- if present, version MUST be v2 | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. (Note that the | 
 |   // EXPLICIT outer tag is stripped.) | 
 |   // | 
 |   // Parsing guarantees that if extensions is present the version is v2. | 
 |   std::optional<der::Input> crl_extensions_tlv; | 
 | }; | 
 |  | 
 | // Represents the IssuingDistributionPoint certificate type constraints: | 
 | enum class ContainedCertsType { | 
 |   // Neither onlyContainsUserCerts or onlyContainsCACerts was present. | 
 |   ANY_CERTS, | 
 |   // onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE, | 
 |   USER_CERTS, | 
 |   // onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE, | 
 |   CA_CERTS, | 
 | }; | 
 |  | 
 | // 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); | 
 |  | 
 | }  // namespace bssl | 
 |  | 
 | #endif  // BSSL_PKI_CRL_H_ |