11#include <botan/tls_extensions.h>
13#include <botan/tls_exceptn.h>
14#include <botan/tls_messages.h>
15#include <botan/internal/tls_reader.h>
20class RFC6066_Empty_Certificate_Status_Request {
22 RFC6066_Empty_Certificate_Status_Request() =
default;
24 explicit RFC6066_Empty_Certificate_Status_Request(uint16_t extension_size) {
25 if(extension_size != 0) {
26 throw Decoding_Error(
"Received an unexpectedly non-empty Certificate_Status_Request");
30 std::vector<uint8_t> serialize()
const {
return {}; }
33class RFC6066_Certificate_Status_Request {
35 RFC6066_Certificate_Status_Request(std::vector<uint8_t> names, std::vector<std::vector<uint8_t>> keys) :
36 ocsp_names(std::move(names)), ocsp_keys(std::move(keys)) {}
38 RFC6066_Certificate_Status_Request(TLS_Data_Reader& reader, uint16_t extension_size) {
39 if(extension_size == 0) {
40 throw Decoding_Error(
"Received an unexpectedly empty Certificate_Status_Request");
43 const uint8_t type = reader.get_byte();
51 if(extension_size < 5) {
52 throw Decoding_Error(
"Truncated OCSP CertificateStatusRequest");
54 const size_t len_resp_id_list = reader.get_uint16_t();
55 if(len_resp_id_list >
static_cast<size_t>(extension_size) - 5) {
56 throw Decoding_Error(
"Inconsistent length in OCSP CertificateStatusRequest");
58 ocsp_names = reader.get_fixed<uint8_t>(len_resp_id_list);
59 const size_t len_requ_ext = reader.get_uint16_t();
60 if(len_resp_id_list + len_requ_ext + 5 != extension_size) {
61 throw Decoding_Error(
"Inconsistent length in OCSP CertificateStatusRequest");
63 extension_bytes = reader.get_fixed<uint8_t>(len_requ_ext);
67 reader.discard_next(extension_size - 1);
71 std::vector<uint8_t> serialize()
const {
83 std::vector<uint8_t> ocsp_names;
84 std::vector<std::vector<uint8_t>> ocsp_keys;
85 std::vector<uint8_t> extension_bytes;
90class Certificate_Status_Request_Internal {
93 std::variant<RFC6066_Empty_Certificate_Status_Request, RFC6066_Certificate_Status_Request, Certificate_Status>;
96 explicit Certificate_Status_Request_Internal(Contents c) : content(std::move(c)) {}
102 uint16_t extension_size,
124 m_impl = std::make_unique<Certificate_Status_Request_Internal>(
125 RFC6066_Certificate_Status_Request(reader, extension_size));
138 m_impl = std::make_unique<Certificate_Status_Request_Internal>(
139 RFC6066_Empty_Certificate_Status_Request(extension_size));
154 m_impl = std::make_unique<Certificate_Status_Request_Internal>(
161 "Server sent a Certificate_Status_Request extension in an unsupported context");
166 m_impl(std::make_unique<Certificate_Status_Request_Internal>(RFC6066_Empty_Certificate_Status_Request())) {}
169 std::vector<std::vector<uint8_t>> ocsp_key_ids) :
170 m_impl(std::make_unique<Certificate_Status_Request_Internal>(
171 RFC6066_Certificate_Status_Request(std::move(ocsp_responder_ids), std::move(ocsp_key_ids)))) {}
174 m_impl(std::make_unique<Certificate_Status_Request_Internal>(
Certificate_Status(std::move(response)))) {}
181 return std::get<Certificate_Status>(m_impl->content).response();
186 return std::visit([](
const auto& c) {
return c.serialize(); }, m_impl->content);
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
~Certificate_Status_Request() override
Certificate_Status_Request()
const std::vector< uint8_t > & get_ocsp_response() const
std::vector< uint8_t > serialize(Connection_Side whoami) const override
std::vector< T > get_fixed(size_t size)