Commit 4b4110dd authored by Francis Dupont's avatar Francis Dupont

applied #2406: OpenSSL alternate crypto backend

parent 314c47ea
794. [func] fdupont
cryptolink: add OpenSSL crypto backend as an alternative to Botan
by specifying --with-openssl[=PATH] on the "configure" command
line. Add hash support to the cryptolink API and use it in DHCP
DDNS, removing the Botan dependency.
(Trac #2406, git xxx)
793. [func] tmark
DHCP-DDNS: Implemented dynamic reconfiguration of the server,
triggered when the SIGHUP signal is received by the server's
......
......@@ -7,6 +7,7 @@ USE_LCOV=@USE_LCOV@
LCOV=@LCOV@
GENHTML=@GENHTML@
DISTCHECK_GTEST_CONFIGURE_FLAG=@DISTCHECK_GTEST_CONFIGURE_FLAG@
DISTCHECK_CRYPTO_CONFIGURE_FLAG=@DISTCHECK_CRYPTO_CONFIGURE_FLAG@
DISTCLEANFILES = config.report
......@@ -16,6 +17,9 @@ DISTCHECK_CONFIGURE_FLAGS = --disable-install-configurations
# Use same --with-gtest flag if set
DISTCHECK_CONFIGURE_FLAGS += $(DISTCHECK_GTEST_CONFIGURE_FLAG)
# Keep the crypto backend config
DISTCHECK_CONFIGURE_FLAGS += $(DISTCHECK_CRYPTO_CONFIGURE_FLAG)
dist_doc_DATA = AUTHORS COPYING ChangeLog README
.PHONY: check-valgrind check-valgrind-suppress
......@@ -73,12 +77,17 @@ report-cpp-coverage:
c++/4.4\*/ext/\* \
c++/4.4\*/\*-\*/bits/\* \
boost/\* \
if HAVE_BOTAN
botan/\* \
endif
ext/asio/\* \
ext/coroutine/\* \
gtest/\* \
log4cplus/\* \
include/\* \
log4cplus/\* \
if HAVE_OPENSSL
openssl/\* \
endif
tests/\* \
unittests/\* \
\*_unittests.cc \
......
This diff is collapsed.
......@@ -6,6 +6,6 @@ includedir=@includedir@
Name: dns++
Description: BIND 10 DNS library
Version: @PACKAGE_VERSION@
Requires: botan-1.8
Requires: @CRYPTO_PACKAGE@
Cflags: -I${includedir}/@PACKAGE_NAME@
Libs: -L${libdir} -lb10-dns++ -lb10-cryptolink -lb10-util -lb10-exceptions -lm
......@@ -138,9 +138,13 @@
</para>
<para>
Kea uses the Botan crypto library for C++
(<ulink url="http://botan.randombit.net/"/>).
It requires at least Botan version 1.8.
Kea supports two crypto libraries: Botan and OpenSSL. Only one
of them is required during compilation. Kea uses the Botan crypto
library for C++ (<ulink url="http://botan.randombit.net/"/>).
It requires at least Botan version 1.8. As an alternative to Botan,
Kea can use the OpenSSL crypto library
(<ulink url="http://www.openssl.org/"/>).
It requires a version with SHA-2 support.
</para>
<para>
......@@ -546,7 +550,7 @@ $ <userinput>./configure</userinput></screen>
<para>
To build Kea, also install the Botan (at least version
1.8) and the log4cplus (at least version 1.0.3)
1.8) or OpenSSL, and the log4cplus (at least version 1.0.3)
development include headers.
</para>
......@@ -696,6 +700,17 @@ as a dependency earlier -->
</listitem>
</varlistentry>
<varlistentry>
<term>--with-openssl</term>
<listitem>
<simpara>Replace Botan by OpenSSL for the crypto library.
The default is to try to find a working Botan then
OpenSSL only if not found.
<!-- missing -with-botan-config -->
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>--without-werror</term>
<listitem>
......
......@@ -52,9 +52,16 @@ b10-cmdctl: cmdctl.py $(PYTHON_LOGMSGPKG_DIR)/work/cmdctl_messages.py $(CERTFILE
$(SED) "s|@@PYTHONPATH@@|@pyexecdir@|" cmdctl.py >$@
chmod a+x $@
b10_certgen_SOURCES = b10-certgen.cc
b10_certgen_CXXFLAGS = $(BOTAN_INCLUDES)
b10_certgen_LDFLAGS = $(BOTAN_LIBS)
if HAVE_BOTAN
b10_certgen_SOURCES = botan-certgen.cc
EXTRA_DIST += openssl-certgen.cc
endif
if HAVE_OPENSSL
b10_certgen_SOURCES = openssl-certgen.cc
EXTRA_DIST += botan-certgen.cc
endif
b10_certgen_CXXFLAGS = $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES)
b10_certgen_LDFLAGS = $(CRYPTO_LIBS)
# Generate the initial certificates immediately
cmdctl-keyfile.pem: b10-certgen
......
This diff is collapsed.
PYCOVERAGE_RUN=@PYCOVERAGE_RUN@
PYTESTS = cmdctl_test.py b10-certgen_test.py
EXTRA_DIST = $(PYTESTS)
PYTESTS = cmdctl_test.py
EXTRA_DIST =
if HAVE_BOTAN
PYTESTS += botan-certgen_test.py
EXTRA_DIST += openssl-certgen_test.py
endif
if HAVE_OPENSSL
EXTRA_DIST += botan-certgen_test.py
PYTESTS += openssl-certgen_test.py
endif
EXTRA_DIST += $(PYTESTS)
EXTRA_DIST += testdata/expired-certfile.pem
EXTRA_DIST += testdata/mangled-certfile.pem
EXTRA_DIST += testdata/noca-certfile.pem
......
This diff is collapsed.
......@@ -2,7 +2,7 @@ SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/user_chk -I$(top_srcdir)/src/hooks/dhcp/user_chk
AM_CPPFLAGS += $(BOOST_INCLUDES) $(BOTAN_INCLUDES)
AM_CPPFLAGS += $(BOOST_INCLUDES) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES)
AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_srcdir)/src/hooks/dhcp/user_chk/tests\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
......@@ -71,7 +71,7 @@ libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.l
libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
libdhcp_user_chk_unittests_LDADD += ${BOTAN_LIBS} ${BOTAN_RPATH}
libdhcp_user_chk_unittests_LDADD += ${CRYPTO_LIBS} ${CRYPTO_RPATH}
libdhcp_user_chk_unittests_LDADD += $(GTEST_LDADD)
endif
noinst_PROGRAMS = $(TESTS)
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(BOTAN_INCLUDES)
AM_CPPFLAGS += $(BOOST_INCLUDES) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
CLEANFILES = *.gcno *.gcda
......@@ -9,7 +9,18 @@ CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = libkea-cryptolink.la
libkea_cryptolink_la_SOURCES = cryptolink.h cryptolink.cc
libkea_cryptolink_la_SOURCES += crypto_hash.h crypto_hash.cc
libkea_cryptolink_la_SOURCES += crypto_hmac.h crypto_hmac.cc
if HAVE_BOTAN
libkea_cryptolink_la_SOURCES += botan_link.cc
libkea_cryptolink_la_SOURCES += botan_hash.cc
libkea_cryptolink_la_SOURCES += botan_hmac.cc
endif
if HAVE_OPENSSL
libkea_cryptolink_la_SOURCES += openssl_link.cc
libkea_cryptolink_la_SOURCES += openssl_hash.cc
libkea_cryptolink_la_SOURCES += openssl_hmac.cc
endif
libkea_cryptolink_la_LDFLAGS = ${BOTAN_LDFLAGS}
libkea_cryptolink_la_LIBADD = ${BOTAN_LIBS} ${BOTAN_RPATH}
libkea_cryptolink_la_LDFLAGS = ${CRYPTO_LDFLAGS}
libkea_cryptolink_la_LIBADD = ${CRYPTO_LIBS} ${CRYPTO_RPATH}
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <cryptolink.h>
#include <cryptolink/crypto_hash.h>
#include <boost/scoped_ptr.hpp>
#include <botan/version.h>
#include <botan/botan.h>
#include <botan/hash.h>
#include <botan/types.h>
#include <cstring>
namespace {
/// @brief Decode the HashAlgorithm enum into a name usable by Botan
///
/// @param algorithm algorithm to be converted
/// @return text representation of the algorithm name
const char*
getBotanHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm) {
switch (algorithm) {
case isc::cryptolink::MD5:
return ("MD5");
case isc::cryptolink::SHA1:
return ("SHA-1");
case isc::cryptolink::SHA256:
return ("SHA-256");
case isc::cryptolink::SHA224:
return ("SHA-224");
case isc::cryptolink::SHA384:
return ("SHA-384");
case isc::cryptolink::SHA512:
return ("SHA-512");
case isc::cryptolink::UNKNOWN_HASH:
return ("Unknown");
}
// compiler should have prevented us to reach this, since we have
// no default. But we need a return value anyway
return ("Unknown");
}
} // local namespace
namespace isc {
namespace cryptolink {
/// @brief Botan implementation of Hash. Each method is the counterpart
/// of the Hash corresponding method.
class HashImpl {
public:
/// @brief Constructor for specific hash algorithm
///
/// @param hash_algorithm The hash algorithm
explicit HashImpl(const HashAlgorithm hash_algorithm) {
Botan::HashFunction* hash;
try {
hash = Botan::get_hash(
getBotanHashAlgorithmName(hash_algorithm));
} catch (const Botan::Algorithm_Not_Found&) {
isc_throw(isc::cryptolink::UnsupportedAlgorithm,
"Unknown hash algorithm: " <<
static_cast<int>(hash_algorithm));
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
hash_.reset(hash);
}
/// @brief Destructor
~HashImpl() { }
/// @brief Returns the output size of the digest
///
/// @return output size of the digest
size_t getOutputLength() const {
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0)
return (hash_->output_length());
#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0)
return (hash_->OUTPUT_LENGTH);
#else
#error "Unsupported Botan version (need 1.8 or higher)"
// added to suppress irrelevant compiler errors
return 0;
#endif
}
/// @brief Adds data to the digest
///
/// See @ref isc::cryptolink::Hash::update() for details.
void update(const void* data, const size_t len) {
try {
hash_->update(static_cast<const Botan::byte*>(data), len);
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Calculate the final digest
///
/// See @ref isc::cryptolink::Hash::final() for details.
void final(isc::util::OutputBuffer& result, size_t len) {
try {
Botan::SecureVector<Botan::byte> b_result(hash_->final());
if (len == 0 || len > b_result.size()) {
len = b_result.size();
}
result.writeData(b_result.begin(), len);
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Calculate the final digest
///
/// See @ref isc::cryptolink::Hash::final() for details.
void final(void* result, size_t len) {
try {
Botan::SecureVector<Botan::byte> b_result(hash_->final());
size_t output_size = getOutputLength();
if (output_size > len) {
output_size = len;
}
std::memcpy(result, b_result.begin(), output_size);
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Calculate the final digest
///
/// See @ref isc::cryptolink::Hash::final() for details.
std::vector<uint8_t> final(size_t len) {
try {
Botan::SecureVector<Botan::byte> b_result(hash_->final());
if (len == 0 || len > b_result.size()) {
return (std::vector<uint8_t>(b_result.begin(), b_result.end()));
} else {
return (std::vector<uint8_t>(b_result.begin(), &b_result[len]));
}
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
private:
/// \brief The protected pointer to the Botan HashFunction object
boost::scoped_ptr<Botan::HashFunction> hash_;
};
Hash::Hash(const HashAlgorithm hash_algorithm)
{
impl_ = new HashImpl(hash_algorithm);
}
Hash::~Hash() {
delete impl_;
}
size_t
Hash::getOutputLength() const {
return (impl_->getOutputLength());
}
void
Hash::update(const void* data, const size_t len) {
impl_->update(data, len);
}
void
Hash::final(isc::util::OutputBuffer& result, size_t len) {
impl_->final(result, len);
}
void
Hash::final(void* result, size_t len) {
impl_->final(result, len);
}
std::vector<uint8_t>
Hash::final(size_t len) {
return impl_->final(len);
}
} // namespace cryptolink
} // namespace isc
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <cryptolink.h>
#include <cryptolink/crypto_hmac.h>
#include <boost/scoped_ptr.hpp>
#include <botan/version.h>
#include <botan/botan.h>
#include <botan/hmac.h>
#include <botan/hash.h>
#include <botan/types.h>
#include <cstring>
namespace {
/// @brief Decode the HashAlgorithm enum into a name usable by Botan
///
/// @param algorithm algorithm to be converted
/// @return text representation of the algorithm name
const char*
getBotanHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm) {
switch (algorithm) {
case isc::cryptolink::MD5:
return ("MD5");
case isc::cryptolink::SHA1:
return ("SHA-1");
case isc::cryptolink::SHA256:
return ("SHA-256");
case isc::cryptolink::SHA224:
return ("SHA-224");
case isc::cryptolink::SHA384:
return ("SHA-384");
case isc::cryptolink::SHA512:
return ("SHA-512");
case isc::cryptolink::UNKNOWN_HASH:
return ("Unknown");
}
// compiler should have prevented us to reach this, since we have
// no default. But we need a return value anyway
return ("Unknown");
}
} // local namespace
namespace isc {
namespace cryptolink {
/// @brief Botan implementation of HMAC. Each method is the counterpart
/// of the HMAC corresponding method.
class HMACImpl {
public:
/// @brief Constructor from a secret and a hash algorithm
///
/// See constructor of the @ref isc::cryptolink::HMAC class for details.
///
/// @param secret The secret to sign with
/// @param secret_len The length of the secret
/// @param hash_algorithm The hash algorithm
explicit HMACImpl(const void* secret, size_t secret_len,
const HashAlgorithm hash_algorithm) {
Botan::HashFunction* hash;
try {
hash = Botan::get_hash(
getBotanHashAlgorithmName(hash_algorithm));
} catch (const Botan::Algorithm_Not_Found&) {
isc_throw(isc::cryptolink::UnsupportedAlgorithm,
"Unknown hash algorithm: " <<
static_cast<int>(hash_algorithm));
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
hmac_.reset(new Botan::HMAC(hash));
// If the key length is larger than the block size, we hash the
// key itself first.
try {
// use a temp var so we don't have blocks spanning
// preprocessor directives
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0)
size_t block_length = hash->hash_block_size();
#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0)
size_t block_length = hash->HASH_BLOCK_SIZE;
#else
#error "Unsupported Botan version (need 1.8 or higher)"
// added to suppress irrelevant compiler errors
size_t block_length = 0;
#endif
if (secret_len > block_length) {
Botan::SecureVector<Botan::byte> hashed_key =
hash->process(static_cast<const Botan::byte*>(secret),
secret_len);
hmac_->set_key(hashed_key.begin(), hashed_key.size());
} else {
// Botan 1.8 considers len 0 a bad key. 1.9 does not,
// but we won't accept it anyway, and fail early
if (secret_len == 0) {
isc_throw(BadKey, "Bad HMAC secret length: 0");
}
hmac_->set_key(static_cast<const Botan::byte*>(secret),
secret_len);
}
} catch (const Botan::Invalid_Key_Length& ikl) {
isc_throw(BadKey, ikl.what());
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Destructor
~HMACImpl() {
}
/// @brief Returns the output size of the digest
///
/// @return output size of the digest
size_t getOutputLength() const {
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0)
return (hmac_->output_length());
#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0)
return (hmac_->OUTPUT_LENGTH);
#else
#error "Unsupported Botan version (need 1.8 or higher)"
// added to suppress irrelevant compiler errors
return 0;
#endif
}
/// @brief Add data to digest
///
/// See @ref isc::cryptolink::HMAC::update() for details.
void update(const void* data, const size_t len) {
try {
hmac_->update(static_cast<const Botan::byte*>(data), len);
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Calculate the final signature
///
/// See @ref isc::cryptolink::HMAC::sign() for details.
void sign(isc::util::OutputBuffer& result, size_t len) {
try {
Botan::SecureVector<Botan::byte> b_result(hmac_->final());
if (len == 0 || len > b_result.size()) {
len = b_result.size();
}
result.writeData(b_result.begin(), len);
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Calculate the final signature
///
/// See @ref isc::cryptolink::HMAC::sign() for details.
void sign(void* result, size_t len) {
try {
Botan::SecureVector<Botan::byte> b_result(hmac_->final());
size_t output_size = getOutputLength();
if (output_size > len) {
output_size = len;
}
std::memcpy(result, b_result.begin(), output_size);
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Calculate the final signature
///
/// See @ref isc::cryptolink::HMAC::sign() for details.
std::vector<uint8_t> sign(size_t len) {
try {
Botan::SecureVector<Botan::byte> b_result(hmac_->final());
if (len == 0 || len > b_result.size()) {
return (std::vector<uint8_t>(b_result.begin(), b_result.end()));
} else {
return (std::vector<uint8_t>(b_result.begin(), &b_result[len]));
}
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
/// @brief Verify an existing signature
///
/// See @ref isc::cryptolink::HMAC::verify() for details.
bool verify(const void* sig, size_t len) {
/// @todo Botan's verify_mac checks if len matches the output_length,
/// which causes it to fail for truncated signatures, so we do
/// the check ourselves
/// SEE BELOW FOR TEMPORARY CHANGE
try {
Botan::SecureVector<Botan::byte> our_mac = hmac_->final();
if (len < getOutputLength()) {
// Currently we don't support truncated signature in TSIG (see
// #920). To avoid validating too short signature accidently,
// we enforce the standard signature size for the moment.
// Once we support truncation correctly, this if-clause should
// (and the capitalized comment above) be removed.
return (false);
}
if (len == 0 || len > getOutputLength()) {
len = getOutputLength();
}
return (Botan::same_mem(&our_mac[0],
static_cast<const unsigned char*>(sig),
len));
} catch (const Botan::Exception& exc) {
isc_throw(isc::cryptolink::LibraryError, exc.what());
}
}
private:
/// \brief The protected pointer to the Botan HMAC object
boost::scoped_ptr<Botan::HMAC> hmac_;
};
HMAC::HMAC(const void* secret, size_t secret_length,
const HashAlgorithm hash_algorithm)
{
impl_ = new HMACImpl(secret, secret_length, hash_algorithm);
}
HMAC::~HMAC() {
delete impl_;
}
size_t
HMAC::getOutputLength() const {
return (impl_->getOutputLength());
}
void
HMAC::update(const void* data, const size_t len) {
impl_->update(data, len);
}
void
HMAC::sign(isc::util::OutputBuffer& result, size_t len) {
impl_->sign(result, len);
}
void
HMAC::sign(void* result, size_t len) {
impl_->sign(result, len);
}
std::vector<uint8_t>
HMAC::sign(size_t len) {
return impl_->sign(len);
}
bool
HMAC::verify(const void* sig, const size_t len) {
return (impl_->verify(sig, len));
}
} // namespace cryptolink
} // namespace isc
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <cryptolink/cryptolink.h>
#include <cryptolink/crypto_hash.h>
#include <cryptolink/crypto_hmac.h>
#include <botan/botan.h>
namespace isc {
namespace cryptolink {
// For Botan, we use the CryptoLink class object in RAII style
class CryptoLinkImpl {
private:
Botan::LibraryInitializer botan_init_;
};
CryptoLink::~CryptoLink() {
delete impl_;
}
void
CryptoLink::initialize() {
CryptoLink& c = getCryptoLinkInternal();
if (c.impl_ == NULL) {
try {
c.impl_ = new CryptoLinkImpl();
} catch (const Botan::Exception& ex) {
isc_throw(InitializationError, ex.what());
}
}
}
} // namespace cryptolink
} // namespace isc
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//