• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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