xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/ocsp.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 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_OCSP_H_
6 #define BSSL_PKI_OCSP_H_
7 
8 #include <memory>
9 #include <optional>
10 #include <string>
11 #include <vector>
12 
13 #include <openssl/base.h>
14 
15 #include "input.h"
16 #include "ocsp_revocation_status.h"
17 #include "ocsp_verify_result.h"
18 #include "parse_values.h"
19 #include "parser.h"
20 #include "signature_algorithm.h"
21 
22 namespace bssl {
23 
24 class ParsedCertificate;
25 
26 // OCSPCertID contains a representation of a DER-encoded RFC 6960 "CertID".
27 //
28 // CertID ::= SEQUENCE {
29 //    hashAlgorithm           AlgorithmIdentifier,
30 //    issuerNameHash          OCTET STRING, -- Hash of issuer's DN
31 //    issuerKeyHash           OCTET STRING, -- Hash of issuer's public key
32 //    serialNumber            CertificateSerialNumber
33 // }
34 struct OPENSSL_EXPORT OCSPCertID {
35   OCSPCertID();
36   ~OCSPCertID();
37 
38   DigestAlgorithm hash_algorithm;
39   der::Input issuer_name_hash;
40   der::Input issuer_key_hash;
41   der::Input serial_number;
42 };
43 
44 // OCSPCertStatus contains a representation of a DER-encoded RFC 6960
45 // "CertStatus". |revocation_time| and |has_reason| are only valid when
46 // |status| is REVOKED. |revocation_reason| is only valid when |has_reason| is
47 // true.
48 //
49 // CertStatus ::= CHOICE {
50 //      good        [0]     IMPLICIT NULL,
51 //      revoked     [1]     IMPLICIT RevokedInfo,
52 //      unknown     [2]     IMPLICIT UnknownInfo
53 // }
54 //
55 // RevokedInfo ::= SEQUENCE {
56 //      revocationTime              GeneralizedTime,
57 //      revocationReason    [0]     EXPLICIT CRLReason OPTIONAL
58 // }
59 //
60 // UnknownInfo ::= NULL
61 //
62 // CRLReason ::= ENUMERATED {
63 //      unspecified             (0),
64 //      keyCompromise           (1),
65 //      cACompromise            (2),
66 //      affiliationChanged      (3),
67 //      superseded              (4),
68 //      cessationOfOperation    (5),
69 //      certificateHold         (6),
70 //           -- value 7 is not used
71 //      removeFromCRL           (8),
72 //      privilegeWithdrawn      (9),
73 //      aACompromise           (10)
74 // }
75 // (from RFC 5280)
76 struct OCSPCertStatus {
77   // Correspond to the values of CRLReason
78   enum class RevocationReason {
79     UNSPECIFIED = 0,
80     KEY_COMPROMISE = 1,
81     CA_COMPROMISE = 2,
82     AFFILIATION_CHANGED = 3,
83     SUPERSEDED = 4,
84     CESSATION_OF_OPERATION = 5,
85     CERTIFICATE_HOLD = 6,
86     UNUSED = 7,
87     REMOVE_FROM_CRL = 8,
88     PRIVILEGE_WITHDRAWN = 9,
89     AA_COMPROMISE = 10,
90 
91     LAST = AA_COMPROMISE,
92   };
93 
94   OCSPRevocationStatus status;
95   der::GeneralizedTime revocation_time;
96   bool has_reason;
97   RevocationReason revocation_reason;
98 };
99 
100 // OCSPSingleResponse contains a representation of a DER-encoded RFC 6960
101 // "SingleResponse". The |cert_id_tlv| and |extensions| fields are pointers to
102 // the original object and are only valid as long as it is alive. They also
103 // aren't verified until they are parsed. |next_update| is only valid if
104 // |has_next_update| is true and |extensions| is only valid if |has_extensions|
105 // is true.
106 //
107 // SingleResponse ::= SEQUENCE {
108 //      certID                       CertID,
109 //      certStatus                   CertStatus,
110 //      thisUpdate                   GeneralizedTime,
111 //      nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
112 //      singleExtensions   [1]       EXPLICIT Extensions OPTIONAL
113 // }
114 struct OPENSSL_EXPORT OCSPSingleResponse {
115   OCSPSingleResponse();
116   ~OCSPSingleResponse();
117 
118   der::Input cert_id_tlv;
119   OCSPCertStatus cert_status;
120   der::GeneralizedTime this_update;
121   bool has_next_update;
122   der::GeneralizedTime next_update;
123   bool has_extensions;
124   der::Input extensions;
125 };
126 
127 // OCSPResponseData contains a representation of a DER-encoded RFC 6960
128 // "ResponseData". The |responses| and |extensions| fields are pointers to the
129 // original object and are only valid as long as it is alive. They also aren't
130 // verified until they are parsed into OCSPSingleResponse and ParsedExtensions.
131 // |extensions| is only valid if |has_extensions| is true.
132 //
133 // ResponseData ::= SEQUENCE {
134 //      version              [0] EXPLICIT Version DEFAULT v1,
135 //      responderID              ResponderID,
136 //      producedAt               GeneralizedTime,
137 //      responses                SEQUENCE OF SingleResponse,
138 //      responseExtensions   [1] EXPLICIT Extensions OPTIONAL
139 // }
140 struct OPENSSL_EXPORT OCSPResponseData {
141   enum class ResponderType { NAME, KEY_HASH };
142 
143   struct ResponderID {
144     ResponderType type;
145     der::Input name;
146     der::Input key_hash;
147   };
148 
149   OCSPResponseData();
150   ~OCSPResponseData();
151 
152   uint8_t version;
153   OCSPResponseData::ResponderID responder_id;
154   der::GeneralizedTime produced_at;
155   std::vector<der::Input> responses;
156   bool has_extensions;
157   der::Input extensions;
158 };
159 
160 // OCSPResponse contains a representation of a DER-encoded RFC 6960
161 // "OCSPResponse" and the corresponding "BasicOCSPResponse". The |data| field
162 // is a pointer to the original object and are only valid as long is it is
163 // alive. The |data| field isn't verified until it is parsed into an
164 // OCSPResponseData. |data|, |signature_algorithm|, |signature|, and
165 // |has_certs| is only valid if |status| is SUCCESSFUL. |certs| is only valid
166 // if |has_certs| is true.
167 //
168 // OCSPResponse ::= SEQUENCE {
169 //      responseStatus         OCSPResponseStatus,
170 //      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL
171 // }
172 //
173 // ResponseBytes ::=       SEQUENCE {
174 //      responseType   OBJECT IDENTIFIER,
175 //      response       OCTET STRING
176 // }
177 //
178 // BasicOCSPResponse       ::= SEQUENCE {
179 //      tbsResponseData      ResponseData,
180 //      signatureAlgorithm   AlgorithmIdentifier,
181 //      signature            BIT STRING,
182 //      certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
183 // }
184 //
185 // OCSPResponseStatus ::= ENUMERATED {
186 //     successful            (0),  -- Response has valid confirmations
187 //     malformedRequest      (1),  -- Illegal confirmation request
188 //     internalError         (2),  -- Internal error in issuer
189 //     tryLater              (3),  -- Try again later
190 //                                 -- (4) is not used
191 //     sigRequired           (5),  -- Must sign the request
192 //     unauthorized          (6)   -- Request unauthorized
193 // }
194 struct OPENSSL_EXPORT OCSPResponse {
195   // Correspond to the values of OCSPResponseStatus
196   enum class ResponseStatus {
197     SUCCESSFUL = 0,
198     MALFORMED_REQUEST = 1,
199     INTERNAL_ERROR = 2,
200     TRY_LATER = 3,
201     UNUSED = 4,
202     SIG_REQUIRED = 5,
203     UNAUTHORIZED = 6,
204 
205     LAST = UNAUTHORIZED,
206   };
207 
208   OCSPResponse();
209   ~OCSPResponse();
210 
211   ResponseStatus status;
212   der::Input data;
213   SignatureAlgorithm signature_algorithm;
214   der::BitString signature;
215   bool has_certs;
216   std::vector<der::Input> certs;
217 };
218 
219 // From RFC 6960:
220 //
221 // id-pkix-ocsp           OBJECT IDENTIFIER ::= { id-ad-ocsp }
222 // id-pkix-ocsp-basic     OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
223 //
224 // In dotted notation: 1.3.6.1.5.5.7.48.1.1
225 inline constexpr uint8_t kBasicOCSPResponseOid[] = {
226     0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01};
227 
228 // Parses a DER-encoded OCSP "CertID" as specified by RFC 6960. Returns true on
229 // success and sets the results in |out|.
230 //
231 // On failure |out| has an undefined state. Some of its fields may have been
232 // updated during parsing, whereas others may not have been changed.
233 OPENSSL_EXPORT bool ParseOCSPCertID(der::Input raw_tlv, OCSPCertID *out);
234 
235 // Parses a DER-encoded OCSP "SingleResponse" as specified by RFC 6960. Returns
236 // true on success and sets the results in |out|. The resulting |out|
237 // references data from |raw_tlv| and is only valid for the lifetime of
238 // |raw_tlv|.
239 //
240 // On failure |out| has an undefined state. Some of its fields may have been
241 // updated during parsing, whereas others may not have been changed.
242 OPENSSL_EXPORT bool ParseOCSPSingleResponse(der::Input raw_tlv,
243                                             OCSPSingleResponse *out);
244 
245 // Parses a DER-encoded OCSP "ResponseData" as specified by RFC 6960. Returns
246 // true on success and sets the results in |out|. The resulting |out|
247 // references data from |raw_tlv| and is only valid for the lifetime of
248 // |raw_tlv|.
249 //
250 // On failure |out| has an undefined state. Some of its fields may have been
251 // updated during parsing, whereas others may not have been changed.
252 OPENSSL_EXPORT bool ParseOCSPResponseData(der::Input raw_tlv,
253                                           OCSPResponseData *out);
254 
255 // Parses a DER-encoded "OCSPResponse" as specified by RFC 6960. Returns true
256 // on success and sets the results in |out|. The resulting |out|
257 // references data from |raw_tlv| and is only valid for the lifetime of
258 // |raw_tlv|.
259 //
260 // On failure |out| has an undefined state. Some of its fields may have been
261 // updated during parsing, whereas others may not have been changed.
262 OPENSSL_EXPORT bool ParseOCSPResponse(der::Input raw_tlv, OCSPResponse *out);
263 
264 // Checks the revocation status of the certificate |certificate_der| by using
265 // the DER-encoded |raw_response|.
266 //
267 // Returns GOOD if the OCSP response indicates the certificate is not revoked,
268 // REVOKED if it indicates it is revoked, or UNKNOWN for all other cases.
269 //
270 //  * |raw_response|: A DER encoded OCSPResponse.
271 //  * |certificate_der|: The certificate being checked for revocation.
272 //  * |issuer_certificate_der|: The certificate that signed |certificate_der|.
273 //        The caller must have already performed path verification.
274 //  * |verify_time_epoch_seconds|: The time as the difference in seconds from
275 //        the POSIX epoch to use when checking revocation status.
276 //  * |max_age_seconds|: The maximum age in seconds for a CRL, implemented as
277 //        time since the |thisUpdate| field in the CRL TBSCertList. Responses
278 //        older than |max_age_seconds| will be considered invalid.
279 //  * |response_details|: Additional details about failures.
280 [[nodiscard]] OPENSSL_EXPORT OCSPRevocationStatus CheckOCSP(
281     std::string_view raw_response, std::string_view certificate_der,
282     std::string_view issuer_certificate_der, int64_t verify_time_epoch_seconds,
283     std::optional<int64_t> max_age_seconds,
284     OCSPVerifyResult::ResponseStatus *response_details);
285 
286 // Checks the revocation status of |certificate| by using the DER-encoded
287 // |raw_response|.
288 //
289 // Arguments are the same as above, except that it takes already parsed
290 // instances of the certificate and issuer certificate.
291 [[nodiscard]] OPENSSL_EXPORT OCSPRevocationStatus CheckOCSP(
292     std::string_view raw_response, const ParsedCertificate *certificate,
293     const ParsedCertificate *issuer_certificate,
294     int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds,
295     OCSPVerifyResult::ResponseStatus *response_details);
296 
297 // Creates a DER-encoded OCSPRequest for |cert|. The request is fairly basic:
298 //  * No signature
299 //  * No requestorName
300 //  * No extensions
301 //  * Uses SHA1 for all hashes.
302 //
303 // Returns true on success and fills |request_der| with the resulting bytes.
304 OPENSSL_EXPORT bool CreateOCSPRequest(const ParsedCertificate *cert,
305                                       const ParsedCertificate *issuer,
306                                       std::vector<uint8_t> *request_der);
307 
308 // Creates a URL to issue a GET request for OCSP information for |cert|.
309 OPENSSL_EXPORT std::optional<std::string> CreateOCSPGetURL(
310     const ParsedCertificate *cert, const ParsedCertificate *issuer,
311     std::string_view ocsp_responder_url);
312 
313 }  // namespace bssl
314 
315 #endif  // BSSL_PKI_OCSP_H_
316