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")) {
 
  102                    isc_throw(LibraryError, 
"Expected a certificate, got '" 
  105                certs_.push_back(Botan::X509_Certificate(cert));
 
  106            } 
catch (
const std::exception& ex) {
 
  107                if (certs_.empty()) {
 
  114        if (certs_.empty()) {
 
  115            isc_throw(LibraryError, 
"Found no certificate?");
 
  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)
 
  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");
 
  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 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.