diff options
-rw-r--r-- | src/lib/tls/msg_cert_status.cpp | 11 | ||||
-rw-r--r-- | src/lib/tls/tls_callbacks.h | 12 | ||||
-rw-r--r-- | src/lib/tls/tls_messages.h | 7 | ||||
-rw-r--r-- | src/lib/tls/tls_server.cpp | 8 |
4 files changed, 36 insertions, 2 deletions
diff --git a/src/lib/tls/msg_cert_status.cpp b/src/lib/tls/msg_cert_status.cpp index c0cd82a28..2a07c4672 100644 --- a/src/lib/tls/msg_cert_status.cpp +++ b/src/lib/tls/msg_cert_status.cpp @@ -41,18 +41,25 @@ Certificate_Status::Certificate_Status(Handshake_IO& io, { hash.update(io.send(*this)); } +Certificate_Status::Certificate_Status(Handshake_IO& io, + Handshake_Hash& hash, + std::vector<uint8_t> const& raw_response_bytes) : + m_raw_response_bytes(raw_response_bytes) + { + hash.update(io.send(*this)); + } std::vector<uint8_t> Certificate_Status::serialize() const { if(m_response.size() > 0xFFFFFF) // unlikely throw Encoding_Error("OCSP response too long to encode in TLS"); - const uint32_t m_response_len = static_cast<uint32_t>(m_response.size()); + const uint32_t response_len = static_cast<uint32_t>(m_response.size()); std::vector<uint8_t> buf; buf.push_back(1); // type OCSP for(size_t i = 1; i < 4; ++i) - buf[i] = get_byte(i, m_response_len); + buf.push_back(get_byte(i, response_len)); buf += m_response; return buf; diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h index b35cf0051..6b93e7d6b 100644 --- a/src/lib/tls/tls_callbacks.h +++ b/src/lib/tls/tls_callbacks.h @@ -142,6 +142,18 @@ class BOTAN_PUBLIC_API(2,0) Callbacks return std::chrono::milliseconds(0); } + /** + * Called by the TLS server whenever the client included the status_request extension (see RFC 6066, a.k.a OCSP stapling) in the ClientHello. + * In the current implementation no information from the contents of the status_request extension within the + * ClientHello is available. + * + * @return the encoded OCSP response to be sent to the client which indicates the revocation status of the server certificate. Return an empty vector to indicate that no response is available, and thus suppress the Certificate_Status message. + */ + virtual std::vector<uint8_t> tls_srv_provoide_cert_status_response() const + { + return std::vector<uint8_t>(); + } + /** * Optional callback with default impl: sign a message * diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index 0549a66a6..31c067696 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -399,6 +399,13 @@ class BOTAN_UNSTABLE_API Certificate_Status final : public Handshake_Message Handshake_Hash& hash, std::shared_ptr<const OCSP::Response> response); + /* + * Create a Certificate_Status message using an already DER encoded OCSP response. + */ + Certificate_Status(Handshake_IO& io, + Handshake_Hash& hash, + std::vector<uint8_t> const& raw_response_bytes ); + private: std::vector<uint8_t> serialize() const override; std::vector<uint8_t> m_response; diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index d0c3baa2e..9e9ca517e 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -846,6 +846,14 @@ void Server::session_create(Server_Handshake_State& pending_state, pending_state.server_certs(new Certificate(pending_state.handshake_io(), pending_state.hash(), cert_chains[algo_used])); + if(pending_state.client_hello()->supports_cert_status_message() && callbacks().tls_srv_provoide_cert_status_response().size() > 0) + { + pending_state.server_cert_status(new Certificate_Status( + pending_state.handshake_io(), + pending_state.hash(), + callbacks().tls_srv_provoide_cert_status_response() + )); + } private_key = m_creds.private_key_for( pending_state.server_certs()->cert_chain()[0], |