blob: d527de940c8b1c4716fb7169068748da95d227bf [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// 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
Bob Beck5c7a2a02023-11-20 17:28:21 -07008#include <optional>
Bob Beck3cd30cc2023-11-22 16:59:00 -07009
10#include <openssl/base.h>
11
Bob Beckbc97b7a2023-04-18 08:35:15 -060012#include "general_names.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060013#include "input.h"
14#include "parse_values.h"
Bob Beck5c7a2a02023-11-20 17:28:21 -070015#include "parsed_certificate.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060016
17namespace bssl {
18
19struct ParsedCrlTbsCertList;
20struct ParsedDistributionPoint;
21
22// TODO(https://crbug.com/749276): This is the same enum with the same meaning
23// as OCSPRevocationStatus, maybe they should be merged?
24enum class CRLRevocationStatus {
25 GOOD = 0,
26 REVOKED = 1,
27 UNKNOWN = 2,
28 MAX_VALUE = UNKNOWN
29};
30
31// Parses a DER-encoded CRL "CertificateList" as specified by RFC 5280 Section
32// 5.1. Returns true on success and sets the results in the |out_*| parameters.
33// The contents of the output data is not validated.
34//
35// Note that on success the out parameters alias data from the input |crl_tlv|.
36// Hence the output values are only valid as long as |crl_tlv| remains valid.
37//
38// On failure the out parameters have an undefined state. Some of them may have
39// been updated during parsing, whereas others may not have been changed.
40//
41// CertificateList ::= SEQUENCE {
42// tbsCertList TBSCertList,
43// signatureAlgorithm AlgorithmIdentifier,
44// signatureValue BIT STRING }
45[[nodiscard]] OPENSSL_EXPORT bool ParseCrlCertificateList(
David Benjamin81138bc2024-01-23 14:53:40 -050046 der::Input crl_tlv, der::Input *out_tbs_cert_list_tlv,
Bob Beck5c7a2a02023-11-20 17:28:21 -070047 der::Input *out_signature_algorithm_tlv,
48 der::BitString *out_signature_value);
Bob Beckbc97b7a2023-04-18 08:35:15 -060049
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(
David Benjamin81138bc2024-01-23 14:53:40 -050080 der::Input tbs_tlv, ParsedCrlTbsCertList *out);
Bob Beckbc97b7a2023-04-18 08:35:15 -060081
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.
85enum class CrlVersion {
86 V1,
87 V2,
88};
89
90// Corresponds with "TBSCertList" from RFC 5280 Section 5.1:
91struct OPENSSL_EXPORT 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 std::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 std::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 std::optional<der::Input> crl_extensions_tlv;
145};
146
147// Represents the IssuingDistributionPoint certificate type constraints:
148enum 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]] OPENSSL_EXPORT bool ParseIssuingDistributionPoint(
David Benjamin81138bc2024-01-23 14:53:40 -0500183 der::Input extension_value,
Bob Beck5c7a2a02023-11-20 17:28:21 -0700184 std::unique_ptr<GeneralNames> *out_distribution_point_names,
185 ContainedCertsType *out_only_contains_cert_type);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600186
187OPENSSL_EXPORT CRLRevocationStatus
David Benjamin81138bc2024-01-23 14:53:40 -0500188GetCRLStatusForCert(der::Input cert_serial, CrlVersion crl_version,
Bob Beck5c7a2a02023-11-20 17:28:21 -0700189 const std::optional<der::Input> &revoked_certificates_tlv);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600190
191// Checks the revocation status of the certificate |cert| by using the
192// DER-encoded |raw_crl|. |cert| must already have passed certificate path
193// validation.
194//
195// Returns GOOD if the CRL indicates the certificate is not revoked,
196// REVOKED if it indicates it is revoked, or UNKNOWN for all other cases.
197//
198// * |raw_crl|: A DER encoded CRL CertificateList.
199// * |valid_chain|: The validated certificate chain containing the target cert.
200// * |target_cert_index|: The index into |valid_chain| of the certificate being
201// checked for revocation.
202// * |cert_dp|: The distribution point from the target certificate's CRL
203// distribution points extension that |raw_crl| corresponds to. If
204// |raw_crl| was not specified in a distribution point, the caller must
205// synthesize a ParsedDistributionPoint object as specified by RFC 5280
206// 6.3.3.
207// * |verify_time_epoch_seconds|: The time as the difference in seconds from
208// the POSIX epoch to use when checking revocation status.
209// * |max_age_seconds|: If present, the maximum age in seconds for a CRL,
210// implemented as time since the |thisUpdate| field in the CRL
211// TBSCertList. Responses older than |max_age_seconds| will be
212// considered invalid.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700213[[nodiscard]] OPENSSL_EXPORT CRLRevocationStatus CheckCRL(
214 std::string_view raw_crl, const ParsedCertificateList &valid_chain,
215 size_t target_cert_index, const ParsedDistributionPoint &cert_dp,
216 int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600217
Bob Beck5c7a2a02023-11-20 17:28:21 -0700218} // namespace bssl
Bob Beckbc97b7a2023-04-18 08:35:15 -0600219
220#endif // BSSL_PKI_CRL_H_