1 // Copyright 2019 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_CRL_H_ 6 #define BSSL_PKI_CRL_H_ 7 8 #include "fillins/openssl_util.h" 9 10 #include "general_names.h" 11 #include "parsed_certificate.h" 12 #include "input.h" 13 #include "parse_values.h" 14 #include <optional> 15 16 namespace bssl { 17 18 struct ParsedCrlTbsCertList; 19 struct ParsedDistributionPoint; 20 21 // TODO(https://crbug.com/749276): This is the same enum with the same meaning 22 // as OCSPRevocationStatus, maybe they should be merged? 23 enum class CRLRevocationStatus { 24 GOOD = 0, 25 REVOKED = 1, 26 UNKNOWN = 2, 27 MAX_VALUE = UNKNOWN 28 }; 29 30 // Parses a DER-encoded CRL "CertificateList" as specified by RFC 5280 Section 31 // 5.1. Returns true on success and sets the results in the |out_*| parameters. 32 // The contents of the output data is not validated. 33 // 34 // Note that on success the out parameters alias data from the input |crl_tlv|. 35 // Hence the output values are only valid as long as |crl_tlv| remains valid. 36 // 37 // On failure the out parameters have an undefined state. Some of them may have 38 // been updated during parsing, whereas others may not have been changed. 39 // 40 // CertificateList ::= SEQUENCE { 41 // tbsCertList TBSCertList, 42 // signatureAlgorithm AlgorithmIdentifier, 43 // signatureValue BIT STRING } 44 [[nodiscard]] OPENSSL_EXPORT bool ParseCrlCertificateList( 45 const der::Input& crl_tlv, 46 der::Input* out_tbs_cert_list_tlv, 47 der::Input* out_signature_algorithm_tlv, 48 der::BitString* out_signature_value); 49 50 // Parses a DER-encoded "TBSCertList" as specified by RFC 5280 Section 5.1. 51 // Returns true on success and sets the results in |out|. 52 // 53 // Note that on success |out| aliases data from the input |tbs_tlv|. 54 // Hence the fields of the ParsedCrlTbsCertList are only valid as long as 55 // |tbs_tlv| remains valid. 56 // 57 // On failure |out| has an undefined state. Some of its fields may have been 58 // updated during parsing, whereas others may not have been changed. 59 // 60 // Refer to the per-field documentation of ParsedCrlTbsCertList for details on 61 // what validity checks parsing performs. 62 // 63 // TBSCertList ::= SEQUENCE { 64 // version Version OPTIONAL, 65 // -- if present, MUST be v2 66 // signature AlgorithmIdentifier, 67 // issuer Name, 68 // thisUpdate Time, 69 // nextUpdate Time OPTIONAL, 70 // revokedCertificates SEQUENCE OF SEQUENCE { 71 // userCertificate CertificateSerialNumber, 72 // revocationDate Time, 73 // crlEntryExtensions Extensions OPTIONAL 74 // -- if present, version MUST be v2 75 // } OPTIONAL, 76 // crlExtensions [0] EXPLICIT Extensions OPTIONAL 77 // -- if present, version MUST be v2 78 // } 79 [[nodiscard]] OPENSSL_EXPORT bool ParseCrlTbsCertList( 80 const der::Input& tbs_tlv, 81 ParsedCrlTbsCertList* out); 82 83 // Represents a CRL "Version" from RFC 5280. TBSCertList reuses the same 84 // Version definition from TBSCertificate, however only v1(not present) and 85 // v2(1) are valid values, so a unique enum is used to avoid confusion. 86 enum class CrlVersion { 87 V1, 88 V2, 89 }; 90 91 // Corresponds with "TBSCertList" from RFC 5280 Section 5.1: 92 struct OPENSSL_EXPORT ParsedCrlTbsCertList { 93 ParsedCrlTbsCertList(); 94 ~ParsedCrlTbsCertList(); 95 96 // version Version OPTIONAL, 97 // -- if present, MUST be v2 98 // 99 // Parsing guarantees that the version is one of v1 or v2. 100 CrlVersion version = CrlVersion::V1; 101 102 // signature AlgorithmIdentifier, 103 // 104 // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No 105 // guarantees are made regarding the value of this SEQUENCE. 106 // 107 // This can be further parsed using SignatureValue::Create(). 108 der::Input signature_algorithm_tlv; 109 110 // issuer Name, 111 // 112 // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No 113 // guarantees are made regarding the value of this SEQUENCE. 114 der::Input issuer_tlv; 115 116 // thisUpdate Time, 117 // nextUpdate Time OPTIONAL, 118 // 119 // Parsing guarantees that thisUpdate and nextUpdate(if present) are valid 120 // DER-encoded dates, however it DOES NOT guarantee anything about their 121 // values. For instance notAfter could be before notBefore, or the dates 122 // could indicate an expired CRL. 123 der::GeneralizedTime this_update; 124 std::optional<der::GeneralizedTime> next_update; 125 126 // revokedCertificates SEQUENCE OF SEQUENCE { 127 // userCertificate CertificateSerialNumber, 128 // revocationDate Time, 129 // crlEntryExtensions Extensions OPTIONAL 130 // -- if present, version MUST be v2 131 // } OPTIONAL, 132 // 133 // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No 134 // guarantees are made regarding the value of this SEQUENCE. 135 std::optional<der::Input> revoked_certificates_tlv; 136 137 // crlExtensions [0] EXPLICIT Extensions OPTIONAL 138 // -- if present, version MUST be v2 139 // 140 // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No 141 // guarantees are made regarding the value of this SEQUENCE. (Note that the 142 // EXPLICIT outer tag is stripped.) 143 // 144 // Parsing guarantees that if extensions is present the version is v2. 145 std::optional<der::Input> crl_extensions_tlv; 146 }; 147 148 // Represents the IssuingDistributionPoint certificate type constraints: 149 enum class ContainedCertsType { 150 // Neither onlyContainsUserCerts or onlyContainsCACerts was present. 151 ANY_CERTS, 152 // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, 153 USER_CERTS, 154 // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, 155 CA_CERTS, 156 }; 157 158 // Parses a DER-encoded IssuingDistributionPoint extension value. 159 // Returns true on success and sets the results in the |out_*| parameters. 160 // 161 // If the IssuingDistributionPoint contains a distributionPoint fullName field, 162 // |out_distribution_point_names| will contain the parsed representation. 163 // If the distributionPoint type is nameRelativeToCRLIssuer, parsing will fail. 164 // 165 // |out_only_contains_cert_type| will contain the logical representation of the 166 // onlyContainsUserCerts and onlyContainsCACerts fields (or their absence). 167 // 168 // indirectCRL and onlyContainsAttributeCerts are not supported and parsing will 169 // fail if they are present. 170 // 171 // Note that on success |out_distribution_point_names| aliases data from the 172 // input |extension_value|. 173 // 174 // On failure the |out_*| parameters have undefined state. 175 // 176 // IssuingDistributionPoint ::= SEQUENCE { 177 // distributionPoint [0] DistributionPointName OPTIONAL, 178 // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, 179 // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, 180 // onlySomeReasons [3] ReasonFlags OPTIONAL, 181 // indirectCRL [4] BOOLEAN DEFAULT FALSE, 182 // onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } 183 [[nodiscard]] OPENSSL_EXPORT bool ParseIssuingDistributionPoint( 184 const der::Input& extension_value, 185 std::unique_ptr<GeneralNames>* out_distribution_point_names, 186 ContainedCertsType* out_only_contains_cert_type); 187 188 OPENSSL_EXPORT CRLRevocationStatus 189 GetCRLStatusForCert(const der::Input& cert_serial, 190 CrlVersion crl_version, 191 const std::optional<der::Input>& revoked_certificates_tlv); 192 193 // Checks the revocation status of the certificate |cert| by using the 194 // DER-encoded |raw_crl|. |cert| must already have passed certificate path 195 // validation. 196 // 197 // Returns GOOD if the CRL indicates the certificate is not revoked, 198 // REVOKED if it indicates it is revoked, or UNKNOWN for all other cases. 199 // 200 // * |raw_crl|: A DER encoded CRL CertificateList. 201 // * |valid_chain|: The validated certificate chain containing the target cert. 202 // * |target_cert_index|: The index into |valid_chain| of the certificate being 203 // checked for revocation. 204 // * |cert_dp|: The distribution point from the target certificate's CRL 205 // distribution points extension that |raw_crl| corresponds to. If 206 // |raw_crl| was not specified in a distribution point, the caller must 207 // synthesize a ParsedDistributionPoint object as specified by RFC 5280 208 // 6.3.3. 209 // * |verify_time_epoch_seconds|: The time as the difference in seconds from 210 // the POSIX epoch to use when checking revocation status. 211 // * |max_age_seconds|: If present, the maximum age in seconds for a CRL, 212 // implemented as time since the |thisUpdate| field in the CRL 213 // TBSCertList. Responses older than |max_age_seconds| will be 214 // considered invalid. 215 [[nodiscard]] OPENSSL_EXPORT CRLRevocationStatus 216 CheckCRL(std::string_view raw_crl, 217 const ParsedCertificateList& valid_chain, 218 size_t target_cert_index, 219 const ParsedDistributionPoint& cert_dp, 220 int64_t verify_time_epoch_seconds, 221 std::optional<int64_t> max_age_seconds); 222 223 } // namespace net 224 225 #endif // BSSL_PKI_CRL_H_ 226