From: Francis Dupont Date: Sat, 6 Jun 2015 13:40:43 +0000 (+0200) Subject: [sedhcpv6] rearrange asym crypto (checkpoint before splitting files) X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=ef46c7d89c24600f7fb22fcec90fec1822aea0ff;p=thirdparty%2Fkea.git [sedhcpv6] rearrange asym crypto (checkpoint before splitting files) --- diff --git a/src/lib/cryptolink/botan_asym.cc b/src/lib/cryptolink/botan_asym.cc index 9f785e8e55..fd09f667fa 100644 --- a/src/lib/cryptolink/botan_asym.cc +++ b/src/lib/cryptolink/botan_asym.cc @@ -46,7 +46,7 @@ namespace cryptolink { /// @brief Botan implementation of asymmetrical cryptography (Asym). // Each method is the counterpart of the Asym corresponding method. -class AsymImpl { +class RsaAsymImpl : public AsymImpl { public: /// @brief Constructor from a key, asym and hash algorithm, /// key kind and key binary format @@ -55,23 +55,16 @@ public: /// /// @param key The key to sign/verify with /// @param len The length of the key - /// @param asym_algorithm The asymmetrical cryptography algorithm /// @param hash_algorithm The hash algorithm /// @param key_kind The key kind /// @param key_format The key binary format - explicit AsymImpl(const void* key, size_t key_len, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymKeyKind key_kind, - const AsymFormat key_format) { - algo_ = asym_algorithm; + RsaAsymImpl(const void* key, size_t key_len, + const HashAlgorithm hash_algorithm, + const AsymKeyKind key_kind, + const AsymFormat key_format) { + algo_ = RSA_; hash_ = hash_algorithm; kind_ = key_kind; - if (algo_ != RSA_) { - isc_throw(UnsupportedAlgorithm, - "Unknown asym algorithm: " << - static_cast(algo_)); - } std::string hash = btn::getHashAlgorithmName(hash_); if (hash.compare("Unknown") == 0) { isc_throw(UnsupportedAlgorithm, @@ -296,24 +289,17 @@ public: /// /// @param filename The key file name/path /// @param password The PKCS#8 password - /// @param asym_algorithm The asymmetrical cryptography algorithm /// @param hash_algorithm The hash algorithm /// @param key_kind The key kind /// @param key_format The key binary format - explicit AsymImpl(const std::string& filename, - const std::string& password, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymKeyKind key_kind, - const AsymFormat key_format) { - algo_ = asym_algorithm; + RsaAsymImpl(const std::string& filename, + const std::string& password, + const HashAlgorithm hash_algorithm, + const AsymKeyKind key_kind, + const AsymFormat key_format) { + algo_ = RSA_; hash_ = hash_algorithm; kind_ = key_kind; - if (algo_ != RSA_) { - isc_throw(UnsupportedAlgorithm, - "Unknown asym algorithm: " << - static_cast(algo_)); - } std::string hash = btn::getHashAlgorithmName(hash_); if (hash.compare("Unknown") == 0) { isc_throw(UnsupportedAlgorithm, @@ -731,7 +717,7 @@ public: } /// @brief Destructor - ~AsymImpl() { } + ~RsaAsymImpl() { } /// @brief Returns the AsymAlgorithm of the object AsymAlgorithm getAsymAlgorithm() const { @@ -762,33 +748,26 @@ public: /// /// \param sig_format The signature binary format size_t getSignatureLength(const AsymFormat sig_format) const { - switch (algo_) { - case RSA_: - switch (sig_format) { - case BASIC: - case ASN1: - case DNS: - // In all cases a big integer of the size of n - if (kind_ == PRIVATE) { - return (priv_->get_n().bytes()); - } else { - return (pub_->get_n().bytes()); - } - default: - isc_throw(UnsupportedAlgorithm, - "Unknown RSA Signature format: " << - static_cast(sig_format)); + switch (sig_format) { + case BASIC: + case ASN1: + case DNS: + // In all cases a big integer of the size of n + if (kind_ == PRIVATE) { + return (priv_->get_n().bytes()); + } else { + return (pub_->get_n().bytes()); } default: isc_throw(UnsupportedAlgorithm, - "Unknown asym algorithm: " << - static_cast(algo_)); + "Unknown RSA Signature format: " << + static_cast(sig_format)); } } /// @brief Add data to digest /// - /// See @ref isc::cryptolink::Asym::update() for details. + /// See @ref isc::cryptolink::AsymBase::update() for details. void update(const void* data, const size_t len) { try { if (kind_ == PRIVATE) { @@ -805,7 +784,7 @@ public: /// @brief Calculate the final signature /// - /// See @ref isc::cryptolink::Asym::sign() for details. + /// See @ref isc::cryptolink::AsymBase::sign() for details. void sign(isc::util::OutputBuffer& result, size_t len, const AsymFormat) { try { @@ -823,7 +802,7 @@ public: /// @brief Calculate the final signature /// - /// See @ref isc::cryptolink::Asym::sign() for details. + /// See @ref isc::cryptolink::AsymBase::sign() for details. void sign(void* result, size_t len, const AsymFormat sig_format) { try { Botan::SecureVector b_result; @@ -841,7 +820,7 @@ public: /// @brief Calculate the final signature /// - /// See @ref isc::cryptolink::Asym::sign() for details. + /// See @ref isc::cryptolink::AsymBase::sign() for details. std::vector sign(size_t len, const AsymFormat) { try { Botan::SecureVector b_result; @@ -859,7 +838,7 @@ public: /// @brief Verify an existing signature /// - /// See @ref isc::cryptolink::Asym::verify() for details. + /// See @ref isc::cryptolink::AsymBase::verify() for details. bool verify(const void* sig, size_t len, const AsymFormat sig_format) { size_t size = getSignatureLength(sig_format); if (len != size) { @@ -900,7 +879,7 @@ public: /// @brief Export the key value (binary) /// - /// See @ref isc::cryptolink::Asym::exportkey() for details + /// See @ref isc::cryptolink::AsymBase::exportkey() for details std::vector exportkey(const AsymKeyKind key_kind, const AsymFormat key_format) const { if ((key_kind == PRIVATE) && (key_format == BASIC)) { @@ -987,7 +966,7 @@ public: /// @brief Export the key value (file) /// - /// See @ref isc::cryptolink::Asym::exportkey() for details + /// See @ref isc::cryptolink::AsymBase::exportkey() for details void exportkey(const std::string& filename, const std::string& password, const AsymKeyKind key_kind, @@ -1140,7 +1119,7 @@ public: /// @brief Check the validity /// - /// See @ref isc::cryptolink::Asym::validate() for details + /// See @ref isc::cryptolink::AsymBase::validate() for details bool validate() const { Botan::AutoSeeded_RNG rng; Botan::X509_Store store; @@ -1174,7 +1153,10 @@ public: /// @brief Compare two keys /// /// See @ref isc::cryptolink::Asym::compare() for details - bool compare(const AsymImpl* other, const AsymKeyKind key_kind) const { + bool compare(const RsaAsymImpl* other, const AsymKeyKind key_kind) const { + if (!other || (other->algo_ != RSA_)) { + return false; + } Botan::BigInt e, n; switch (key_kind) { case CERT: @@ -1244,9 +1226,16 @@ Asym::Asym(const void* key, size_t key_len, const AsymKeyKind key_kind, const AsymFormat key_format) { - impl_ = new AsymImpl(key, key_len, - asym_algorithm, hash_algorithm, - key_kind, key_format); + switch (asym_algorithm) { + case RSA_: + impl_ = new RsaAsymImpl(key, key_len, hash_algorithm, + key_kind, key_format); + return; + default: + isc_throw(UnsupportedAlgorithm, + "Unknown asym algorithm: " << + static_cast(asym_algorithm)); + } } Asym::Asym(const std::vector key, @@ -1255,9 +1244,16 @@ Asym::Asym(const std::vector key, const AsymKeyKind key_kind, const AsymFormat key_format) { - impl_ = new AsymImpl(&key[0], key.size(), - asym_algorithm, hash_algorithm, - key_kind, key_format); + switch (asym_algorithm) { + case RSA_: + impl_ = new RsaAsymImpl(&key[0], key.size(), hash_algorithm, + key_kind, key_format); + return; + default: + isc_throw(UnsupportedAlgorithm, + "Unknown asym algorithm: " << + static_cast(asym_algorithm)); + } } Asym::Asym(const std::string& filename, @@ -1267,9 +1263,16 @@ Asym::Asym(const std::string& filename, const AsymKeyKind key_kind, const AsymFormat key_format) { - impl_ = new AsymImpl(filename, password, - asym_algorithm, hash_algorithm, - key_kind, key_format); + switch (asym_algorithm) { + case RSA_: + impl_ = new RsaAsymImpl(filename, password, hash_algorithm, + key_kind, key_format); + return; + default: + isc_throw(UnsupportedAlgorithm, + "Unknown asym algorithm: " << + static_cast(asym_algorithm)); + } } Asym::~Asym() { @@ -1356,7 +1359,7 @@ Asym::validate() const { // Call the hook if available using namespace isc::hooks; if (HooksManager::calloutsPresent(hook_point_validate_certificate)) { - // Callout handle (static in order to reuse it) + // Callout handle CalloutHandlePtr callout_handle_ = HooksManager::createCalloutHandle(); // Delete add previous arguments @@ -1380,7 +1383,20 @@ Asym::validate() const { bool Asym::compare(const Asym* other, const AsymKeyKind key_kind) const { - return (impl_->compare(other->impl_, key_kind)); + if (getAsymAlgorithm() != other->getAsymAlgorithm()) { + return false; + } + if (getAsymAlgorithm() == RSA_) { + const RsaAsymImpl* impl = dynamic_cast(impl_); + // Should not happen but to test is better than to crash + if (!impl) { + isc_throw(Unexpected, "dynamic_cast failed on RsaAsymImpl*"); + } + const RsaAsymImpl* oimpl = + dynamic_cast(other->impl_); + return (impl->compare(oimpl, key_kind)); + } + isc_throw(UnsupportedAlgorithm, "compare"); } } // namespace cryptolink diff --git a/src/lib/cryptolink/crypto_asym.h b/src/lib/cryptolink/crypto_asym.h index 2b1ab050cc..8b92aaa15a 100644 --- a/src/lib/cryptolink/crypto_asym.h +++ b/src/lib/cryptolink/crypto_asym.h @@ -24,19 +24,168 @@ namespace isc { namespace cryptolink { -/// Forward declaration, pimpl style -class AsymImpl; +/// \brief Asymmetrical cryptography (Asym) support + +/// \brief Asymmetrical cryptography (Asym) base class +/// +/// This class is an abstract base class to give the interface +/// (at the exception of constructors which can't be virtual and +/// compare which needs a second object). +class AsymBase : private boost::noncopyable { +protected: + AsymBase() { } + +public: + /// \brief Destructor + virtual ~AsymBase() {} + + /// \brief Returns the AsymAlgorithm of the object + virtual AsymAlgorithm getAsymAlgorithm() const = 0; + + /// \brief Returns the HashAlgorithm of the object + virtual HashAlgorithm getHashAlgorithm() const = 0; + + /// \brief Returns the AsymKeyKind of the object + virtual AsymKeyKind getAsymKeyKind() const = 0; + + /// \brief Returns the key size in bits + /// + virtual size_t getKeySize() const = 0; + + /// \brief Returns the output size of the signature + /// + /// \param sig_format The signature binary format + virtual size_t getSignatureLength(const AsymFormat sig_format) const = 0; + + /// \brief Add data to digest + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// \param data The data to add + /// \param len The size of the data + virtual void update(const void* data, const size_t len) = 0; + + /// \brief Calculate the final signature + /// + /// The result will be appended to the given outputbuffer + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// \param result The OutputBuffer to append the result to + /// \param len The number of bytes from the result to copy. If this + /// value is smaller than the algorithms output size, the + /// result will be truncated. If this value is larger, + /// only output size bytes will be copied + /// \param sig_format The signature binary format + virtual void sign(isc::util::OutputBuffer& result, size_t len, + const AsymFormat sig_format) = 0; + + /// \brief Calculate the final signature + /// + /// len bytes of data from the result will be copied to *result + /// If len is larger than the output size, only output_size bytes + /// will be copied. If it is smaller, the output will be truncated + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// At least len bytes of data must be available for writing at + /// result + virtual void sign(void* result, size_t len, + const AsymFormat sig_format) = 0; + + /// \brief Calculate the final signature + /// + /// The result will be returned as a std::vector + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// \param len The number of bytes from the result to copy. If this + /// value is smaller than the algorithms output size, the + /// result will be truncated. If this value is larger, + /// only output size bytes will be copied + /// \param sig_format The signature binary format + /// \return a vector containing the signature + virtual std::vector sign(size_t len, + const AsymFormat sig_format) = 0; + + /// \brief Verify an existing signature + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// \param sig The signature to verify + /// \param len The length of the signature. If this is smaller + /// than the output length of the algorithm, + /// only len bytes will be checked + /// \param sig_format The signature binary format + /// \return true if the signature is correct, false otherwise + /// + /// \note verify() does not destroy its context so it can be + /// called multiple times with different signatures. + virtual bool verify(const void* sig, size_t len, + const AsymFormat sig_format) = 0; + + /// \brief Clear the crypto state and go back to the initial state + /// (must be called before reusing an Asym object) + virtual void clear() = 0; + + /// \brief Export the key value + /// + /// The result will be returned as a std::vector + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// \param key_kind The key kind + /// \param key_format The key binary format + virtual std::vector + exportkey(const AsymKeyKind key_kind, + const AsymFormat key_format) const = 0; + + /// \brief Export the key value + /// + /// The key value will be returned into the given file, + /// optionally when PKCS#8 is selected encrypted by the password + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + /// \param filename The key file name/path + /// \param password The PKCS#8 password + /// \param key_kind The key kind + /// \param file_format The key file format + virtual void exportkey(const std::string& filename, + const std::string& password, + const AsymKeyKind key_kind, + const AsymFormat file_format) const = 0; + + /// \brief Check the validity + /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// + virtual bool validate() const = 0; +}; + +/// Implementation (abstract) class declaration, pimpl style +class AsymImpl : public AsymBase {}; /// \brief Asymmetrical cryptography (Asym) support /// /// This class is used to create and verify Asym signatures. Instances /// can be created with CryptoLink::createAsym() /// -class Asym : private boost::noncopyable { +/// Constructors, destructor and all methods are inherited from +/// the \c AsymBase class. +class Asym : public AsymBase { private: /// \brief Constructor from a key, asym and hash algorithm, /// key kind and key binary format - /// + /// \ref AsymBase::AsymBase /// \exception UnsupportedAlgorithm if the given algorithm /// is unknown or not supported by the underlying library /// \exception Badkey if the given key length is bad @@ -99,7 +248,7 @@ private: public: /// \brief Destructor - ~Asym(); + virtual ~Asym(); /// \brief Returns the AsymAlgorithm of the object AsymAlgorithm getAsymAlgorithm() const; @@ -121,101 +270,45 @@ public: /// \brief Add data to digest /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library - /// - /// \param data The data to add - /// \param len The size of the data + /// \ref isc::cryptolink::AsymBase::update void update(const void* data, const size_t len); /// \brief Calculate the final signature /// - /// The result will be appended to the given outputbuffer - /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library - /// - /// \param result The OutputBuffer to append the result to - /// \param len The number of bytes from the result to copy. If this - /// value is smaller than the algorithms output size, the - /// result will be truncated. If this value is larger, - /// only output size bytes will be copied - /// \param sig_format The signature binary format + /// \ref isc::cryptolink::AsymBase::sign void sign(isc::util::OutputBuffer& result, size_t len, const AsymFormat sig_format); /// \brief Calculate the final signature /// - /// len bytes of data from the result will be copied to *result - /// If len is larger than the output size, only output_size bytes - /// will be copied. If it is smaller, the output will be truncated - /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library - /// - /// At least len bytes of data must be available for writing at - /// result + /// \ref isc::cryptolink::AsymBase::sign void sign(void* result, size_t len, const AsymFormat sig_format); - /// \brief Calculate the final signatre - /// - /// The result will be returned as a std::vector - /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library + /// \brief Calculate the final signature /// - /// \param len The number of bytes from the result to copy. If this - /// value is smaller than the algorithms output size, the - /// result will be truncated. If this value is larger, - /// only output size bytes will be copied - /// \param sig_format The signature binary format - /// \return a vector containing the signature + /// \ref isc::cryptolink::AsymBase::sign std::vector sign(size_t len, const AsymFormat sig_format); /// \brief Verify an existing signature /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library - /// - /// \param sig The signature to verify - /// \param len The length of the signature. If this is smaller - /// than the output length of the algorithm, - /// only len bytes will be checked - /// \param sig_format The signature binary format - /// \return true if the signature is correct, false otherwise - /// - /// \note verify() does not destroy its context so it can be - /// called multiple times with different signatures. + /// \ref isc::cryptolink::AsymBase::verify bool verify(const void* sig, size_t len, const AsymFormat sig_format); /// \brief Clear the crypto state and go back to the initial state /// (must be called before reusing an Asym object) + /// + /// \ref isc::cryptolink::AsymBase::clear void clear(); /// \brief Export the key value /// - /// The result will be returned as a std::vector - /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library - /// - /// \param key_kind The key kind - /// \param key_format The key binary format + /// \ref isc::cryptolink::AsymBase::exportkey std::vector exportkey(const AsymKeyKind key_kind, const AsymFormat key_format) const; /// \brief Export the key value /// - /// The key value will be returned into the given file, - /// optionally when PKCS#8 is selected encrypted by the password - /// - /// \exception LibraryError if there was any unexpected exception - /// in the underlying library - /// - /// \param filename The key file name/path - /// \param password The PKCS#8 password - /// \param key_kind The key kind - /// \param file_format The key file format + /// \ref isc::cryptolink::AsymBase::exportkey void exportkey(const std::string& filename, const std::string& password, const AsymKeyKind key_kind, @@ -223,6 +316,8 @@ public: /// \brief Check the validity /// + /// \ref isc::cryptolink::AsymBase::validate + /// /// \exception LibraryError if there was any unexpected exception /// in the underlying library /// diff --git a/src/lib/cryptolink/crypto_hmac.h b/src/lib/cryptolink/crypto_hmac.h index 040e573182..22f68c804b 100644 --- a/src/lib/cryptolink/crypto_hmac.h +++ b/src/lib/cryptolink/crypto_hmac.h @@ -104,7 +104,7 @@ public: /// result void sign(void* result, size_t len); - /// \brief Calculate the final signatre + /// \brief Calculate the final signature /// /// The result will be returned as a std::vector /// diff --git a/src/lib/cryptolink/openssl_asym.cc b/src/lib/cryptolink/openssl_asym.cc index 644a71ff6c..d2e0ccb341 100644 --- a/src/lib/cryptolink/openssl_asym.cc +++ b/src/lib/cryptolink/openssl_asym.cc @@ -43,7 +43,7 @@ namespace cryptolink { /// @brief OpenSSL implementation of asymmetrical cryptography (Asym). // Each method is the counterpart of the Asym corresponding method. -class AsymImpl { +class RsaAsymImpl : public AsymImpl { public: /// @brief Constructor from a key, asym and hash algorithm, /// key kind and key binary format @@ -52,25 +52,18 @@ public: /// /// @param key The key to sign/verify with /// @param len The length of the key - /// @param asym_algorithm The asymmetrical cryptography algorithm /// @param hash_algorithm The hash algorithm /// @param key_kind The key kind /// @param key_format The key binary format - explicit AsymImpl(const void* key, size_t key_len, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymKeyKind key_kind, - const AsymFormat key_format) { - algo_ = asym_algorithm; + RsaAsymImpl(const void* key, size_t key_len, + const HashAlgorithm hash_algorithm, + const AsymKeyKind key_kind, + const AsymFormat key_format) { + algo_ = RSA_; hash_ = hash_algorithm; kind_ = key_kind; pkey_ = NULL; x509_ = NULL; - if (algo_ != RSA_) { - isc_throw(UnsupportedAlgorithm, - "Unknown asym algorithm: " << - static_cast(algo_)); - } const EVP_MD* md = ossl::getHashAlgorithm(hash_); if (md == 0) { isc_throw(UnsupportedAlgorithm, @@ -301,26 +294,19 @@ public: /// /// @param filename The key file name/path /// @param password The PKCS#8 password - /// @param asym_algorithm The asymmetrical cryptography algorithm /// @param hash_algorithm The hash algorithm /// @param key_kind The key kind /// @param key_format The key binary format - explicit AsymImpl(const std::string& filename, - const std::string& password, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymKeyKind key_kind, - const AsymFormat key_format) { - algo_ = asym_algorithm; + RsaAsymImpl(const std::string& filename, + const std::string& password, + const HashAlgorithm hash_algorithm, + const AsymKeyKind key_kind, + const AsymFormat key_format) { + algo_ = RSA_; hash_ = hash_algorithm; kind_ = key_kind; pkey_ = NULL; x509_ = NULL; - if (algo_ != RSA_) { - isc_throw(UnsupportedAlgorithm, - "Unknown asym algorithm: " << - static_cast(algo_)); - } const EVP_MD* md = ossl::getHashAlgorithm(hash_); if (md == 0) { isc_throw(UnsupportedAlgorithm, @@ -853,7 +839,7 @@ public: } /// @brief Destructor - ~AsymImpl() { + virtual ~RsaAsymImpl() { if (mdctx_) { EVP_MD_CTX_cleanup(mdctx_.get()); } @@ -892,29 +878,22 @@ public: /// /// \param sig_format The signature binary format size_t getSignatureLength(const AsymFormat sig_format) const { - switch (algo_) { - case RSA_: - switch (sig_format) { - case BASIC: - case ASN1: - case DNS: - // In all cases a big integer of the size of n - return (static_cast(EVP_PKEY_size(pkey_))); - default: - isc_throw(UnsupportedAlgorithm, - "Unknown RSA Signature format: " << - static_cast(sig_format)); - } + switch (sig_format) { + case BASIC: + case ASN1: + case DNS: + // In all cases a big integer of the size of n + return (static_cast(EVP_PKEY_size(pkey_))); default: isc_throw(UnsupportedAlgorithm, - "Unknown asym algorithm: " << - static_cast(algo_)); + "Unknown RSA Signature format: " << + static_cast(sig_format)); } } /// @brief Add data to digest /// - /// See @ref isc::cryptolink::Asym::update() for details. + /// See @ref isc::cryptolink::AsymBase::update() for details. void update(const void* data, const size_t len) { if (!EVP_DigestUpdate(mdctx_.get(), data, len)) { isc_throw(LibraryError, "EVP_DigestUpdate"); @@ -923,7 +902,7 @@ public: /// @brief Calculate the final signature /// - /// See @ref isc::cryptolink::Asym::sign() for details. + /// See @ref isc::cryptolink::AsymBase::sign() for details. void sign(isc::util::OutputBuffer& result, size_t len, const AsymFormat sig_format) { unsigned int size = getSignatureLength(sig_format); @@ -939,7 +918,7 @@ public: /// @brief Calculate the final signature /// - /// See @ref isc::cryptolink::Asym::sign() for details. + /// See @ref isc::cryptolink::AsymBase::sign() for details. void sign(void* result, size_t len, const AsymFormat sig_format) { unsigned int size = getSignatureLength(sig_format); ossl::SecBuf sig(size); @@ -954,7 +933,7 @@ public: /// @brief Calculate the final signature /// - /// See @ref isc::cryptolink::Asym::sign() for details. + /// See @ref isc::cryptolink::AsymBase::sign() for details. std::vector sign(size_t len, const AsymFormat sig_format) { unsigned int size = getSignatureLength(sig_format); ossl::SecBuf sig(size); @@ -968,7 +947,7 @@ public: /// @brief Verify an existing signature /// - /// See @ref isc::cryptolink::Asym::verify() for details. + /// See @ref isc::cryptolink::AsymBase::verify() for details. bool verify(const void* sig, size_t len, const AsymFormat sig_format) { size_t size = getSignatureLength(sig_format); if (len != size) { @@ -1014,7 +993,7 @@ public: /// @brief Export the key value (binary) /// - /// See @ref isc::cryptolink::Asym::exportkey() for details + /// See @ref isc::cryptolink::AsymBase::exportkey() for details std::vector exportkey(const AsymKeyKind key_kind, const AsymFormat key_format) const { if ((key_kind == PRIVATE) && (key_format == BASIC)) { @@ -1138,7 +1117,7 @@ public: /// @brief Export the key value (file) /// - /// See @ref isc::cryptolink::Asym::exportkey() for details + /// See @ref isc::cryptolink::AsymBase::exportkey() for details void exportkey(const std::string& filename, const std::string& password, const AsymKeyKind key_kind, @@ -1317,7 +1296,7 @@ public: /// @brief Check the validity /// - /// See @ref isc::cryptolink::Asym::validate() for details + /// See @ref isc::cryptolink::AsymBase::validate() for details bool validate() const { RSA* rsa; X509_STORE* store; @@ -1379,7 +1358,10 @@ public: /// @brief Compare two keys /// /// See @ref isc::cryptolink::Asym::compare() for details - bool compare(const AsymImpl* other, const AsymKeyKind key_kind) const { + bool compare(const RsaAsymImpl* other, const AsymKeyKind key_kind) const { + if (!other || (other->algo_ != RSA_)) { + return false; + } int status; switch (key_kind) { case CERT: @@ -1471,9 +1453,16 @@ Asym::Asym(const void* key, size_t key_len, const AsymKeyKind key_kind, const AsymFormat key_format) { - impl_ = new AsymImpl(key, key_len, - asym_algorithm, hash_algorithm, - key_kind, key_format); + switch (asym_algorithm) { + case RSA_: + impl_ = new RsaAsymImpl(key, key_len, hash_algorithm, + key_kind, key_format); + return; + default: + isc_throw(UnsupportedAlgorithm, + "Unknown asym algorithm: " << + static_cast(asym_algorithm)); + } } Asym::Asym(const std::vector key, @@ -1482,9 +1471,16 @@ Asym::Asym(const std::vector key, const AsymKeyKind key_kind, const AsymFormat key_format) { - impl_ = new AsymImpl(&key[0], key.size(), - asym_algorithm, hash_algorithm, - key_kind, key_format); + switch (asym_algorithm) { + case RSA_: + impl_ = new RsaAsymImpl(&key[0], key.size(), hash_algorithm, + key_kind, key_format); + return; + default: + isc_throw(UnsupportedAlgorithm, + "Unknown asym algorithm: " << + static_cast(asym_algorithm)); + } } Asym::Asym(const std::string& filename, @@ -1494,9 +1490,16 @@ Asym::Asym(const std::string& filename, const AsymKeyKind key_kind, const AsymFormat key_format) { - impl_ = new AsymImpl(filename, password, - asym_algorithm, hash_algorithm, - key_kind, key_format); + switch (asym_algorithm) { + case RSA_: + impl_ = new RsaAsymImpl(filename, password, hash_algorithm, + key_kind, key_format); + return; + default: + isc_throw(UnsupportedAlgorithm, + "Unknown asym algorithm: " << + static_cast(asym_algorithm)); + } } Asym::~Asym() { @@ -1607,7 +1610,20 @@ Asym::validate() const { bool Asym::compare(const Asym* other, const AsymKeyKind key_kind) const { - return (impl_->compare(other->impl_, key_kind)); + if (getAsymAlgorithm() != other->getAsymAlgorithm()) { + return false; + } + if (getAsymAlgorithm() == RSA_) { + const RsaAsymImpl* impl = dynamic_cast(impl_); + // Should not happen but to test is better than to crash + if (!impl) { + isc_throw(Unexpected, "dynamic_cast failed on RsaAsymImpl*"); + } + const RsaAsymImpl* oimpl = + dynamic_cast(other->impl_); + return (impl->compare(oimpl, key_kind)); + } + isc_throw(UnsupportedAlgorithm, "compare"); } } // namespace cryptolink diff --git a/src/lib/cryptolink/tests/asym_unittests.cc b/src/lib/cryptolink/tests/asym_unittests.cc index ee6fb17a2f..6db19ed700 100644 --- a/src/lib/cryptolink/tests/asym_unittests.cc +++ b/src/lib/cryptolink/tests/asym_unittests.cc @@ -931,14 +931,14 @@ TEST(AsymTest, callout) { // Install validate_certificate_callout LibraryHandle& preCLH = HooksManager::preCalloutsLibraryHandle(); EXPECT_NO_THROW(preCLH.registerCallout("validate_certificate", - validate_certificate_callout)); + validate_certificate_callout)); // Get a certificate and validate it CryptoLink& crypto = CryptoLink::getCryptoLink(); boost::shared_ptr cert(crypto.createAsym(certfile, "", - RSA_, SHA1, - CERT, ASN1), - deleteAsym); + RSA_, SHA1, + CERT, ASN1), + deleteAsym); EXPECT_TRUE(cert->validate()); // Check that callouts were indeed called