Skip to content

Commit

Permalink
check OCSP status
Browse files Browse the repository at this point in the history
Co-authored-by: René Meusel <rene.meusel@nexenio.com>
  • Loading branch information
Hannes Rantzsch and reneme committed Mar 18, 2022
1 parent 38c1740 commit 8b68663
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
49 changes: 36 additions & 13 deletions src/lib/tls/msg_certificate_13.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/credentials_manager.h>
#include <botan/tls_callbacks.h>
#include <botan/tls_messages.h>
#include <botan/tls_extensions.h>
#include <botan/tls_exceptn.h>
Expand All @@ -18,19 +20,6 @@

namespace Botan::TLS {

/**
* Create a new Certificate message
*/
Certificate_13::Certificate_13(Handshake_IO& io,
Handshake_Hash& hash,
std::vector<Certificate_Entry> entries,
const Connection_Side side) :
m_entries(std::move(entries)),
m_side(side)
{
hash.update(io.send(*this));
}

void Certificate_13::validate_extensions(const Extensions& requested_extensions) const
{
// RFC 8446 4.4.2
Expand All @@ -44,6 +33,40 @@ void Certificate_13::validate_extensions(const Extensions& requested_extensions)
{ throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Unexpected extension received"); }
}

void Certificate_13::verify(Callbacks& callbacks,
const Policy& policy,
Credentials_Manager& creds,
const std::string& hostname,
bool use_ocsp) const
{
// RFC 8446 4.4.2.4
// If the server supplies an empty Certificate message, the client
// MUST abort the handshake with a "decode_error" alert.
if(m_entries.empty())
{ throw TLS_Exception(Alert::DECODE_ERROR, "Client: No certificates sent by server"); }

auto trusted_CAs = creds.trusted_certificate_authorities("tls-client", hostname);

std::vector<X509_Certificate> certs;
std::vector<std::optional<OCSP::Response>> ocsp_responses;
for (const auto& entry : m_entries)
{
certs.push_back(entry.certificate);
if(use_ocsp)
{
if(entry.extensions.has<Certificate_Status_Request>())
// The response inside the extension can still be emtpy. This will be treated as an error during
// construction of the OCSP response.
ocsp_responses.push_back(entry.extensions.get<Certificate_Status_Request>()->get_ocsp_response());
else
ocsp_responses.push_back(std::nullopt);
}
}

const auto usage = (m_side == CLIENT) ? Usage_Type::TLS_SERVER_AUTH : Usage_Type::TLS_CLIENT_AUTH;
callbacks.tls_verify_cert_chain(certs, ocsp_responses, trusted_CAs, usage, hostname, policy);
}

/**
* Deserialize a Certificate message
*/
Expand Down
25 changes: 5 additions & 20 deletions src/lib/tls/tls13/tls_client_impl_13.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,26 +305,11 @@ void Client_Impl_13::handle(const Encrypted_Extensions& encrypted_extensions_msg
void Client_Impl_13::handle(const Certificate_13& certificate_msg)
{
certificate_msg.validate_extensions(m_handshake_state.client_hello().extensions());
const auto& server_certs = certificate_msg.cert_chain();

// RFC 8446 4.4.2.4
// If the server supplies an empty Certificate message, the client
// MUST abort the handshake with a "decode_error" alert.
if(server_certs.empty())
{ throw TLS_Exception(Alert::DECODE_ERROR, "Client: No certificates sent by server"); }

auto trusted_CAs = credentials_manager().trusted_certificate_authorities("tls-client", m_info.hostname());

std::vector<X509_Certificate> certs;
std::transform(server_certs.cbegin(), server_certs.cend(), std::back_inserter(certs),
[](const auto& entry) { return entry.certificate; });

callbacks().tls_verify_cert_chain(certs,
{}, // TODO: Support OCSP stapling via RFC8446 4.4.2.1
trusted_CAs,
Usage_Type::TLS_SERVER_AUTH,
m_info.hostname(),
policy());
certificate_msg.verify(callbacks(),
policy(),
credentials_manager(),
m_info.hostname(),
m_handshake_state.client_hello().extensions().has<Certificate_Status_Request>());

m_transitions.set_expected_next(CERTIFICATE_VERIFY);
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/tls/tls_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
#ifndef BOTAN_TLS_EXTENSIONS_H_
#define BOTAN_TLS_EXTENSIONS_H_

#include <botan/ocsp.h>
#include <botan/tls_algos.h>
#include <botan/tls_magic.h>
#include <botan/tls_version.h>
#include <botan/secmem.h>
#include <botan/pkix_types.h>

#include <algorithm>
#include <optional>
#include <vector>
#include <string>
#include <set>
Expand Down
16 changes: 11 additions & 5 deletions src/lib/tls/tls_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,6 @@ class BOTAN_UNSTABLE_API Certificate_13 final : public Handshake_Message
size_t count() const { return m_entries.size(); }
bool empty() const { return m_entries.empty(); }

Certificate_13(Handshake_IO& io,
Handshake_Hash& hash,
std::vector<Certificate_Entry> certs,
const Connection_Side side);

/**
* Deserialize a Certificate message
* @param buf the serialized message
Expand All @@ -544,6 +539,17 @@ class BOTAN_UNSTABLE_API Certificate_13 final : public Handshake_Message
*/
void validate_extensions(const Extensions& requested_extensions) const;

/**
* Verify the certificate chain
*
* @throws if verification fails.
*/
void verify(Callbacks& callbacks,
const Policy& policy,
Credentials_Manager& creds,
const std::string& hostname,
bool use_ocsp) const;

std::vector<uint8_t> serialize() const override;

private:
Expand Down

0 comments on commit 8b68663

Please sign in to comment.