#ifdef WITH_OPENSSL
expected += "No such file or directory";
#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
testInvalidConfig(patched, expected);
}
#ifdef WITH_OPENSSL
expected += "No such file or directory";
#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
testInvalidConfig(patched, expected);
}
#ifdef WITH_OPENSSL
expected += "No such file or directory";
#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
testInvalidConfig(patched, expected);
}
#include <botan/data_src.h>
#include <botan/pem.h>
#include <botan/pkcs8.h>
+#if BOTAN_VERSION_MAJOR > 2
+#include <botan/tls_session_manager_noop.h>
+#endif
using namespace isc::cryptolink;
}
// Destructor.
- virtual ~KeaCredentialsManager() {
- }
+ virtual ~KeaCredentialsManager() = default;
// CA certificate stores.
// nullptr means do not require or check peer certificate.
// Certificate chain.
std::vector<Botan::X509_Certificate>
cert_chain(const std::vector<std::string>&,
+#if BOTAN_VERSION_MAJOR > 2
+ const std::vector<Botan::AlgorithmIdentifier>&,
+#endif
const std::string&,
const std::string&) override {
return (certs_);
}
// 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&,
const std::string&,
const std::string&) override {
+#if BOTAN_VERSION_MAJOR > 2
+ return (key_);
+#else
return (key_.get());
+#endif
}
// Set the store from a path.
// Set the private key.
void setPrivateKey(const std::string& file,
+#if BOTAN_VERSION_MAJOR > 2
+ Botan::RandomNumberGenerator&,
+#else
Botan::RandomNumberGenerator& rng,
+#endif
bool& is_rsa) {
- key_.reset(Botan::PKCS8::load_key(file, rng));
- if (!key_) {
+#if BOTAN_VERSION_MAJOR > 2
+ 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,
"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");
}
std::vector<Botan::X509_Certificate> certs_;
// Pointer to the private key.
- std::unique_ptr<Botan::Private_Key> key_;
+ std::shared_ptr<Botan::Private_Key> key_;
};
// Class of Kea policy.
class TlsContextImpl {
public:
// 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.
- virtual ~TlsContextImpl() {
- }
+ virtual ~TlsContextImpl() = default;
// Get the peer certificate requirement mode.
virtual bool getCertRequired() const {
- return (cred_mgr_.getUseStores());
+ return (cred_mgr_->getUseStores());
}
// Set the peer certificate requirement mode.
//
// With Botan this means to provide or not the CA certificate stores.
virtual void setCertRequired(bool cert_required) {
- cred_mgr_.setUseStores(cert_required);
+ cred_mgr_->setUseStores(cert_required);
}
// Load the trust anchor aka certificate authority (path).
virtual void loadCaPath(const std::string& ca_path) {
try {
- cred_mgr_.setStorePath(ca_path);
+ cred_mgr_->setStorePath(ca_path);
} catch (const std::exception& ex) {
isc_throw(LibraryError, ex.what());
}
// Load the trust anchor aka certificate authority (file).
virtual void loadCaFile(const std::string& ca_file) {
try {
- cred_mgr_.setStoreFile(ca_file);
+ cred_mgr_->setStoreFile(ca_file);
} catch (const std::exception& ex) {
isc_throw(LibraryError, ex.what());
}
/// @brief Load the certificate file.
virtual void loadCertFile(const std::string& cert_file) {
try {
- cred_mgr_.setCertChain(cert_file);
+ cred_mgr_->setCertChain(cert_file);
} catch (const std::exception& ex) {
isc_throw(LibraryError, ex.what());
}
virtual void loadKeyFile(const std::string& key_file) {
try {
bool is_rsa = true;
- cred_mgr_.setPrivateKey(key_file, rng_, is_rsa);
- policy_.setPrefRSA(is_rsa);
+ cred_mgr_->setPrivateKey(key_file, *rng_, is_rsa);
+ policy_->setPrefRSA(is_rsa);
} catch (const std::exception& ex) {
isc_throw(LibraryError, ex.what());
}
if (context_) {
return;
}
+#if BOTAN_VERSION_MAJOR > 2
context_.reset(new Botan::TLS::Context(cred_mgr_,
rng_,
sess_mgr_,
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() {
return (*context_);
}
+#endif
// Credentials Manager.
- KeaCredentialsManager cred_mgr_;
+ std::shared_ptr<KeaCredentialsManager> cred_mgr_;
// Random Number Generator.
- Botan::AutoSeeded_RNG rng_;
+ std::shared_ptr<Botan::AutoSeeded_RNG> rng_;
// 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() {
: 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&
TlsContext::getContext() {
impl_->build();
return (impl_->get());
}
+#endif
void
TlsContext::setCertRequired(bool cert_required) {
/// @brief Translate TLS role into implementation.
inline Botan::TLS::Connection_Side roleToImpl(TlsRole role) {
if (role == TlsRole::SERVER) {
+#if BOTAN_VERSION_MAJOR > 2
+ return (Botan::TLS::Connection_Side::Server);
+#else
return (Botan::TLS::Connection_Side::SERVER);
+#endif
} else {
+#if BOTAN_VERSION_MAJOR > 2
+ return (Botan::TLS::Connection_Side::Client);
+#else
return (Botan::TLS::Connection_Side::CLIENT);
+#endif
}
}
explicit TlsContext(TlsRole role);
/// @brief Return the underlying context.
+#if BOTAN_VERSION_MAJOR > 2
+ std::shared_ptr<Botan::TLS::Context> getContext();
+#else
Botan::TLS::Context& getContext();
+#endif
/// @brief Get the peer certificate requirement mode.
///
Expecteds exps;
// 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'");
// OpenSSL errors.
exps.addThrow("No such file or directory");
exps.addThrow("No such file or directory (system library)");
Expecteds exps;
// 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'");
// OpenSSL errors.
exps.addThrow("No such file or directory");
exps.addThrow("No such file or directory (system library)");
Expecteds exps;
// 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'");
// OpenSSL errors.
exps.addThrow("No such file or directory");
exps.addThrow("No such file or directory (system library)");
string botan_error = "PKCS #8 private key decoding failed with PKCS #8: ";
botan_error += "Unknown PEM label CERTIFICATE";
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.
exps.addThrow("no start line");
exps.addThrow("no start line (PEM routines)");
// Botan error.
string botan_error = "I/O error: DataSource: Failure opening file /no-such-file";
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.
string openssl_error = "No such file or directory";
exps.addThrow(common_error + openssl_error);
exps.clear();
// On Botan and some OpenSSL the client hangs.
exps.addTimeout();
+ exps.addError("handshake_failure");
// OpenSSL errors.
exps.addError("sslv3 alert handshake failure");
exps.addError("sslv3 alert handshake failure (SSL routines)");
Expecteds exps;
// On Botan and some OpenSSL the server hangs.
exps.addTimeout();
+ exps.addError("bad_certificate");
// OpenSSL errors.
exps.addError("tlsv1 alert unknown ca");
exps.addError("tlsv1 alert unknown ca (SSL routines)");
exps.addTimeout();
// Botan error.
exps.addError("protocol_version");
+ exps.addError("unexpected_message");
// Old LibreSSL error.
exps.addError("tlsv1 alert protocol version");
// OpenSSL errors (OpenSSL recognizes HTTP).
// Botan errors.
exps.addError("record_overflow");
exps.addError("protocol_version");
+ exps.addError("unexpected_message");
// Old LibreSSL error.
exps.addError("tlsv1 alert protocol version");
// Old OpenSSL error.
exps.clear();
// Botan and some OpenSSL.
exps.addError("stream truncated");
+ exps.addError("handshake_failure");
// Alias on old OpenSSL.
exps.addError("short read");
// OpenSSL errors.
Expecteds exps;
// Botan and some OpenSSL.
exps.addError("stream truncated");
+ exps.addError("bad_certificate");
// Alias on old OpenSSL.
exps.addError("short read");
// OpenSSL errors.
exps.addTimeout();
// Botan behavior was reported and fixed.
exps.addError("protocol_version");
+ exps.addError("unexpected_message");
// Old LibreSSL error.
exps.addError("tlsv1 alert protocol version");
// OpenSSL errors when OpenSSL recognizes HTTP.
#include <botan/certstor_flatfile.h>
#include <botan/pkcs8.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) {
return (std::string(TEST_CA_DIR) + "/" + filename);
class Client_Credentials_Manager : public Botan::Credentials_Manager
{
public:
+#if BOTAN_VERSION_MAJOR > 2
+ explicit Client_Credentials_Manager()
+#else
explicit Client_Credentials_Manager(Botan::RandomNumberGenerator& rng)
+#endif
: stores_(), certs_(),
store_(new Client_Certificate_Store(CA_("kea-ca.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());
certs_.push_back(cert_);
}
- virtual ~Client_Credentials_Manager()
- {
- }
+ virtual ~Client_Credentials_Manager() = default;
std::vector<Botan::Certificate_Store*>
trusted_certificate_authorities(const std::string&,
std::vector<Botan::X509_Certificate>
cert_chain(const std::vector<std::string>&,
+#if BOTAN_VERSION_MAJOR > 2
+ const std::vector<Botan::AlgorithmIdentifier>&,
+#endif
const std::string&,
const std::string&) override
{
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&,
const std::string&,
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::X509_Certificate> certs_;
std::shared_ptr<Botan::Certificate_Store> store_;
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;
class client
{
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,
+#endif
const tcp::endpoint& endpoint)
: socket_(io_context, context)
{
void handshake()
{
+#if BOTAN_VERSION_MAJOR > 2
+ socket_.async_handshake(Botan::TLS::Connection_Side::Client,
+#else
socket_.async_handshake(Botan::TLS::Connection_Side::CLIENT,
+#endif
[this](const boost::system::error_code& error)
{
if (!error)
using namespace std; // For atoi.
tcp::endpoint endpoint(
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;
Client_Credentials_Manager creds_mgr(rng);
Client_Session_Manager sess_mgr;
Client_Policy policy;
Botan::TLS::Context ctx(creds_mgr, rng, sess_mgr, policy);
+#endif
client c(io_context, ctx, endpoint);
#include <botan/certstor_flatfile.h>
#include <botan/pkcs8.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) {
return (std::string(TEST_CA_DIR) + "/" + filename);
class Server_Credentials_Manager : public Botan::Credentials_Manager
{
public:
+#if BOTAN_VERSION_MAJOR > 2
+ explicit Server_Credentials_Manager()
+#else
explicit Server_Credentials_Manager(Botan::RandomNumberGenerator& rng)
+#endif
: stores_(), certs_(),
store_(new Server_Certificate_Store(CA_("kea-ca.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());
certs_.push_back(cert_);
}
- virtual ~Server_Credentials_Manager()
- {
- }
+ virtual ~Server_Credentials_Manager() = default;
std::vector<Botan::Certificate_Store*>
trusted_certificate_authorities(const std::string&,
std::vector<Botan::X509_Certificate>
cert_chain(const std::vector<std::string>&,
+#if BOTAN_VERSION_MAJOR > 2
+ const std::vector<Botan::AlgorithmIdentifier>&,
+#endif
const std::string&,
const std::string&) override
{
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&,
const std::string&,
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::X509_Certificate> certs_;
std::shared_ptr<Botan::Certificate_Store> store_;
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;
class session : public std::enable_shared_from_this<session>
{
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)
+#endif
: socket_(std::move(socket), ctx)
{
}
void do_handshake()
{
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,
+#endif
[this, self](const boost::system::error_code& error)
{
if (!error)
public:
server(boost::asio::io_context& io_context,
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::RandomNumberGenerator& rng,
Botan::TLS::Session_Manager& sess_mgr,
- Botan::TLS::Policy& policy)
+ Botan::TLS::Policy& policy
+#endif
+ )
: 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)
+#endif
{
do_accept();
}
}
tcp::acceptor acceptor_;
+#if BOTAN_VERSION_MAJOR > 2
+ std::shared_ptr<Botan::TLS::Context> context_;
+#else
Botan::TLS::Context context_;
+#endif
};
int main(int argc, char* argv[])
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;
Server_Credentials_Manager creds_mgr(rng);
Server_Session_Manager sess_mgr;
Server_Policy policy;
+#endif
server s(io_context, std::atoi(argv[1]), creds_mgr, rng, sess_mgr, policy);
io_context.run();