blob: 213ec264243645998539a1ef97db75b4286732c6 [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// 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
Bob Beckbc97b7a2023-04-18 08:35:15 -06008#include <memory>
Bob Beck3cd30cc2023-11-22 16:59:00 -07009#include <optional>
Bob Beck300f2212023-08-16 22:18:25 +000010#include <string>
Bob Beckbc97b7a2023-04-18 08:35:15 -060011#include <vector>
12
Bob Beck3cd30cc2023-11-22 16:59:00 -070013#include <openssl/base.h>
Bob Beckbc97b7a2023-04-18 08:35:15 -060014
Bob Beck5c7a2a02023-11-20 17:28:21 -070015#include "input.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060016#include "ocsp_revocation_status.h"
17#include "ocsp_verify_result.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060018#include "parse_values.h"
19#include "parser.h"
Bob Beck5c7a2a02023-11-20 17:28:21 -070020#include "signature_algorithm.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060021
22namespace bssl {
23
24class 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// }
34struct 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)
76struct 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// }
114struct 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// }
140struct 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// }
194struct 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
225inline 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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700233OPENSSL_EXPORT bool ParseOCSPCertID(const der::Input &raw_tlv, OCSPCertID *out);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600234
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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700242OPENSSL_EXPORT bool ParseOCSPSingleResponse(const der::Input &raw_tlv,
243 OCSPSingleResponse *out);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600244
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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700252OPENSSL_EXPORT bool ParseOCSPResponseData(const der::Input &raw_tlv,
253 OCSPResponseData *out);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600254
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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700262OPENSSL_EXPORT bool ParseOCSPResponse(const der::Input &raw_tlv,
263 OCSPResponse *out);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600264
265// Checks the revocation status of the certificate |certificate_der| by using
266// the DER-encoded |raw_response|.
267//
268// Returns GOOD if the OCSP response indicates the certificate is not revoked,
269// REVOKED if it indicates it is revoked, or UNKNOWN for all other cases.
270//
271// * |raw_response|: A DER encoded OCSPResponse.
272// * |certificate_der|: The certificate being checked for revocation.
273// * |issuer_certificate_der|: The certificate that signed |certificate_der|.
274// The caller must have already performed path verification.
275// * |verify_time_epoch_seconds|: The time as the difference in seconds from
276// the POSIX epoch to use when checking revocation status.
277// * |max_age_seconds|: The maximum age in seconds for a CRL, implemented as
278// time since the |thisUpdate| field in the CRL TBSCertList. Responses
279// older than |max_age_seconds| will be considered invalid.
280// * |response_details|: Additional details about failures.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700281[[nodiscard]] OPENSSL_EXPORT OCSPRevocationStatus CheckOCSP(
282 std::string_view raw_response, std::string_view certificate_der,
283 std::string_view issuer_certificate_der, int64_t verify_time_epoch_seconds,
284 std::optional<int64_t> max_age_seconds,
285 OCSPVerifyResult::ResponseStatus *response_details);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600286
287// Checks the revocation status of |certificate| by using the DER-encoded
288// |raw_response|.
289//
290// Arguments are the same as above, except that it takes already parsed
291// instances of the certificate and issuer certificate.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700292[[nodiscard]] OPENSSL_EXPORT OCSPRevocationStatus CheckOCSP(
293 std::string_view raw_response, const ParsedCertificate *certificate,
294 const ParsedCertificate *issuer_certificate,
295 int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds,
296 OCSPVerifyResult::ResponseStatus *response_details);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600297
298// Creates a DER-encoded OCSPRequest for |cert|. The request is fairly basic:
299// * No signature
300// * No requestorName
301// * No extensions
302// * Uses SHA1 for all hashes.
303//
304// Returns true on success and fills |request_der| with the resulting bytes.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700305OPENSSL_EXPORT bool CreateOCSPRequest(const ParsedCertificate *cert,
306 const ParsedCertificate *issuer,
307 std::vector<uint8_t> *request_der);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600308
309// Creates a URL to issue a GET request for OCSP information for |cert|.
Bob Beck300f2212023-08-16 22:18:25 +0000310OPENSSL_EXPORT std::optional<std::string> CreateOCSPGetURL(
Bob Beck5c7a2a02023-11-20 17:28:21 -0700311 const ParsedCertificate *cert, const ParsedCertificate *issuer,
Bob Beck300f2212023-08-16 22:18:25 +0000312 std::string_view ocsp_responder_url);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600313
Bob Beck5c7a2a02023-11-20 17:28:21 -0700314} // namespace bssl
Bob Beckbc97b7a2023-04-18 08:35:15 -0600315
316#endif // BSSL_PKI_OCSP_H_