mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-22 09:57:41 +00:00
[#3553] Checkpoint
This commit is contained in:
parent
9566324f68
commit
a140a853c9
@ -1658,7 +1658,12 @@ TEST_F(HAConfigTest, badTrustAnchor) {
|
|||||||
#ifdef WITH_OPENSSL
|
#ifdef WITH_OPENSSL
|
||||||
expected += "No such file or directory";
|
expected += "No such file or directory";
|
||||||
#else
|
#else
|
||||||
expected += "I/O error: DataSource: Failure opening file /this-file-does-not-exist";
|
expected += "I/O error: DataSource: Failure opening file ";
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
expected += "'/this-file-does-not-exist'";
|
||||||
|
#else
|
||||||
|
expected += "/this-file-does-not-exist";
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
testInvalidConfig(patched, expected);
|
testInvalidConfig(patched, expected);
|
||||||
}
|
}
|
||||||
@ -1698,7 +1703,12 @@ TEST_F(HAConfigTest, badCertFile) {
|
|||||||
#ifdef WITH_OPENSSL
|
#ifdef WITH_OPENSSL
|
||||||
expected += "No such file or directory";
|
expected += "No such file or directory";
|
||||||
#else
|
#else
|
||||||
expected += "I/O error: DataSource: Failure opening file /this-file-does-not-exist";
|
expected += "I/O error: DataSource: Failure opening file ";
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
expected += "'/this-file-does-not-exist'";
|
||||||
|
#else
|
||||||
|
expected += "/this-file-does-not-exist";
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
testInvalidConfig(patched, expected);
|
testInvalidConfig(patched, expected);
|
||||||
}
|
}
|
||||||
@ -1738,7 +1748,12 @@ TEST_F(HAConfigTest, badKeyFile) {
|
|||||||
#ifdef WITH_OPENSSL
|
#ifdef WITH_OPENSSL
|
||||||
expected += "No such file or directory";
|
expected += "No such file or directory";
|
||||||
#else
|
#else
|
||||||
expected += "I/O error: DataSource: Failure opening file /this-file-does-not-exist";
|
expected += "I/O error: DataSource: Failure opening file ";
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
expected += "'/this-file-does-not-exist'";
|
||||||
|
#else
|
||||||
|
expected += "/this-file-does-not-exist";
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
testInvalidConfig(patched, expected);
|
testInvalidConfig(patched, expected);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
#include <botan/data_src.h>
|
#include <botan/data_src.h>
|
||||||
#include <botan/pem.h>
|
#include <botan/pem.h>
|
||||||
#include <botan/pkcs8.h>
|
#include <botan/pkcs8.h>
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
#include <botan/tls_session_manager_noop.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace isc::cryptolink;
|
using namespace isc::cryptolink;
|
||||||
|
|
||||||
@ -36,8 +39,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Destructor.
|
// Destructor.
|
||||||
virtual ~KeaCredentialsManager() {
|
virtual ~KeaCredentialsManager() = default;
|
||||||
}
|
|
||||||
|
|
||||||
// CA certificate stores.
|
// CA certificate stores.
|
||||||
// nullptr means do not require or check peer certificate.
|
// nullptr means do not require or check peer certificate.
|
||||||
@ -54,17 +56,28 @@ public:
|
|||||||
// Certificate chain.
|
// Certificate chain.
|
||||||
std::vector<Botan::X509_Certificate>
|
std::vector<Botan::X509_Certificate>
|
||||||
cert_chain(const std::vector<std::string>&,
|
cert_chain(const std::vector<std::string>&,
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
const std::vector<Botan::AlgorithmIdentifier>&,
|
||||||
|
#endif
|
||||||
const std::string&,
|
const std::string&,
|
||||||
const std::string&) override {
|
const std::string&) override {
|
||||||
return (certs_);
|
return (certs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private key.
|
// Private key.
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::Private_Key>
|
||||||
|
#else
|
||||||
Botan::Private_Key*
|
Botan::Private_Key*
|
||||||
|
#endif
|
||||||
private_key_for(const Botan::X509_Certificate&,
|
private_key_for(const Botan::X509_Certificate&,
|
||||||
const std::string&,
|
const std::string&,
|
||||||
const std::string&) override {
|
const std::string&) override {
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
return (key_);
|
||||||
|
#else
|
||||||
return (key_.get());
|
return (key_.get());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the store from a path.
|
// Set the store from a path.
|
||||||
@ -118,13 +131,27 @@ public:
|
|||||||
|
|
||||||
// Set the private key.
|
// Set the private key.
|
||||||
void setPrivateKey(const std::string& file,
|
void setPrivateKey(const std::string& file,
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
Botan::RandomNumberGenerator&,
|
||||||
|
#else
|
||||||
Botan::RandomNumberGenerator& rng,
|
Botan::RandomNumberGenerator& rng,
|
||||||
|
#endif
|
||||||
bool& is_rsa) {
|
bool& is_rsa) {
|
||||||
key_.reset(Botan::PKCS8::load_key(file, rng));
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
if (!key_) {
|
Botan::DataSource_Stream source(file);
|
||||||
|
auto priv_key = Botan::PKCS8::load_key(source);
|
||||||
|
#else
|
||||||
|
auto priv_key = Botan::PKCS8::load_key(file, rng);
|
||||||
|
#endif
|
||||||
|
if (!priv_key) {
|
||||||
isc_throw(Unexpected,
|
isc_throw(Unexpected,
|
||||||
"Botan::PKCS8::load_key failed but not threw?");
|
"Botan::PKCS8::load_key failed but not threw?");
|
||||||
}
|
}
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
key_ = std::move(priv_key);
|
||||||
|
#else
|
||||||
|
key_.reset(priv_key);
|
||||||
|
#endif
|
||||||
is_rsa = (key_->algo_name() == "RSA");
|
is_rsa = (key_->algo_name() == "RSA");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +165,7 @@ public:
|
|||||||
std::vector<Botan::X509_Certificate> certs_;
|
std::vector<Botan::X509_Certificate> certs_;
|
||||||
|
|
||||||
// Pointer to the private key.
|
// Pointer to the private key.
|
||||||
std::unique_ptr<Botan::Private_Key> key_;
|
std::shared_ptr<Botan::Private_Key> key_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Class of Kea policy.
|
// Class of Kea policy.
|
||||||
@ -197,29 +224,32 @@ KeaPolicy::AllowedSignatureMethodsECDSA = { "ECDSA", "RSA", "DSA" };
|
|||||||
class TlsContextImpl {
|
class TlsContextImpl {
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
TlsContextImpl() : cred_mgr_(), rng_(), sess_mgr_(), policy_() {
|
TlsContextImpl() :
|
||||||
|
cred_mgr_(new KeaCredentialsManager()),
|
||||||
|
rng_(new Botan::AutoSeeded_RNG()),
|
||||||
|
sess_mgr_(new KeaSessionManager()),
|
||||||
|
policy_(new KeaPolicy()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor.
|
// Destructor.
|
||||||
virtual ~TlsContextImpl() {
|
virtual ~TlsContextImpl() = default;
|
||||||
}
|
|
||||||
|
|
||||||
// Get the peer certificate requirement mode.
|
// Get the peer certificate requirement mode.
|
||||||
virtual bool getCertRequired() const {
|
virtual bool getCertRequired() const {
|
||||||
return (cred_mgr_.getUseStores());
|
return (cred_mgr_->getUseStores());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the peer certificate requirement mode.
|
// Set the peer certificate requirement mode.
|
||||||
//
|
//
|
||||||
// With Botan this means to provide or not the CA certificate stores.
|
// With Botan this means to provide or not the CA certificate stores.
|
||||||
virtual void setCertRequired(bool cert_required) {
|
virtual void setCertRequired(bool cert_required) {
|
||||||
cred_mgr_.setUseStores(cert_required);
|
cred_mgr_->setUseStores(cert_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the trust anchor aka certificate authority (path).
|
// Load the trust anchor aka certificate authority (path).
|
||||||
virtual void loadCaPath(const std::string& ca_path) {
|
virtual void loadCaPath(const std::string& ca_path) {
|
||||||
try {
|
try {
|
||||||
cred_mgr_.setStorePath(ca_path);
|
cred_mgr_->setStorePath(ca_path);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
isc_throw(LibraryError, ex.what());
|
isc_throw(LibraryError, ex.what());
|
||||||
}
|
}
|
||||||
@ -228,7 +258,7 @@ public:
|
|||||||
// Load the trust anchor aka certificate authority (file).
|
// Load the trust anchor aka certificate authority (file).
|
||||||
virtual void loadCaFile(const std::string& ca_file) {
|
virtual void loadCaFile(const std::string& ca_file) {
|
||||||
try {
|
try {
|
||||||
cred_mgr_.setStoreFile(ca_file);
|
cred_mgr_->setStoreFile(ca_file);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
isc_throw(LibraryError, ex.what());
|
isc_throw(LibraryError, ex.what());
|
||||||
}
|
}
|
||||||
@ -237,7 +267,7 @@ public:
|
|||||||
/// @brief Load the certificate file.
|
/// @brief Load the certificate file.
|
||||||
virtual void loadCertFile(const std::string& cert_file) {
|
virtual void loadCertFile(const std::string& cert_file) {
|
||||||
try {
|
try {
|
||||||
cred_mgr_.setCertChain(cert_file);
|
cred_mgr_->setCertChain(cert_file);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
isc_throw(LibraryError, ex.what());
|
isc_throw(LibraryError, ex.what());
|
||||||
}
|
}
|
||||||
@ -249,8 +279,8 @@ public:
|
|||||||
virtual void loadKeyFile(const std::string& key_file) {
|
virtual void loadKeyFile(const std::string& key_file) {
|
||||||
try {
|
try {
|
||||||
bool is_rsa = true;
|
bool is_rsa = true;
|
||||||
cred_mgr_.setPrivateKey(key_file, rng_, is_rsa);
|
cred_mgr_->setPrivateKey(key_file, *rng_, is_rsa);
|
||||||
policy_.setPrefRSA(is_rsa);
|
policy_->setPrefRSA(is_rsa);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
isc_throw(LibraryError, ex.what());
|
isc_throw(LibraryError, ex.what());
|
||||||
}
|
}
|
||||||
@ -261,28 +291,41 @@ public:
|
|||||||
if (context_) {
|
if (context_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
context_.reset(new Botan::TLS::Context(cred_mgr_,
|
context_.reset(new Botan::TLS::Context(cred_mgr_,
|
||||||
rng_,
|
rng_,
|
||||||
sess_mgr_,
|
sess_mgr_,
|
||||||
policy_));
|
policy_));
|
||||||
|
#else
|
||||||
|
context_.reset(new Botan::TLS::Context(*cred_mgr_,
|
||||||
|
*rng_,
|
||||||
|
*sess_mgr_,
|
||||||
|
*policy_));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
virtual std::shared_ptr<Botan::TLS::Context> get() {
|
||||||
|
return (context_);
|
||||||
|
}
|
||||||
|
#else
|
||||||
virtual Botan::TLS::Context& get() {
|
virtual Botan::TLS::Context& get() {
|
||||||
return (*context_);
|
return (*context_);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Credentials Manager.
|
// Credentials Manager.
|
||||||
KeaCredentialsManager cred_mgr_;
|
std::shared_ptr<KeaCredentialsManager> cred_mgr_;
|
||||||
|
|
||||||
// Random Number Generator.
|
// Random Number Generator.
|
||||||
Botan::AutoSeeded_RNG rng_;
|
std::shared_ptr<Botan::AutoSeeded_RNG> rng_;
|
||||||
|
|
||||||
// Session Manager.
|
// Session Manager.
|
||||||
KeaSessionManager sess_mgr_;
|
std::shared_ptr<KeaSessionManager> sess_mgr_;
|
||||||
|
|
||||||
KeaPolicy policy_;
|
std::shared_ptr<KeaPolicy> policy_;
|
||||||
|
|
||||||
std::unique_ptr<Botan::TLS::Context> context_;
|
std::shared_ptr<Botan::TLS::Context> context_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TlsContext::~TlsContext() {
|
TlsContext::~TlsContext() {
|
||||||
@ -292,11 +335,19 @@ TlsContext::TlsContext(TlsRole role)
|
|||||||
: TlsContextBase(role), impl_(new TlsContextImpl()) {
|
: TlsContextBase(role), impl_(new TlsContextImpl()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::TLS::Context>
|
||||||
|
TlsContext::getContext() {
|
||||||
|
impl_->build();
|
||||||
|
return (impl_->get());
|
||||||
|
}
|
||||||
|
#else
|
||||||
Botan::TLS::Context&
|
Botan::TLS::Context&
|
||||||
TlsContext::getContext() {
|
TlsContext::getContext() {
|
||||||
impl_->build();
|
impl_->build();
|
||||||
return (impl_->get());
|
return (impl_->get());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
TlsContext::setCertRequired(bool cert_required) {
|
TlsContext::setCertRequired(bool cert_required) {
|
||||||
|
@ -28,9 +28,17 @@ namespace asiolink {
|
|||||||
/// @brief Translate TLS role into implementation.
|
/// @brief Translate TLS role into implementation.
|
||||||
inline Botan::TLS::Connection_Side roleToImpl(TlsRole role) {
|
inline Botan::TLS::Connection_Side roleToImpl(TlsRole role) {
|
||||||
if (role == TlsRole::SERVER) {
|
if (role == TlsRole::SERVER) {
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
return (Botan::TLS::Connection_Side::Server);
|
||||||
|
#else
|
||||||
return (Botan::TLS::Connection_Side::SERVER);
|
return (Botan::TLS::Connection_Side::SERVER);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
return (Botan::TLS::Connection_Side::Client);
|
||||||
|
#else
|
||||||
return (Botan::TLS::Connection_Side::CLIENT);
|
return (Botan::TLS::Connection_Side::CLIENT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +61,11 @@ public:
|
|||||||
explicit TlsContext(TlsRole role);
|
explicit TlsContext(TlsRole role);
|
||||||
|
|
||||||
/// @brief Return the underlying context.
|
/// @brief Return the underlying context.
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::TLS::Context> getContext();
|
||||||
|
#else
|
||||||
Botan::TLS::Context& getContext();
|
Botan::TLS::Context& getContext();
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief Get the peer certificate requirement mode.
|
/// @brief Get the peer certificate requirement mode.
|
||||||
///
|
///
|
||||||
|
@ -509,6 +509,7 @@ TEST_F(TLSTest, loadNoCAFile) {
|
|||||||
Expecteds exps;
|
Expecteds exps;
|
||||||
// Botan error.
|
// Botan error.
|
||||||
exps.addThrow("I/O error: DataSource: Failure opening file /no-such-file");
|
exps.addThrow("I/O error: DataSource: Failure opening file /no-such-file");
|
||||||
|
exps.addThrow("I/O error: DataSource: Failure opening file '/no-such-file'");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
exps.addThrow("No such file or directory");
|
exps.addThrow("No such file or directory");
|
||||||
exps.addThrow("No such file or directory (system library)");
|
exps.addThrow("No such file or directory (system library)");
|
||||||
@ -586,6 +587,7 @@ TEST_F(TLSTest, loadNoCertFile) {
|
|||||||
Expecteds exps;
|
Expecteds exps;
|
||||||
// Botan error.
|
// Botan error.
|
||||||
exps.addThrow("I/O error: DataSource: Failure opening file /no-such-file");
|
exps.addThrow("I/O error: DataSource: Failure opening file /no-such-file");
|
||||||
|
exps.addThrow("I/O error: DataSource: Failure opening file '/no-such-file'");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
exps.addThrow("No such file or directory");
|
exps.addThrow("No such file or directory");
|
||||||
exps.addThrow("No such file or directory (system library)");
|
exps.addThrow("No such file or directory (system library)");
|
||||||
@ -632,6 +634,7 @@ TEST_F(TLSTest, loadNoKeyFile) {
|
|||||||
Expecteds exps;
|
Expecteds exps;
|
||||||
// Botan error.
|
// Botan error.
|
||||||
exps.addThrow("I/O error: DataSource: Failure opening file /no-such-file");
|
exps.addThrow("I/O error: DataSource: Failure opening file /no-such-file");
|
||||||
|
exps.addThrow("I/O error: DataSource: Failure opening file '/no-such-file'");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
exps.addThrow("No such file or directory");
|
exps.addThrow("No such file or directory");
|
||||||
exps.addThrow("No such file or directory (system library)");
|
exps.addThrow("No such file or directory (system library)");
|
||||||
@ -655,6 +658,9 @@ TEST_F(TLSTest, loadCertKeyFile) {
|
|||||||
string botan_error = "PKCS #8 private key decoding failed with PKCS #8: ";
|
string botan_error = "PKCS #8 private key decoding failed with PKCS #8: ";
|
||||||
botan_error += "Unknown PEM label CERTIFICATE";
|
botan_error += "Unknown PEM label CERTIFICATE";
|
||||||
exps.addThrow(botan_error);
|
exps.addThrow(botan_error);
|
||||||
|
botan_error = "PKCS #8 private key decoding failed with PKCS #8: ";
|
||||||
|
botan_error += "Unknown PEM label 'CERTIFICATE'";
|
||||||
|
exps.addThrow(botan_error);
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
exps.addThrow("no start line");
|
exps.addThrow("no start line");
|
||||||
exps.addThrow("no start line (PEM routines)");
|
exps.addThrow("no start line (PEM routines)");
|
||||||
@ -733,6 +739,8 @@ TEST_F(TLSTest, configureError) {
|
|||||||
// Botan error.
|
// Botan error.
|
||||||
string botan_error = "I/O error: DataSource: Failure opening file /no-such-file";
|
string botan_error = "I/O error: DataSource: Failure opening file /no-such-file";
|
||||||
exps.addThrow(common_error + botan_error);
|
exps.addThrow(common_error + botan_error);
|
||||||
|
botan_error = "I/O error: DataSource: Failure opening file '/no-such-file'";
|
||||||
|
exps.addThrow(common_error + botan_error);
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
string openssl_error = "No such file or directory";
|
string openssl_error = "No such file or directory";
|
||||||
exps.addThrow(common_error + openssl_error);
|
exps.addThrow(common_error + openssl_error);
|
||||||
@ -946,6 +954,7 @@ TEST_F(TLSTest, serverNotConfigured) {
|
|||||||
exps.clear();
|
exps.clear();
|
||||||
// On Botan and some OpenSSL the client hangs.
|
// On Botan and some OpenSSL the client hangs.
|
||||||
exps.addTimeout();
|
exps.addTimeout();
|
||||||
|
exps.addError("handshake_failure");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
exps.addError("sslv3 alert handshake failure");
|
exps.addError("sslv3 alert handshake failure");
|
||||||
exps.addError("sslv3 alert handshake failure (SSL routines)");
|
exps.addError("sslv3 alert handshake failure (SSL routines)");
|
||||||
@ -1027,6 +1036,7 @@ TEST_F(TLSTest, clientNotConfigured) {
|
|||||||
Expecteds exps;
|
Expecteds exps;
|
||||||
// On Botan and some OpenSSL the server hangs.
|
// On Botan and some OpenSSL the server hangs.
|
||||||
exps.addTimeout();
|
exps.addTimeout();
|
||||||
|
exps.addError("bad_certificate");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
exps.addError("tlsv1 alert unknown ca");
|
exps.addError("tlsv1 alert unknown ca");
|
||||||
exps.addError("tlsv1 alert unknown ca (SSL routines)");
|
exps.addError("tlsv1 alert unknown ca (SSL routines)");
|
||||||
@ -1128,6 +1138,7 @@ TEST_F(TLSTest, clientHTTPnoS) {
|
|||||||
exps.addTimeout();
|
exps.addTimeout();
|
||||||
// Botan error.
|
// Botan error.
|
||||||
exps.addError("protocol_version");
|
exps.addError("protocol_version");
|
||||||
|
exps.addError("unexpected_message");
|
||||||
// Old LibreSSL error.
|
// Old LibreSSL error.
|
||||||
exps.addError("tlsv1 alert protocol version");
|
exps.addError("tlsv1 alert protocol version");
|
||||||
// OpenSSL errors (OpenSSL recognizes HTTP).
|
// OpenSSL errors (OpenSSL recognizes HTTP).
|
||||||
@ -1220,6 +1231,7 @@ TEST_F(TLSTest, unknownClient) {
|
|||||||
// Botan errors.
|
// Botan errors.
|
||||||
exps.addError("record_overflow");
|
exps.addError("record_overflow");
|
||||||
exps.addError("protocol_version");
|
exps.addError("protocol_version");
|
||||||
|
exps.addError("unexpected_message");
|
||||||
// Old LibreSSL error.
|
// Old LibreSSL error.
|
||||||
exps.addError("tlsv1 alert protocol version");
|
exps.addError("tlsv1 alert protocol version");
|
||||||
// Old OpenSSL error.
|
// Old OpenSSL error.
|
||||||
@ -1630,6 +1642,7 @@ TEST_F(TLSTest, serverNotConfiguredCloseonError) {
|
|||||||
exps.clear();
|
exps.clear();
|
||||||
// Botan and some OpenSSL.
|
// Botan and some OpenSSL.
|
||||||
exps.addError("stream truncated");
|
exps.addError("stream truncated");
|
||||||
|
exps.addError("handshake_failure");
|
||||||
// Alias on old OpenSSL.
|
// Alias on old OpenSSL.
|
||||||
exps.addError("short read");
|
exps.addError("short read");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
@ -1710,6 +1723,7 @@ TEST_F(TLSTest, clientNotConfiguredCloseonError) {
|
|||||||
Expecteds exps;
|
Expecteds exps;
|
||||||
// Botan and some OpenSSL.
|
// Botan and some OpenSSL.
|
||||||
exps.addError("stream truncated");
|
exps.addError("stream truncated");
|
||||||
|
exps.addError("bad_certificate");
|
||||||
// Alias on old OpenSSL.
|
// Alias on old OpenSSL.
|
||||||
exps.addError("short read");
|
exps.addError("short read");
|
||||||
// OpenSSL errors.
|
// OpenSSL errors.
|
||||||
@ -1810,6 +1824,7 @@ TEST_F(TLSTest, clientHTTPnoSCloseonError) {
|
|||||||
exps.addTimeout();
|
exps.addTimeout();
|
||||||
// Botan behavior was reported and fixed.
|
// Botan behavior was reported and fixed.
|
||||||
exps.addError("protocol_version");
|
exps.addError("protocol_version");
|
||||||
|
exps.addError("unexpected_message");
|
||||||
// Old LibreSSL error.
|
// Old LibreSSL error.
|
||||||
exps.addError("tlsv1 alert protocol version");
|
exps.addError("tlsv1 alert protocol version");
|
||||||
// OpenSSL errors when OpenSSL recognizes HTTP.
|
// OpenSSL errors when OpenSSL recognizes HTTP.
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#include <botan/certstor_flatfile.h>
|
#include <botan/certstor_flatfile.h>
|
||||||
#include <botan/pkcs8.h>
|
#include <botan/pkcs8.h>
|
||||||
#include <botan/auto_rng.h>
|
#include <botan/auto_rng.h>
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
#include <botan/tls_session_manager_noop.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
inline std::string CA_(const std::string& filename) {
|
inline std::string CA_(const std::string& filename) {
|
||||||
return (std::string(TEST_CA_DIR) + "/" + filename);
|
return (std::string(TEST_CA_DIR) + "/" + filename);
|
||||||
@ -35,19 +38,29 @@ using Client_Certificate_Store = Botan::Flatfile_Certificate_Store;
|
|||||||
class Client_Credentials_Manager : public Botan::Credentials_Manager
|
class Client_Credentials_Manager : public Botan::Credentials_Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
explicit Client_Credentials_Manager()
|
||||||
|
#else
|
||||||
explicit Client_Credentials_Manager(Botan::RandomNumberGenerator& rng)
|
explicit Client_Credentials_Manager(Botan::RandomNumberGenerator& rng)
|
||||||
|
#endif
|
||||||
: stores_(), certs_(),
|
: stores_(), certs_(),
|
||||||
store_(new Client_Certificate_Store(CA_("kea-ca.crt"))),
|
store_(new Client_Certificate_Store(CA_("kea-ca.crt"))),
|
||||||
cert_(Botan::X509_Certificate(CA_("kea-client.crt"))),
|
cert_(Botan::X509_Certificate(CA_("kea-client.crt"))),
|
||||||
key_(Botan::PKCS8::load_key(CA_("kea-client.key"), rng))
|
key_()
|
||||||
{
|
{
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
Botan::DataSource_Stream source(CA_("kea-client.key"));
|
||||||
|
auto priv_key = Botan::PKCS8::load_key(source);
|
||||||
|
key_ = std::move(priv_key);
|
||||||
|
#else
|
||||||
|
auto priv_key = Botan::PKCS8::load_key(CA_("kea-client.key"), rng);
|
||||||
|
key_.reset(priv_key);
|
||||||
|
#endif
|
||||||
stores_.push_back(store_.get());
|
stores_.push_back(store_.get());
|
||||||
certs_.push_back(cert_);
|
certs_.push_back(cert_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Client_Credentials_Manager()
|
virtual ~Client_Credentials_Manager() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Botan::Certificate_Store*>
|
std::vector<Botan::Certificate_Store*>
|
||||||
trusted_certificate_authorities(const std::string&,
|
trusted_certificate_authorities(const std::string&,
|
||||||
@ -58,25 +71,36 @@ public:
|
|||||||
|
|
||||||
std::vector<Botan::X509_Certificate>
|
std::vector<Botan::X509_Certificate>
|
||||||
cert_chain(const std::vector<std::string>&,
|
cert_chain(const std::vector<std::string>&,
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
const std::vector<Botan::AlgorithmIdentifier>&,
|
||||||
|
#endif
|
||||||
const std::string&,
|
const std::string&,
|
||||||
const std::string&) override
|
const std::string&) override
|
||||||
{
|
{
|
||||||
return certs_;
|
return certs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Botan::Private_Key*
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::Private_Key>
|
||||||
|
#else
|
||||||
|
Botan::Private_Key*
|
||||||
|
#endif
|
||||||
private_key_for(const Botan::X509_Certificate&,
|
private_key_for(const Botan::X509_Certificate&,
|
||||||
const std::string&,
|
const std::string&,
|
||||||
const std::string&) override
|
const std::string&) override
|
||||||
{
|
{
|
||||||
return key_.get();
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
return (key_);
|
||||||
|
#else
|
||||||
|
return (key_.get());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Botan::Certificate_Store*> stores_;
|
std::vector<Botan::Certificate_Store*> stores_;
|
||||||
std::vector<Botan::X509_Certificate> certs_;
|
std::vector<Botan::X509_Certificate> certs_;
|
||||||
std::shared_ptr<Botan::Certificate_Store> store_;
|
std::shared_ptr<Botan::Certificate_Store> store_;
|
||||||
Botan::X509_Certificate cert_;
|
Botan::X509_Certificate cert_;
|
||||||
std::unique_ptr<Botan::Private_Key> key_;
|
std::shared_ptr<Botan::Private_Key> key_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Client_Session_Manager = Botan::TLS::Session_Manager_Noop;
|
using Client_Session_Manager = Botan::TLS::Session_Manager_Noop;
|
||||||
@ -101,8 +125,12 @@ public:
|
|||||||
class client
|
class client
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
client(boost::asio::io_context& io_context,
|
client(boost::asio::io_service& io_context,
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::TLS::Context> context,
|
||||||
|
#else
|
||||||
Botan::TLS::Context& context,
|
Botan::TLS::Context& context,
|
||||||
|
#endif
|
||||||
const tcp::endpoint& endpoint)
|
const tcp::endpoint& endpoint)
|
||||||
: socket_(io_context, context)
|
: socket_(io_context, context)
|
||||||
{
|
{
|
||||||
@ -128,7 +156,11 @@ private:
|
|||||||
|
|
||||||
void handshake()
|
void handshake()
|
||||||
{
|
{
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
socket_.async_handshake(Botan::TLS::Connection_Side::Client,
|
||||||
|
#else
|
||||||
socket_.async_handshake(Botan::TLS::Connection_Side::CLIENT,
|
socket_.async_handshake(Botan::TLS::Connection_Side::CLIENT,
|
||||||
|
#endif
|
||||||
[this](const boost::system::error_code& error)
|
[this](const boost::system::error_code& error)
|
||||||
{
|
{
|
||||||
if (!error)
|
if (!error)
|
||||||
@ -210,11 +242,24 @@ int main(int argc, char* argv[])
|
|||||||
using namespace std; // For atoi.
|
using namespace std; // For atoi.
|
||||||
tcp::endpoint endpoint(
|
tcp::endpoint endpoint(
|
||||||
boost::asio::ip::make_address(argv[1]), atoi(argv[2]));
|
boost::asio::ip::make_address(argv[1]), atoi(argv[2]));
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::AutoSeeded_RNG>
|
||||||
|
rng(new Botan::AutoSeeded_RNG());
|
||||||
|
std::shared_ptr<Client_Credentials_Manager>
|
||||||
|
creds_mgr(new Client_Credentials_Manager());
|
||||||
|
std::shared_ptr<Client_Session_Manager>
|
||||||
|
sess_mgr(new Client_Session_Manager());
|
||||||
|
std::shared_ptr<Client_Policy>
|
||||||
|
policy(new Client_Policy());
|
||||||
|
std::shared_ptr<Botan::TLS::Context>
|
||||||
|
ctx(new Botan::TLS::Context(creds_mgr, rng, sess_mgr, policy));
|
||||||
|
#else
|
||||||
Botan::AutoSeeded_RNG rng;
|
Botan::AutoSeeded_RNG rng;
|
||||||
Client_Credentials_Manager creds_mgr(rng);
|
Client_Credentials_Manager creds_mgr(rng);
|
||||||
Client_Session_Manager sess_mgr;
|
Client_Session_Manager sess_mgr;
|
||||||
Client_Policy policy;
|
Client_Policy policy;
|
||||||
Botan::TLS::Context ctx(creds_mgr, rng, sess_mgr, policy);
|
Botan::TLS::Context ctx(creds_mgr, rng, sess_mgr, policy);
|
||||||
|
#endif
|
||||||
|
|
||||||
client c(io_context, ctx, endpoint);
|
client c(io_context, ctx, endpoint);
|
||||||
|
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#include <botan/certstor_flatfile.h>
|
#include <botan/certstor_flatfile.h>
|
||||||
#include <botan/pkcs8.h>
|
#include <botan/pkcs8.h>
|
||||||
#include <botan/auto_rng.h>
|
#include <botan/auto_rng.h>
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
#include <botan/tls_session_manager_noop.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
inline std::string CA_(const std::string& filename) {
|
inline std::string CA_(const std::string& filename) {
|
||||||
return (std::string(TEST_CA_DIR) + "/" + filename);
|
return (std::string(TEST_CA_DIR) + "/" + filename);
|
||||||
@ -32,19 +35,29 @@ using Server_Certificate_Store = Botan::Flatfile_Certificate_Store;
|
|||||||
class Server_Credentials_Manager : public Botan::Credentials_Manager
|
class Server_Credentials_Manager : public Botan::Credentials_Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
explicit Server_Credentials_Manager()
|
||||||
|
#else
|
||||||
explicit Server_Credentials_Manager(Botan::RandomNumberGenerator& rng)
|
explicit Server_Credentials_Manager(Botan::RandomNumberGenerator& rng)
|
||||||
|
#endif
|
||||||
: stores_(), certs_(),
|
: stores_(), certs_(),
|
||||||
store_(new Server_Certificate_Store(CA_("kea-ca.crt"))),
|
store_(new Server_Certificate_Store(CA_("kea-ca.crt"))),
|
||||||
cert_(Botan::X509_Certificate(CA_("kea-server.crt"))),
|
cert_(Botan::X509_Certificate(CA_("kea-server.crt"))),
|
||||||
key_(Botan::PKCS8::load_key(CA_("kea-server.key"), rng))
|
key_()
|
||||||
{
|
{
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
Botan::DataSource_Stream source(CA_("kea-server.key"));
|
||||||
|
auto priv_key = Botan::PKCS8::load_key(source);
|
||||||
|
key_ = std::move(priv_key);
|
||||||
|
#else
|
||||||
|
auto priv_key = Botan::PKCS8::load_key(CA_("kea-server.key"), rng);
|
||||||
|
key_.reset(priv_key);
|
||||||
|
#endif
|
||||||
stores_.push_back(store_.get());
|
stores_.push_back(store_.get());
|
||||||
certs_.push_back(cert_);
|
certs_.push_back(cert_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Server_Credentials_Manager()
|
virtual ~Server_Credentials_Manager() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Botan::Certificate_Store*>
|
std::vector<Botan::Certificate_Store*>
|
||||||
trusted_certificate_authorities(const std::string&,
|
trusted_certificate_authorities(const std::string&,
|
||||||
@ -55,25 +68,36 @@ public:
|
|||||||
|
|
||||||
std::vector<Botan::X509_Certificate>
|
std::vector<Botan::X509_Certificate>
|
||||||
cert_chain(const std::vector<std::string>&,
|
cert_chain(const std::vector<std::string>&,
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
const std::vector<Botan::AlgorithmIdentifier>&,
|
||||||
|
#endif
|
||||||
const std::string&,
|
const std::string&,
|
||||||
const std::string&) override
|
const std::string&) override
|
||||||
{
|
{
|
||||||
return certs_;
|
return certs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Botan::Private_Key*
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::Private_Key>
|
||||||
|
#else
|
||||||
|
Botan::Private_Key*
|
||||||
|
#endif
|
||||||
private_key_for(const Botan::X509_Certificate&,
|
private_key_for(const Botan::X509_Certificate&,
|
||||||
const std::string&,
|
const std::string&,
|
||||||
const std::string&) override
|
const std::string&) override
|
||||||
{
|
{
|
||||||
return key_.get();
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
return (key_);
|
||||||
|
#else
|
||||||
|
return (key_.get());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Botan::Certificate_Store*> stores_;
|
std::vector<Botan::Certificate_Store*> stores_;
|
||||||
std::vector<Botan::X509_Certificate> certs_;
|
std::vector<Botan::X509_Certificate> certs_;
|
||||||
std::shared_ptr<Botan::Certificate_Store> store_;
|
std::shared_ptr<Botan::Certificate_Store> store_;
|
||||||
Botan::X509_Certificate cert_;
|
Botan::X509_Certificate cert_;
|
||||||
std::unique_ptr<Botan::Private_Key> key_;
|
std::shared_ptr<Botan::Private_Key> key_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Server_Session_Manager = Botan::TLS::Session_Manager_Noop;
|
using Server_Session_Manager = Botan::TLS::Session_Manager_Noop;
|
||||||
@ -98,7 +122,11 @@ public:
|
|||||||
class session : public std::enable_shared_from_this<session>
|
class session : public std::enable_shared_from_this<session>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
session(tcp::socket socket, std::shared_ptr<Botan::TLS::Context> ctx)
|
||||||
|
#else
|
||||||
session(tcp::socket socket, Botan::TLS::Context& ctx)
|
session(tcp::socket socket, Botan::TLS::Context& ctx)
|
||||||
|
#endif
|
||||||
: socket_(std::move(socket), ctx)
|
: socket_(std::move(socket), ctx)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -112,7 +140,11 @@ private:
|
|||||||
void do_handshake()
|
void do_handshake()
|
||||||
{
|
{
|
||||||
auto self(shared_from_this());
|
auto self(shared_from_this());
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
socket_.async_handshake(Botan::TLS::Connection_Side::Server,
|
||||||
|
#else
|
||||||
socket_.async_handshake(Botan::TLS::Connection_Side::SERVER,
|
socket_.async_handshake(Botan::TLS::Connection_Side::SERVER,
|
||||||
|
#endif
|
||||||
[this, self](const boost::system::error_code& error)
|
[this, self](const boost::system::error_code& error)
|
||||||
{
|
{
|
||||||
if (!error)
|
if (!error)
|
||||||
@ -162,12 +194,24 @@ class server
|
|||||||
public:
|
public:
|
||||||
server(boost::asio::io_context& io_context,
|
server(boost::asio::io_context& io_context,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::Credentials_Manager> creds_mgr,
|
||||||
|
std::shared_ptr<Botan::RandomNumberGenerator> rng,
|
||||||
|
std::shared_ptr<Botan::TLS::Session_Manager> sess_mgr,
|
||||||
|
std::shared_ptr<Botan::TLS::Policy> policy
|
||||||
|
#else
|
||||||
Botan::Credentials_Manager& creds_mgr,
|
Botan::Credentials_Manager& creds_mgr,
|
||||||
Botan::RandomNumberGenerator& rng,
|
Botan::RandomNumberGenerator& rng,
|
||||||
Botan::TLS::Session_Manager& sess_mgr,
|
Botan::TLS::Session_Manager& sess_mgr,
|
||||||
Botan::TLS::Policy& policy)
|
Botan::TLS::Policy& policy
|
||||||
|
#endif
|
||||||
|
)
|
||||||
: acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
|
: acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
context_(new Botan::TLS::Context(creds_mgr, rng, sess_mgr, policy))
|
||||||
|
#else
|
||||||
context_(creds_mgr, rng, sess_mgr, policy)
|
context_(creds_mgr, rng, sess_mgr, policy)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
do_accept();
|
do_accept();
|
||||||
}
|
}
|
||||||
@ -188,7 +232,11 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcp::acceptor acceptor_;
|
tcp::acceptor acceptor_;
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::TLS::Context> context_;
|
||||||
|
#else
|
||||||
Botan::TLS::Context context_;
|
Botan::TLS::Context context_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@ -203,10 +251,21 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
boost::asio::io_context io_context;
|
boost::asio::io_context io_context;
|
||||||
|
|
||||||
|
#if BOTAN_VERSION_MAJOR > 2
|
||||||
|
std::shared_ptr<Botan::AutoSeeded_RNG>
|
||||||
|
rng(new Botan::AutoSeeded_RNG());
|
||||||
|
std::shared_ptr<Server_Credentials_Manager>
|
||||||
|
creds_mgr(new Server_Credentials_Manager());
|
||||||
|
std::shared_ptr<Server_Session_Manager>
|
||||||
|
sess_mgr(new Server_Session_Manager());
|
||||||
|
std::shared_ptr<Server_Policy>
|
||||||
|
policy(new Server_Policy());
|
||||||
|
#else
|
||||||
Botan::AutoSeeded_RNG rng;
|
Botan::AutoSeeded_RNG rng;
|
||||||
Server_Credentials_Manager creds_mgr(rng);
|
Server_Credentials_Manager creds_mgr(rng);
|
||||||
Server_Session_Manager sess_mgr;
|
Server_Session_Manager sess_mgr;
|
||||||
Server_Policy policy;
|
Server_Policy policy;
|
||||||
|
#endif
|
||||||
server s(io_context, std::atoi(argv[1]), creds_mgr, rng, sess_mgr, policy);
|
server s(io_context, std::atoi(argv[1]), creds_mgr, rng, sess_mgr, policy);
|
||||||
|
|
||||||
io_context.run();
|
io_context.run();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user