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.