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