Update the verify_certificate_chain code to work with botan >= 1.11.34 as well
ref #3245
This commit is contained in:
@@ -37,6 +37,28 @@ void BasicCredentialsManager::set_trusted_fingerprint(const std::string& fingerp
|
|||||||
this->trusted_fingerprint = fingerprint;
|
this->trusted_fingerprint = fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& BasicCredentialsManager::get_trusted_fingerprint() const
|
||||||
|
{
|
||||||
|
return this->trusted_fingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_tls_certificate(const std::vector<Botan::X509_Certificate>& certs,
|
||||||
|
const std::string& hostname, const std::string& trusted_fingerprint,
|
||||||
|
std::exception_ptr exc)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!trusted_fingerprint.empty() && !certs.empty() &&
|
||||||
|
trusted_fingerprint == certs[0].fingerprint() &&
|
||||||
|
certs[0].matches_dns_name(hostname))
|
||||||
|
// We trust the certificate, based on the trusted fingerprint and
|
||||||
|
// the fact that the hostname matches
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (exc)
|
||||||
|
std::rethrow_exception(exc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34)
|
||||||
void BasicCredentialsManager::verify_certificate_chain(const std::string& type,
|
void BasicCredentialsManager::verify_certificate_chain(const std::string& type,
|
||||||
const std::string& purported_hostname,
|
const std::string& purported_hostname,
|
||||||
const std::vector<Botan::X509_Certificate>& certs)
|
const std::vector<Botan::X509_Certificate>& certs)
|
||||||
@@ -50,17 +72,14 @@ void BasicCredentialsManager::verify_certificate_chain(const std::string& type,
|
|||||||
catch (const std::exception& tls_exception)
|
catch (const std::exception& tls_exception)
|
||||||
{
|
{
|
||||||
log_warning("TLS certificate check failed: ", tls_exception.what());
|
log_warning("TLS certificate check failed: ", tls_exception.what());
|
||||||
if (!this->trusted_fingerprint.empty() && !certs.empty() &&
|
std::exception_ptr exception_ptr{};
|
||||||
this->trusted_fingerprint == certs[0].fingerprint() &&
|
|
||||||
certs[0].matches_dns_name(purported_hostname))
|
|
||||||
// We trust the certificate, based on the trusted fingerprint and
|
|
||||||
// the fact that the hostname matches
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this->socket_handler->abort_on_invalid_cert())
|
if (this->socket_handler->abort_on_invalid_cert())
|
||||||
throw;
|
exception_ptr = std::current_exception();
|
||||||
|
|
||||||
|
check_tls_certificate(certs, purported_hostname, this->trusted_fingerprint, exception_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool BasicCredentialsManager::try_to_open_one_ca_bundle(const std::vector<std::string>& paths)
|
bool BasicCredentialsManager::try_to_open_one_ca_bundle(const std::vector<std::string>& paths)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,18 @@
|
|||||||
|
|
||||||
class TCPSocketHandler;
|
class TCPSocketHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the given cert isn’t valid, based on the given hostname
|
||||||
|
* and fingerprint, then throws the exception if it’s non-empty.
|
||||||
|
*
|
||||||
|
* Must be called after the standard (from Botan) way of
|
||||||
|
* checking the certificate, if we want to also accept certificates based
|
||||||
|
* on a trusted fingerprint.
|
||||||
|
*/
|
||||||
|
void check_tls_certificate(const std::vector<Botan::X509_Certificate>& certs,
|
||||||
|
const std::string& hostname, const std::string& trusted_fingerprint,
|
||||||
|
std::exception_ptr exc);
|
||||||
|
|
||||||
class BasicCredentialsManager: public Botan::Credentials_Manager
|
class BasicCredentialsManager: public Botan::Credentials_Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -19,12 +31,15 @@ public:
|
|||||||
BasicCredentialsManager& operator=(const BasicCredentialsManager&) = delete;
|
BasicCredentialsManager& operator=(const BasicCredentialsManager&) = delete;
|
||||||
BasicCredentialsManager& operator=(BasicCredentialsManager&&) = delete;
|
BasicCredentialsManager& operator=(BasicCredentialsManager&&) = delete;
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34)
|
||||||
void verify_certificate_chain(const std::string& type,
|
void verify_certificate_chain(const std::string& type,
|
||||||
const std::string& purported_hostname,
|
const std::string& purported_hostname,
|
||||||
const std::vector<Botan::X509_Certificate>&) override final;
|
const std::vector<Botan::X509_Certificate>&) override final;
|
||||||
|
#endif
|
||||||
std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(const std::string& type,
|
std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(const std::string& type,
|
||||||
const std::string& context) override final;
|
const std::string& context) override final;
|
||||||
void set_trusted_fingerprint(const std::string& fingerprint);
|
void set_trusted_fingerprint(const std::string& fingerprint);
|
||||||
|
const std::string& get_trusted_fingerprint() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TCPSocketHandler* const socket_handler;
|
const TCPSocketHandler* const socket_handler;
|
||||||
|
|||||||
@@ -509,6 +509,31 @@ bool TCPSocketHandler::tls_session_established(const Botan::TLS::Session& sessio
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
|
||||||
|
void TCPSocketHandler::tls_verify_cert_chain(const std::vector<Botan::X509_Certificate>& cert_chain,
|
||||||
|
const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& ocsp_responses,
|
||||||
|
const std::vector<Botan::Certificate_Store*>& trusted_roots,
|
||||||
|
Botan::Usage_Type usage, const std::string& hostname,
|
||||||
|
const Botan::TLS::Policy& policy)
|
||||||
|
{
|
||||||
|
log_debug("Checking remote certificate for hostname ", hostname);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Botan::TLS::Callbacks::tls_verify_cert_chain(cert_chain, ocsp_responses, trusted_roots, usage, hostname, policy);
|
||||||
|
log_debug("Certificate is valid");
|
||||||
|
}
|
||||||
|
catch (const std::exception& tls_exception)
|
||||||
|
{
|
||||||
|
log_warning("TLS certificate check failed: ", tls_exception.what());
|
||||||
|
std::exception_ptr exception_ptr{};
|
||||||
|
if (this->abort_on_invalid_cert())
|
||||||
|
exception_ptr = std::current_exception();
|
||||||
|
|
||||||
|
check_tls_certificate(cert_chain, hostname, this->credential_manager.get_trusted_fingerprint(), exception_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void TCPSocketHandler::on_tls_activated()
|
void TCPSocketHandler::on_tls_activated()
|
||||||
{
|
{
|
||||||
this->send_data({});
|
this->send_data({});
|
||||||
|
|||||||
@@ -196,6 +196,15 @@ private:
|
|||||||
* anything here appart from logging the TLS session information.
|
* anything here appart from logging the TLS session information.
|
||||||
*/
|
*/
|
||||||
bool tls_session_established(const Botan::TLS::Session& session) BOTAN_TLS_CALLBACKS_OVERRIDE;
|
bool tls_session_established(const Botan::TLS::Session& session) BOTAN_TLS_CALLBACKS_OVERRIDE;
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
|
||||||
|
void tls_verify_cert_chain(const std::vector<Botan::X509_Certificate>& cert_chain,
|
||||||
|
const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& ocsp_responses,
|
||||||
|
const std::vector<Botan::Certificate_Store*>& trusted_roots,
|
||||||
|
Botan::Usage_Type usage,
|
||||||
|
const std::string& hostname,
|
||||||
|
const Botan::TLS::Policy& policy) BOTAN_TLS_CALLBACKS_OVERRIDE;
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* Called whenever the tls session goes from inactive to active. This
|
* Called whenever the tls session goes from inactive to active. This
|
||||||
* means that the handshake has just been successfully done, and we can
|
* means that the handshake has just been successfully done, and we can
|
||||||
|
|||||||
Reference in New Issue
Block a user