16#include <botan/auto_rng.h>
17#include <botan/certstor_flatfile.h>
18#include <botan/data_src.h>
20#include <botan/pkcs8.h>
21#include <botan/tls_session_manager_noop.h>
29using KeaCertificateStorePath = Botan::Certificate_Store_In_Memory;
30using KeaCertificateStoreFile = Botan::Flatfile_Certificate_Store;
33class KeaCredentialsManager :
public Botan::Credentials_Manager {
36 KeaCredentialsManager() : store_(), use_stores_(true), certs_(), key_() {
40 virtual ~KeaCredentialsManager() =
default;
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>&,
57 const std::vector<Botan::AlgorithmIdentifier>&,
59 const std::string&)
override {
64 std::shared_ptr<Botan::Private_Key>
65 private_key_for(
const Botan::X509_Certificate&,
67 const std::string&)
override {
72 void setStorePath(
const std::string& path) {
73 store_.reset(
new KeaCertificateStorePath(path));
77 void setStoreFile(
const std::string& file) {
78 store_.reset(
new KeaCertificateStoreFile(file));
82 bool getUseStores()
const {
87 void setUseStores(
bool use_stores) {
88 use_stores_ = use_stores;
92 void setCertChain(
const std::string& file) {
93 Botan::DataSource_Stream source(file);
95 while (!source.end_of_data()) {
97 std::vector<uint8_t> cert;
99 cert = unlock(Botan::PEM_Code::decode(source, label));
100 if ((label !=
"CERTIFICATE") &&
101 (label !=
"X509 CERTIFICATE") &&
102 (label !=
"TRUSTED CERTIFICATE")) {
103 isc_throw(LibraryError,
"Expected a certificate, got '"
106 certs_.push_back(Botan::X509_Certificate(cert));
107 }
catch (
const std::exception& ex) {
108 if (certs_.empty()) {
115 if (certs_.empty()) {
116 isc_throw(LibraryError,
"Found no certificate?");
121 void setPrivateKey(
const std::string& file,
122 Botan::RandomNumberGenerator&,
124 Botan::DataSource_Stream source(file);
125 auto priv_key = Botan::PKCS8::load_key(source);
128 "Botan::PKCS8::load_key failed but not threw?");
130 key_ = std::move(priv_key);
131 is_rsa = (key_->algo_name() ==
"RSA");
135 std::unique_ptr<Botan::Certificate_Store> store_;
141 std::vector<Botan::X509_Certificate> certs_;
144 std::shared_ptr<Botan::Private_Key> key_;
149class KeaPolicy :
public Botan::TLS::Default_Policy {
152 KeaPolicy() : prefer_rsa_(true) {
156 virtual ~KeaPolicy() {
160 std::vector<std::string> allowed_signature_methods()
const override {
162 return (AllowedSignatureMethodsRSA);
164 return (AllowedSignatureMethodsECDSA);
169 bool require_cert_revocation_info()
const override {
174 void setPrefRSA(
bool prefer_rsa) {
175 prefer_rsa_ = prefer_rsa;
182 static const std::vector<std::string> AllowedSignatureMethodsRSA;
185 static const std::vector<std::string> AllowedSignatureMethodsECDSA;
189using KeaSessionManager = Botan::TLS::Session_Manager_Noop;
192const std::vector<std::string>
193KeaPolicy::AllowedSignatureMethodsRSA = {
"RSA",
"DSA",
"ECDSA" };
196const std::vector<std::string>
197KeaPolicy::AllowedSignatureMethodsECDSA = {
"ECDSA",
"RSA",
"DSA" };
200class TlsContextImpl {
204 cred_mgr_(new KeaCredentialsManager()),
205 rng_(new Botan::AutoSeeded_RNG()),
206 sess_mgr_(new KeaSessionManager()),
207 policy_(new KeaPolicy()) {
211 virtual ~TlsContextImpl() =
default;
214 virtual bool getCertRequired()
const {
215 return (cred_mgr_->getUseStores());
221 virtual void setCertRequired(
bool cert_required) {
222 cred_mgr_->setUseStores(cert_required);
226 virtual void loadCaPath(
const std::string& ca_path) {
228 cred_mgr_->setStorePath(ca_path);
229 }
catch (
const std::exception& ex) {
235 virtual void loadCaFile(
const std::string& ca_file) {
237 cred_mgr_->setStoreFile(ca_file);
238 }
catch (
const std::exception& ex) {
244 virtual void loadCertFile(
const std::string& cert_file) {
246 cred_mgr_->setCertChain(cert_file);
247 }
catch (
const std::exception& ex) {
255 virtual void loadKeyFile(
const std::string& key_file) {
258 cred_mgr_->setPrivateKey(key_file, *rng_, is_rsa);
259 policy_->setPrefRSA(is_rsa);
260 }
catch (
const std::exception& ex) {
266 virtual void build() {
270 context_.reset(
new Botan::TLS::Context(cred_mgr_,
277 virtual std::shared_ptr<Botan::TLS::Context>
get() {
282 std::shared_ptr<KeaCredentialsManager> cred_mgr_;
285 std::shared_ptr<Botan::AutoSeeded_RNG> rng_;
288 std::shared_ptr<KeaSessionManager> sess_mgr_;
290 std::shared_ptr<KeaPolicy> policy_;
292 std::shared_ptr<Botan::TLS::Context> context_;
295TlsContext::~TlsContext() {
298TlsContext::TlsContext(
TlsRole role)
302std::shared_ptr<Botan::TLS::Context>
303TlsContext::getContext() {
305 return (impl_->get());
309TlsContext::setCertRequired(
bool cert_required) {
310 if (!cert_required && (getRole() == TlsRole::CLIENT)) {
312 "'cert-required' parameter must be true for a TLS client");
318TlsContext::getCertRequired()
const {
319 return (impl_->getCertRequired());
323TlsContext::loadCaFile(
const std::string& ca_file) {
324 impl_->loadCaFile(ca_file);
328TlsContext::loadCaPath(
const std::string& ca_path) {
329 impl_->loadCaPath(ca_path);
333TlsContext::loadCertFile(
const std::string& cert_file) {
334 impl_->loadCertFile(cert_file);
338TlsContext::loadKeyFile(
const std::string& key_file) {
339 impl_->loadKeyFile(key_file);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual void setCertRequired(bool cert_required)=0
Set the peer certificate requirement mode.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
int get(CalloutHandle &handle)
The gss-tsig-get command.
TlsRole
Client and server roles.
Defines the logger used by the top-level component of kea-lfc.