16#include <botan/auto_rng.h>
17#include <botan/certstor_flatfile.h>
18#include <botan/data_src.h>
20#include <botan/pkcs8.h>
28using KeaCertificateStorePath = Botan::Certificate_Store_In_Memory;
29using KeaCertificateStoreFile = Botan::Flatfile_Certificate_Store;
32class KeaCredentialsManager :
public Botan::Credentials_Manager {
35 KeaCredentialsManager() : store_(), use_stores_(true), certs_(), key_() {
39 virtual ~KeaCredentialsManager() {
44 std::vector<Botan::Certificate_Store*>
45 trusted_certificate_authorities(
const std::string&,
46 const std::string&)
override {
47 std::vector<Botan::Certificate_Store*> result;
48 if (use_stores_ && store_) {
49 result.push_back(store_.get());
55 std::vector<Botan::X509_Certificate>
56 cert_chain(
const std::vector<std::string>&,
58 const std::string&)
override {
64 private_key_for(
const Botan::X509_Certificate&,
66 const std::string&)
override {
71 void setStorePath(
const std::string& path) {
72 store_.reset(
new KeaCertificateStorePath(path));
76 void setStoreFile(
const std::string& file) {
77 store_.reset(
new KeaCertificateStoreFile(file));
81 bool getUseStores()
const {
86 void setUseStores(
bool use_stores) {
87 use_stores_ = use_stores;
91 void setCertChain(
const std::string& file) {
92 Botan::DataSource_Stream source(file);
94 while (!source.end_of_data()) {
96 std::vector<uint8_t> cert;
98 cert = unlock(Botan::PEM_Code::decode(source, label));
99 if ((label !=
"CERTIFICATE") &&
100 (label !=
"X509 CERTIFICATE") &&
101 (label !=
"TRUSTED CERTIFICATE")) {
105 certs_.push_back(Botan::X509_Certificate(cert));
106 }
catch (
const std::exception& ex) {
107 if (certs_.empty()) {
114 if (certs_.empty()) {
120 void setPrivateKey(
const std::string& file,
121 Botan::RandomNumberGenerator& rng,
123 key_.reset(Botan::PKCS8::load_key(file, rng));
126 "Botan::PKCS8::load_key failed but not threw?");
128 is_rsa = (key_->algo_name() ==
"RSA");
132 std::unique_ptr<Botan::Certificate_Store> store_;
138 std::vector<Botan::X509_Certificate> certs_;
141 std::unique_ptr<Botan::Private_Key> key_;
146class KeaPolicy :
public Botan::TLS::Default_Policy {
149 KeaPolicy() : prefer_rsa_(true) {
153 virtual ~KeaPolicy() {
157 std::vector<std::string> allowed_signature_methods()
const override {
159 return (AllowedSignatureMethodsRSA);
161 return (AllowedSignatureMethodsECDSA);
166 bool require_cert_revocation_info()
const override {
171 void setPrefRSA(
bool prefer_rsa) {
172 prefer_rsa_ = prefer_rsa;
179 static const std::vector<std::string> AllowedSignatureMethodsRSA;
182 static const std::vector<std::string> AllowedSignatureMethodsECDSA;
186using KeaSessionManager = Botan::TLS::Session_Manager_Noop;
189const std::vector<std::string>
190KeaPolicy::AllowedSignatureMethodsRSA = {
"RSA",
"DSA",
"ECDSA" };
193const std::vector<std::string>
194KeaPolicy::AllowedSignatureMethodsECDSA = {
"ECDSA",
"RSA",
"DSA" };
197class TlsContextImpl {
200 TlsContextImpl() : cred_mgr_(), rng_(), sess_mgr_(), policy_() {
204 virtual ~TlsContextImpl() {
208 virtual bool getCertRequired()
const {
209 return (cred_mgr_.getUseStores());
215 virtual void setCertRequired(
bool cert_required) {
216 cred_mgr_.setUseStores(cert_required);
220 virtual void loadCaPath(
const std::string& ca_path) {
222 cred_mgr_.setStorePath(ca_path);
223 }
catch (
const std::exception& ex) {
229 virtual void loadCaFile(
const std::string& ca_file) {
231 cred_mgr_.setStoreFile(ca_file);
232 }
catch (
const std::exception& ex) {
238 virtual void loadCertFile(
const std::string& cert_file) {
240 cred_mgr_.setCertChain(cert_file);
241 }
catch (
const std::exception& ex) {
249 virtual void loadKeyFile(
const std::string& key_file) {
252 cred_mgr_.setPrivateKey(key_file, rng_, is_rsa);
253 policy_.setPrefRSA(is_rsa);
254 }
catch (
const std::exception& ex) {
260 virtual void build() {
264 context_.reset(
new Botan::TLS::Context(cred_mgr_,
270 virtual Botan::TLS::Context& get() {
275 KeaCredentialsManager cred_mgr_;
278 Botan::AutoSeeded_RNG rng_;
281 KeaSessionManager sess_mgr_;
285 std::unique_ptr<Botan::TLS::Context> context_;
288TlsContext::~TlsContext() {
291TlsContext::TlsContext(
TlsRole role)
292 : TlsContextBase(role), impl_(new TlsContextImpl()) {
296TlsContext::getContext() {
298 return (impl_->get());
302TlsContext::setCertRequired(
bool cert_required) {
303 if (!cert_required && (getRole() == TlsRole::CLIENT)) {
305 "'cert-required' parameter must be true for a TLS client");
307 impl_->setCertRequired(cert_required);
311TlsContext::getCertRequired()
const {
312 return (impl_->getCertRequired());
316TlsContext::loadCaFile(
const std::string& ca_file) {
317 impl_->loadCaFile(ca_file);
321TlsContext::loadCaPath(
const std::string& ca_path) {
322 impl_->loadCaPath(ca_path);
326TlsContext::loadCertFile(
const std::string& cert_file) {
327 impl_->loadCertFile(cert_file);
331TlsContext::loadKeyFile(
const std::string& key_file) {
332 impl_->loadKeyFile(key_file);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
This exception is raised when a general error that was not specifically caught is thrown by the under...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A wrapper interface for the ASIO library.
TlsRole
Client and server roles.
Defines the logger used by the top-level component of kea-lfc.