xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/crl.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 <optional>
9 
10 #include <openssl/base.h>
11 
12 #include "general_names.h"
13 #include "input.h"
14 #include "parse_values.h"
15 #include "parsed_certificate.h"
16 
17 namespace bssl {
18 
19 struct ParsedCrlTbsCertList;
20 struct 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?
24 enum 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(
46     der::Input crl_tlv, 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     der::Input tbs_tlv, 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 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:
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]] OPENSSL_EXPORT bool ParseIssuingDistributionPoint(
183     der::Input extension_value,
184     std::unique_ptr<GeneralNames> *out_distribution_point_names,
185     ContainedCertsType *out_only_contains_cert_type);
186 
187 OPENSSL_EXPORT CRLRevocationStatus
188 GetCRLStatusForCert(der::Input cert_serial, CrlVersion crl_version,
189                     const std::optional<der::Input> &revoked_certificates_tlv);
190 
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.
213 [[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);
217 
218 }  // namespace bssl
219 
220 #endif  // BSSL_PKI_CRL_H_
221