From: Francis Dupont Date: Sun, 7 Jun 2015 16:40:39 +0000 (+0200) Subject: [sedhcpv6] fixed OpenSSL ECDSA, still Botan ECDSA to do X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=b84bb8dc0f4558e65b1a73ebcd6482a8f7f4026c;p=thirdparty%2Fkea.git [sedhcpv6] fixed OpenSSL ECDSA, still Botan ECDSA to do --- diff --git a/src/lib/cryptolink/Makefile.am b/src/lib/cryptolink/Makefile.am index 980c1157d7..30dd02ef02 100644 --- a/src/lib/cryptolink/Makefile.am +++ b/src/lib/cryptolink/Makefile.am @@ -19,6 +19,7 @@ libkea_cryptolink_la_SOURCES += botan_hash.cc libkea_cryptolink_la_SOURCES += botan_hmac.cc libkea_cryptolink_la_SOURCES += botan_asym.cc libkea_cryptolink_la_SOURCES += botan_rsa.h botan_rsa.cc +libkea_cryptolink_la_SOURCES += botan_ecdsa.h botan_ecdsa.cc endif if HAVE_OPENSSL libkea_cryptolink_la_SOURCES += openssl_link.cc @@ -27,6 +28,7 @@ libkea_cryptolink_la_SOURCES += openssl_hash.cc libkea_cryptolink_la_SOURCES += openssl_hmac.cc libkea_cryptolink_la_SOURCES += openssl_asym.cc libkea_cryptolink_la_SOURCES += openssl_rsa.h openssl_rsa.cc +libkea_cryptolink_la_SOURCES += openssl_ecdsa.h openssl_ecdsa.cc endif libkea_cryptolink_la_LDFLAGS = ${CRYPTO_LDFLAGS} diff --git a/src/lib/cryptolink/botan_rsa.h b/src/lib/cryptolink/botan_rsa.h index 6329946fe0..3c6db360af 100644 --- a/src/lib/cryptolink/botan_rsa.h +++ b/src/lib/cryptolink/botan_rsa.h @@ -17,6 +17,7 @@ namespace cryptolink { /// @brief Botan implementation of asymmetrical cryptography (Asym). // Each method is the counterpart of the Asym corresponding method. +// RSA class RsaAsymImpl : public AsymImpl { public: /// @brief Constructor from a key, asym and hash algorithm, diff --git a/src/lib/cryptolink/openssl_asym.cc b/src/lib/cryptolink/openssl_asym.cc index 1907fd5dc8..014b6bd036 100644 --- a/src/lib/cryptolink/openssl_asym.cc +++ b/src/lib/cryptolink/openssl_asym.cc @@ -16,11 +16,13 @@ #include #include +#include #include #include #include #include +#include namespace { @@ -44,6 +46,10 @@ Asym::Asym(const void* key, size_t key_len, impl_ = new RsaAsymImpl(key, key_len, hash_algorithm, key_kind, key_format); return; + case ECDSA_: + impl_ = new EcDsaAsymImpl(key, key_len, hash_algorithm, + key_kind, key_format); + return; default: isc_throw(UnsupportedAlgorithm, "Unknown asym algorithm: " << @@ -62,6 +68,10 @@ Asym::Asym(const std::vector key, impl_ = new RsaAsymImpl(&key[0], key.size(), hash_algorithm, key_kind, key_format); return; + case ECDSA_: + impl_ = new EcDsaAsymImpl(&key[0], key.size(), hash_algorithm, + key_kind, key_format); + return; default: isc_throw(UnsupportedAlgorithm, "Unknown asym algorithm: " << @@ -81,6 +91,10 @@ Asym::Asym(const std::string& filename, impl_ = new RsaAsymImpl(filename, password, hash_algorithm, key_kind, key_format); return; + case ECDSA_: + impl_ = new EcDsaAsymImpl(filename, password, hash_algorithm, + key_kind, key_format); + return; default: isc_throw(UnsupportedAlgorithm, "Unknown asym algorithm: " << @@ -208,7 +222,17 @@ Asym::compare(const Asym* other, const AsymKeyKind key_kind) const { const RsaAsymImpl* oimpl = dynamic_cast(other->impl_); return (impl->compare(oimpl, key_kind)); + } else if (getAsymAlgorithm() == ECDSA_) { + const EcDsaAsymImpl* impl = dynamic_cast(impl_); + // Should not happen but to test is better than to crash + if (!impl) { + isc_throw(Unexpected, "dynamic_cast failed on EcDsaAsymImpl*"); + } + const EcDsaAsymImpl* oimpl = + dynamic_cast(other->impl_); + return (impl->compare(oimpl, key_kind)); } + isc_throw(UnsupportedAlgorithm, "compare"); } diff --git a/src/lib/cryptolink/openssl_common.h b/src/lib/cryptolink/openssl_common.h index 0652037247..fb19c9f2d6 100644 --- a/src/lib/cryptolink/openssl_common.h +++ b/src/lib/cryptolink/openssl_common.h @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014, 2015 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 @@ -78,6 +78,11 @@ public: vec_.resize(sz); }; + void clear() { + std::memset(&vec_[0], 0, vec_.capacity() * sizeof(T)); + vec_.clear(); + } + SecBuf& operator=(const SecBuf& x) { if (&x != *this) { vec_ = x.vec_; diff --git a/src/lib/cryptolink/openssl_ecdsa.cc b/src/lib/cryptolink/openssl_ecdsa.cc index 2e43febdac..f1db80e3c6 100644 --- a/src/lib/cryptolink/openssl_ecdsa.cc +++ b/src/lib/cryptolink/openssl_ecdsa.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,38 @@ #error "P-384 group is not known (NID_secp384r1)" #endif +namespace { + +/// @brief Class for the curves/groups +class EcDsaGroup { +public: + // @brief Constructor + // Get the group and set the curve name flag for ASN.1 + EcDsaGroup(int nid) { + group_ = EC_GROUP_new_by_curve_name(nid); + if (!group_) { + isc_throw(isc::Unexpected, "EC_GROUP_new_by_curve_name"); + } + EC_GROUP_set_asn1_flag(group_, OPENSSL_EC_NAMED_CURVE); + } + + // @brief Destructor + ~EcDsaGroup() { + if (group_) { + EC_GROUP_free(group_); + group_ = NULL; + } + } + + // @brief The group + EC_GROUP* group_; +}; + +const EcDsaGroup prime256v1(NID_X9_62_prime256v1); +const EcDsaGroup secp384r1(NID_secp384r1); + +} // anonymous namespace + namespace isc { namespace cryptolink { @@ -51,13 +84,14 @@ EcDsaAsymImpl::EcDsaAsymImpl(const void* key, size_t key_len, kind_ = key_kind; eckey_ = NULL; x509_ = NULL; - int curve_nid = 0; switch (hash_) { case SHA256: - curve_nid = NID_X9_62_prime256v1; + md_ = EVP_sha256(); + group_ = prime256v1.group_; break; case SHA384: - curve_nid = NID_secp384r1; + md_ = EVP_sha512(); + group_ = secp384r1.group_; break; default: isc_throw(UnsupportedAlgorithm, @@ -75,12 +109,17 @@ EcDsaAsymImpl::EcDsaAsymImpl(const void* key, size_t key_len, if (!privkey) { throw std::bad_alloc(); } - eckey_ = EC_KEY_new_by_curve_name(curve_nid); + eckey_ = EC_KEY_new(); if (!eckey_) { BN_clear_free(privkey); - isc_throw(LibraryError, "EC_KEY_new_by_curve_name"); + isc_throw(LibraryError, "EC_KEY_new"); + } + if (!EC_KEY_set_group(eckey_, group_)) { + BN_clear_free(privkey); + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EC_KEY_set_group"); } - EC_KEY_set_asn1_flag(eckey_, OPENSSL_EC_NAMED_CURVE); if (!EC_KEY_set_private_key(eckey_, privkey)) { BN_clear_free(privkey); EC_KEY_free(eckey_); @@ -88,13 +127,12 @@ EcDsaAsymImpl::EcDsaAsymImpl(const void* key, size_t key_len, isc_throw(LibraryError, "EC_KEY_set_private_key"); } // Compute the public key - const EC_GROUP* grp = EC_KEY_get0_group(eckey_); - EC_POINT* pubkey = EC_POINT_new(grp); + EC_POINT* pubkey = EC_POINT_new(group_); if (!pubkey) { BN_clear_free(privkey); throw std::bad_alloc(); } - if (!EC_POINT_mul(grp, pubkey, privkey, NULL, NULL, NULL)) { + if (!EC_POINT_mul(group_, pubkey, privkey, NULL, NULL, NULL)) { EC_POINT_free(pubkey); BN_clear_free(privkey); EC_KEY_free(eckey_); @@ -126,15 +164,8 @@ EcDsaAsymImpl::EcDsaAsymImpl(const void* key, size_t key_len, eckey_ = NULL; isc_throw(BadKey, "EC_KEY_check_key"); } - EC_GROUP* wanted = EC_GROUP_new_by_curve_name(curve_nid); - if (!wanted) { - EC_KEY_free(eckey_); - eckey_ = NULL; - isc_throw(LibraryError, "EC_GROUP_new_by_curve_name"); - } const int status = - EC_GROUP_cmp(EC_KEY_get0_group(eckey_), wanted, NULL); - EC_GROUP_free(wanted); + EC_GROUP_cmp(EC_KEY_get0_group(eckey_), group_, NULL); if (status < 0) { EC_KEY_free(eckey_); eckey_ = NULL; @@ -165,11 +196,15 @@ EcDsaAsymImpl::EcDsaAsymImpl(const void* key, size_t key_len, pubbin[0] = POINT_CONVERSION_UNCOMPRESSED; std::memcpy(&pubbin[1], key, len); const uint8_t* p = &pubbin[0]; - eckey_ = EC_KEY_new_by_curve_name(curve_nid); + eckey_ = EC_KEY_new(); if (!eckey_) { - isc_throw(LibraryError, "EC_KEY_new_by_curve_name"); + isc_throw(LibraryError, "EC_KEY_new"); + } + if (!EC_KEY_set_group(eckey_, group_)) { + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EC_KEY_set_group"); } - EC_KEY_set_asn1_flag(eckey_, OPENSSL_EC_NAMED_CURVE); if (o2i_ECPublicKey(&eckey_, &p, static_cast(len + 1)) == NULL) { EC_KEY_free(eckey_); @@ -227,6 +262,16 @@ EcDsaAsymImpl::EcDsaAsymImpl(const void* key, size_t key_len, isc_throw(UnsupportedAlgorithm, "Unknown ECDSA Key kind: " << static_cast(kind_)); } + + mdctx_.reset(new EVP_MD_CTX); + EVP_MD_CTX_init(mdctx_.get()); + + if (!EVP_DigestInit_ex(mdctx_.get(), md_, NULL)) { + EVP_MD_CTX_cleanup(mdctx_.get()); + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EVP_DigestInit_ex"); + } } /// @brief Constructor from a key file with password, @@ -241,13 +286,14 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, kind_ = key_kind; eckey_ = NULL; x509_ = NULL; - int curve_nid = 0; switch (hash_) { case SHA256: - curve_nid = NID_X9_62_prime256v1; + md_ = EVP_sha256(); + group_ = prime256v1.group_; break; case SHA384: - curve_nid = NID_secp384r1; + md_ = EVP_sha512(); + group_ = secp384r1.group_; break; default: isc_throw(UnsupportedAlgorithm, @@ -271,13 +317,12 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, } if (!EC_KEY_get0_public_key(eckey_)) { // Compute the public key as a side effect - const EC_GROUP* grp = EC_KEY_get0_group(eckey_); const BIGNUM* privkey = EC_KEY_get0_private_key(eckey_); - EC_POINT* pubkey = EC_POINT_new(grp); + EC_POINT* pubkey = EC_POINT_new(group_); if (!pubkey) { throw std::bad_alloc(); } - if (!EC_POINT_mul(grp, pubkey, privkey, NULL, NULL, NULL)) { + if (!EC_POINT_mul(group_, pubkey, privkey, NULL, NULL, NULL)) { EC_POINT_free(pubkey); EC_KEY_free(eckey_); eckey_ = NULL; @@ -296,15 +341,8 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, eckey_ = NULL; isc_throw(BadKey, "EC_KEY_check_key"); } - EC_GROUP* wanted = EC_GROUP_new_by_curve_name(curve_nid); - if (!wanted) { - EC_KEY_free(eckey_); - eckey_ = NULL; - isc_throw(LibraryError, "EC_GROUP_new_by_curve_name"); - } const int status = - EC_GROUP_cmp(EC_KEY_get0_group(eckey_), wanted, NULL); - EC_GROUP_free(wanted); + EC_GROUP_cmp(EC_KEY_get0_group(eckey_), group_, NULL); if (status < 0) { EC_KEY_free(eckey_); eckey_ = NULL; @@ -378,12 +416,17 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, BN_clear_free(privkey); isc_throw(BadKey, "Missing Algorithm entry"); } - eckey_ = EC_KEY_new_by_curve_name(curve_nid); + eckey_ = EC_KEY_new(); if (!eckey_) { BN_clear_free(privkey); - isc_throw(LibraryError, "EC_KEY_new_by_curve_name"); + isc_throw(LibraryError, "EC_KEY_new"); + } + if (!EC_KEY_set_group(eckey_, group_)) { + BN_clear_free(privkey); + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EC_KEY_set_group"); } - EC_KEY_set_asn1_flag(eckey_, OPENSSL_EC_NAMED_CURVE); if (!EC_KEY_set_private_key(eckey_, privkey)) { BN_clear_free(privkey); EC_KEY_free(eckey_); @@ -418,15 +461,8 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, eckey_ = NULL; isc_throw(BadKey, "EC_KEY_check_key"); } - EC_GROUP* wanted = EC_GROUP_new_by_curve_name(curve_nid); - if (!wanted) { - EC_KEY_free(eckey_); - eckey_ = NULL; - isc_throw(LibraryError, "EC_GROUP_new_by_curve_name"); - } const int status = - EC_GROUP_cmp(EC_KEY_get0_group(eckey_), wanted, NULL); - EC_GROUP_free(wanted); + EC_GROUP_cmp(EC_KEY_get0_group(eckey_), group_, NULL); if (status < 0) { EC_KEY_free(eckey_); eckey_ = NULL; @@ -492,11 +528,15 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, } bin.insert(bin.begin(), POINT_CONVERSION_UNCOMPRESSED); const uint8_t* p = &bin[0]; - eckey_ = EC_KEY_new_by_curve_name(curve_nid); + eckey_ = EC_KEY_new(); if (!eckey_) { - isc_throw(LibraryError, "EC_KEY_new_by_curve_name"); + isc_throw(LibraryError, "EC_KEY_new"); + } + if (!EC_KEY_set_group(eckey_, group_)) { + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EC_KEY_set_group"); } - EC_KEY_set_asn1_flag(eckey_, OPENSSL_EC_NAMED_CURVE); if (o2i_ECPublicKey(&eckey_, &p, static_cast(len + 1)) == NULL) { EC_KEY_free(eckey_); @@ -559,11 +599,23 @@ EcDsaAsymImpl::EcDsaAsymImpl(const std::string& filename, isc_throw(UnsupportedAlgorithm, "Unknown ECDSA Key kind: " << static_cast(kind_)); } + + mdctx_.reset(new EVP_MD_CTX); + EVP_MD_CTX_init(mdctx_.get()); + + if (!EVP_DigestInit_ex(mdctx_.get(), md_, NULL)) { + EVP_MD_CTX_cleanup(mdctx_.get()); + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EVP_DigestInit_ex"); + } } /// @brief Destructor EcDsaAsymImpl::~EcDsaAsymImpl() { - tbs_.clear(); + if (mdctx_) { + EVP_MD_CTX_cleanup(mdctx_.get()); + } if (eckey_) { EC_KEY_free(eckey_); eckey_ = NULL; @@ -613,14 +665,15 @@ size_t EcDsaAsymImpl::getSignatureLength(const AsymFormat sig_format) const { /// @brief Add data to digest void EcDsaAsymImpl::update(const void* data, const size_t len) { - const size_t old = tbs_.size(); - tbs_.resize(old + len); - std::memcpy(&tbs_[old], data, len); + if (!EVP_DigestUpdate(mdctx_.get(), data, len)) { + isc_throw(LibraryError, "EVP_DigestUpdate"); + } } /// @brief Calculate the final signature void EcDsaAsymImpl::sign(isc::util::OutputBuffer& result, size_t len, const AsymFormat sig_format) { + // Check the signature format if ((sig_format != BASIC) && (sig_format != ASN1) && (sig_format != DNS)) { @@ -628,14 +681,25 @@ void EcDsaAsymImpl::sign(isc::util::OutputBuffer& result, size_t len, "Unknown Signature format: " << static_cast(sig_format)); } + + // Get the digest + size_t digest_len = EVP_MD_CTX_size(mdctx_.get()); + ossl::SecBuf digest(digest_len); + if (!EVP_DigestFinal_ex(mdctx_.get(), &digest[0], NULL)) { + isc_throw(LibraryError, "EVP_DigestFinal_ex"); + } + + // Get the signature size_t size = getSignatureLength(sig_format); ossl::SecBuf buf(size); - ECDSA_SIG* sig = ECDSA_do_sign(&tbs_[0], - static_cast(tbs_.size()), + ECDSA_SIG* sig = ECDSA_do_sign(&digest[0], + static_cast(digest_len), eckey_); if (!sig) { isc_throw(LibraryError, "ECDSA_do_sign"); } + + // Build the result if ((sig_format == BASIC) || (sig_format == DNS)) { // Store the 2 integers with padding BN_bn2bin(sig->r, &buf[(size / 2) - BN_num_bytes(sig->r)]); @@ -669,6 +733,7 @@ void EcDsaAsymImpl::sign(isc::util::OutputBuffer& result, size_t len, /// @brief Calculate the final signature void EcDsaAsymImpl::sign(void* result, size_t len, const AsymFormat sig_format) { + // Check the signature format if ((sig_format != BASIC) && (sig_format != ASN1) && (sig_format != DNS)) { @@ -676,14 +741,25 @@ void EcDsaAsymImpl::sign(void* result, size_t len, "Unknown Signature format: " << static_cast(sig_format)); } + + // Get the digest + size_t digest_len = EVP_MD_CTX_size(mdctx_.get()); + ossl::SecBuf digest(digest_len); + if (!EVP_DigestFinal_ex(mdctx_.get(), &digest[0], NULL)) { + isc_throw(LibraryError, "EVP_DigestFinal_ex"); + } + + // Get the signature size_t size = getSignatureLength(sig_format); ossl::SecBuf buf(size); - ECDSA_SIG* sig = ECDSA_do_sign(&tbs_[0], - static_cast(tbs_.size()), + ECDSA_SIG* sig = ECDSA_do_sign(&digest[0], + static_cast(digest_len), eckey_); if (!sig) { isc_throw(LibraryError, "ECDSA_do_sign"); } + + // Build the result if ((sig_format == BASIC) || (sig_format == DNS)) { // Store the 2 integers with padding BN_bn2bin(sig->r, &buf[(size / 2) - BN_num_bytes(sig->r)]); @@ -717,6 +793,7 @@ void EcDsaAsymImpl::sign(void* result, size_t len, /// @brief Calculate the final signature std::vector EcDsaAsymImpl::sign(size_t len, const AsymFormat sig_format) { + // Check the signature format if ((sig_format != BASIC) && (sig_format != ASN1) && (sig_format != DNS)) { @@ -724,14 +801,25 @@ std::vector EcDsaAsymImpl::sign(size_t len, "Unknown Signature format: " << static_cast(sig_format)); } + + // Get the digest + size_t digest_len = EVP_MD_CTX_size(mdctx_.get()); + ossl::SecBuf digest(digest_len); + if (!EVP_DigestFinal_ex(mdctx_.get(), &digest[0], NULL)) { + isc_throw(LibraryError, "EVP_DigestFinal_ex"); + } + + // Get the signature size_t size = getSignatureLength(sig_format); ossl::SecBuf buf(size); - ECDSA_SIG* sig = ECDSA_do_sign(&tbs_[0], - static_cast(tbs_.size()), + ECDSA_SIG* sig = ECDSA_do_sign(&digest[0], + static_cast(digest_len), eckey_); if (!sig) { isc_throw(LibraryError, "ECDSA_do_sign"); } + + // Build the result if ((sig_format == BASIC) || (sig_format == DNS)) { // Store the 2 integers with padding BN_bn2bin(sig->r, &buf[(size / 2) - BN_num_bytes(sig->r)]); @@ -763,6 +851,7 @@ std::vector EcDsaAsymImpl::sign(size_t len, /// @brief Verify an existing signature bool EcDsaAsymImpl::verify(const void* sig, size_t len, const AsymFormat sig_format) { + // Check the signature format if ((sig_format != BASIC) && (sig_format != ASN1) && (sig_format != DNS)) { @@ -770,6 +859,22 @@ bool EcDsaAsymImpl::verify(const void* sig, size_t len, "Unknown Signature format: " << static_cast(sig_format)); } + + // Get the digest from a copy of the context + EVP_MD_CTX tmp; + EVP_MD_CTX_init(&tmp); + if (!EVP_MD_CTX_copy_ex(&tmp, mdctx_.get())) { + isc_throw(LibraryError, "EVP_MD_CTX_copy_ex"); + } + size_t digest_len = EVP_MD_CTX_size(mdctx_.get()); + ossl::SecBuf digest(digest_len); + if (!EVP_DigestFinal_ex(&tmp, &digest[0], NULL)) { + EVP_MD_CTX_cleanup(&tmp); + isc_throw(LibraryError, "EVP_DigestFinal_ex"); + } + EVP_MD_CTX_cleanup(&tmp); + + // Get the signature ECDSA_SIG* asn_sig; const uint8_t* sigbuf = reinterpret_cast(const_cast(sig)); @@ -805,7 +910,10 @@ bool EcDsaAsymImpl::verify(const void* sig, size_t len, return false; } } - int status = ECDSA_do_verify(&tbs_[0], static_cast(tbs_.size()), + + // Check the signature + int status = ECDSA_do_verify(&digest[0], + static_cast(digest_len), asn_sig, eckey_); ECDSA_SIG_free(asn_sig); switch (status) { @@ -821,7 +929,18 @@ bool EcDsaAsymImpl::verify(const void* sig, size_t len, /// @brief Clear the crypto state and go back to the initial state void EcDsaAsymImpl::clear() { - tbs_.clear(); + if (mdctx_) { + EVP_MD_CTX_cleanup(mdctx_.get()); + } else { + mdctx_.reset(new EVP_MD_CTX); + } + EVP_MD_CTX_init(mdctx_.get()); + if (!EVP_DigestInit_ex(mdctx_.get(), md_, NULL)) { + EVP_MD_CTX_cleanup(mdctx_.get()); + EC_KEY_free(eckey_); + eckey_ = NULL; + isc_throw(LibraryError, "EVP_DigestInit_ex"); + } } /// @brief Export the key value (binary) @@ -1092,8 +1211,6 @@ bool EcDsaAsymImpl::compare(const EcDsaAsymImpl* other, if (!other || (other->algo_ != ECDSA_)) { return false; } - const EC_GROUP* grp = EC_KEY_get0_group(eckey_); - const EC_GROUP* ogrp = EC_KEY_get0_group(other->eckey_); const EC_POINT* pub = EC_KEY_get0_public_key(eckey_); const EC_POINT* opub = EC_KEY_get0_public_key(other->eckey_); int status; @@ -1127,7 +1244,7 @@ bool EcDsaAsymImpl::compare(const EcDsaAsymImpl* other, return false; } cmppub: - status = EC_GROUP_cmp(grp, ogrp, NULL); + status = EC_GROUP_cmp(group_, other->group_, NULL); switch (status) { case 0: // match but not finished @@ -1139,7 +1256,7 @@ bool EcDsaAsymImpl::compare(const EcDsaAsymImpl* other, // errors return false; } - status = EC_POINT_cmp(grp, pub, opub, NULL); + status = EC_POINT_cmp(group_, pub, opub, NULL); switch (status) { case 0: // match diff --git a/src/lib/cryptolink/openssl_ecdsa.h b/src/lib/cryptolink/openssl_ecdsa.h index 2779532254..4b270a4392 100644 --- a/src/lib/cryptolink/openssl_ecdsa.h +++ b/src/lib/cryptolink/openssl_ecdsa.h @@ -133,8 +133,12 @@ private: HashAlgorithm hash_; /// @brief The key kind AsymKeyKind kind_; - /// @brief The to be signed cache - ossl::SecBuf tbs_; + /// @brief the hash algorithm + const EVP_MD* md_; + /// @brief The protected pointer to the OpenSSL EVP_MD_CTX structure + boost::scoped_ptr mdctx_; + /// @brief The curve (group) + const EC_GROUP* group_; /// @brief The raw pointer to the OpenSSL EC_KEY structure /// There is no EC_PKEY_init() or EC_PKEY_cleanup() so /// a smart pointer cannot be used. diff --git a/src/lib/cryptolink/openssl_rsa.cc b/src/lib/cryptolink/openssl_rsa.cc index 8958cc3785..a8e1e8c1d4 100644 --- a/src/lib/cryptolink/openssl_rsa.cc +++ b/src/lib/cryptolink/openssl_rsa.cc @@ -35,16 +35,16 @@ namespace cryptolink { /// @brief Constructor from a key, asym and hash algorithm, /// key kind and key binary format RsaAsymImpl::RsaAsymImpl(const void* key, size_t key_len, - const HashAlgorithm hash_algorithm, - const AsymKeyKind key_kind, - const AsymFormat key_format) { + const HashAlgorithm hash_algorithm, + const AsymKeyKind key_kind, + const AsymFormat key_format) { algo_ = RSA_; hash_ = hash_algorithm; kind_ = key_kind; pkey_ = NULL; x509_ = NULL; - const EVP_MD* md = ossl::getHashAlgorithm(hash_); - if (md == 0) { + md_ = ossl::getHashAlgorithm(hash_); + if (md_ == 0) { isc_throw(UnsupportedAlgorithm, "Unknown hash algorithm: " << static_cast(hash_)); } @@ -247,10 +247,10 @@ RsaAsymImpl::RsaAsymImpl(const void* key, size_t key_len, mdctx_.reset(new EVP_MD_CTX); EVP_MD_CTX_init(mdctx_.get()); - if (!EVP_DigestInit_ex(mdctx_.get(), md, NULL)) { + if (!EVP_DigestInit_ex(mdctx_.get(), md_, NULL)) { EVP_MD_CTX_cleanup(mdctx_.get()); EVP_PKEY_free(pkey_); - pkey_ =NULL; + pkey_ = NULL; isc_throw(LibraryError, "EVP_DigestInit_ex"); } } @@ -258,17 +258,17 @@ RsaAsymImpl::RsaAsymImpl(const void* key, size_t key_len, /// @brief Constructor from a key file with password, /// asym and hash algorithm, key kind and key binary format RsaAsymImpl::RsaAsymImpl(const std::string& filename, - const std::string& password, - const HashAlgorithm hash_algorithm, - const AsymKeyKind key_kind, - const AsymFormat key_format) { + 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; - const EVP_MD* md = ossl::getHashAlgorithm(hash_); - if (md == 0) { + md_ = ossl::getHashAlgorithm(hash_); + if (md_ == 0) { isc_throw(UnsupportedAlgorithm, "Unknown hash algorithm: " << static_cast(hash_)); } @@ -380,7 +380,7 @@ RsaAsymImpl::RsaAsymImpl(const std::string& filename, int len = static_cast(bin.size()); rsa->n = BN_bin2bn(&bin[0], len, NULL); } else if (strncmp(line, "PublicExponent:", - strlen("PublicExponent:")) == 0) { + strlen("PublicExponent:")) == 0) { if (got_pub_exponent) { RSA_free(rsa); fclose(fp); @@ -454,7 +454,7 @@ RsaAsymImpl::RsaAsymImpl(const std::string& filename, int len = static_cast(bin.size()); rsa->q = BN_bin2bn(&bin[0], len, NULL); } else if (strncmp(line, "Exponent1:", - strlen("Exponent1:")) == 0) { + strlen("Exponent1:")) == 0) { if (got_exponent1) { RSA_free(rsa); fclose(fp); @@ -786,10 +786,10 @@ RsaAsymImpl::RsaAsymImpl(const std::string& filename, mdctx_.reset(new EVP_MD_CTX); EVP_MD_CTX_init(mdctx_.get()); - if (!EVP_DigestInit_ex(mdctx_.get(), md, NULL)) { + if (!EVP_DigestInit_ex(mdctx_.get(), md_, NULL)) { EVP_MD_CTX_cleanup(mdctx_.get()); EVP_PKEY_free(pkey_); - pkey_ =NULL; + pkey_ = NULL; isc_throw(LibraryError, "EVP_DigestInit_ex"); } } @@ -853,7 +853,7 @@ void RsaAsymImpl::update(const void* data, const size_t len) { /// @brief Calculate the final signature void RsaAsymImpl::sign(isc::util::OutputBuffer& result, size_t len, - const AsymFormat sig_format) { + const AsymFormat sig_format) { unsigned int size = getSignatureLength(sig_format); ossl::SecBuf sig(size); if (!EVP_SignFinal(mdctx_.get(), &sig[0], &size, pkey_)) { @@ -880,7 +880,7 @@ void RsaAsymImpl::sign(void* result, size_t len, const AsymFormat sig_format) { /// @brief Calculate the final signature std::vector RsaAsymImpl::sign(size_t len, - const AsymFormat sig_format) { + const AsymFormat sig_format) { unsigned int size = getSignatureLength(sig_format); ossl::SecBuf sig(size); if (!EVP_SignFinal(mdctx_.get(), &sig[0], &size, pkey_)) { @@ -893,7 +893,7 @@ std::vector RsaAsymImpl::sign(size_t len, /// @brief Verify an existing signature bool RsaAsymImpl::verify(const void* sig, size_t len, - const AsymFormat sig_format) { + const AsymFormat sig_format) { size_t size = getSignatureLength(sig_format); if (len != size) { return false; @@ -921,16 +921,10 @@ void RsaAsymImpl::clear() { mdctx_.reset(new EVP_MD_CTX); } EVP_MD_CTX_init(mdctx_.get()); - const EVP_MD* md = ossl::getHashAlgorithm(hash_); - if (md == 0) { - isc_throw(UnsupportedAlgorithm, - "Unknown hash algorithm: " << - static_cast(hash_)); - } - if (!EVP_DigestInit_ex(mdctx_.get(), md, NULL)) { + if (!EVP_DigestInit_ex(mdctx_.get(), md_, NULL)) { EVP_MD_CTX_cleanup(mdctx_.get()); EVP_PKEY_free(pkey_); - pkey_ =NULL; + pkey_ = NULL; isc_throw(LibraryError, "EVP_DigestInit_ex"); } } @@ -938,7 +932,7 @@ void RsaAsymImpl::clear() { /// @brief Export the key value (binary) std::vector RsaAsymImpl::exportkey(const AsymKeyKind key_kind, - const AsymFormat key_format) const { + const AsymFormat key_format) const { if ((key_kind == PRIVATE) && (key_format == BASIC)) { // PKCS#1 Private Key if (kind_ != PRIVATE) { @@ -1060,9 +1054,9 @@ RsaAsymImpl::exportkey(const AsymKeyKind key_kind, /// @brief Export the key value (file) void RsaAsymImpl::exportkey(const std::string& filename, - const std::string& password, - const AsymKeyKind key_kind, - const AsymFormat key_format) const { + const std::string& password, + const AsymKeyKind key_kind, + const AsymFormat key_format) const { if ((key_kind == PRIVATE) && (key_format == ASN1)) { // PKCS#8 Private Key PEM file if (kind_ != PRIVATE) { @@ -1296,7 +1290,7 @@ bool RsaAsymImpl::validate() const { /// @brief Compare two keys bool RsaAsymImpl::compare(const RsaAsymImpl* other, - const AsymKeyKind key_kind) const { + const AsymKeyKind key_kind) const { if (!other || (other->algo_ != RSA_)) { return false; } diff --git a/src/lib/cryptolink/openssl_rsa.h b/src/lib/cryptolink/openssl_rsa.h index 9b675e0a9f..d6473573ca 100644 --- a/src/lib/cryptolink/openssl_rsa.h +++ b/src/lib/cryptolink/openssl_rsa.h @@ -17,6 +17,7 @@ namespace cryptolink { /// @brief OpenSSL implementation of asymmetrical cryptography (Asym). // Each method is the counterpart of the Asym corresponding method. +// RSA class RsaAsymImpl : public AsymImpl { public: /// @brief Constructor from a key, asym and hash algorithm, @@ -132,6 +133,8 @@ private: HashAlgorithm hash_; /// @brief The key kind AsymKeyKind kind_; + /// @brief the hash algorithm + const EVP_MD* md_; /// @brief The protected pointer to the OpenSSL EVP_MD_CTX structure boost::scoped_ptr mdctx_; /// @brief The raw pointer to the OpenSSL EVP_PKEY structure diff --git a/src/lib/cryptolink/tests/Makefile.am b/src/lib/cryptolink/tests/Makefile.am index 4f40874a52..1f0f347df3 100644 --- a/src/lib/cryptolink/tests/Makefile.am +++ b/src/lib/cryptolink/tests/Makefile.am @@ -23,6 +23,8 @@ run_unittests_SOURCES += crypto_unittests.cc run_unittests_SOURCES += hash_unittests.cc run_unittests_SOURCES += hmac_unittests.cc run_unittests_SOURCES += asym_unittests.cc +run_unittests_SOURCES += rsa_unittests.cc +run_unittests_SOURCES += ecdsa_unittests.cc run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) run_unittests_LDFLAGS = $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS) $(AM_LDFLAGS) run_unittests_LDADD = $(GTEST_LDADD) $(CRYPTO_LIBS) diff --git a/src/lib/cryptolink/tests/asym_unittests.cc b/src/lib/cryptolink/tests/asym_unittests.cc index 6db19ed700..f7c0608930 100644 --- a/src/lib/cryptolink/tests/asym_unittests.cc +++ b/src/lib/cryptolink/tests/asym_unittests.cc @@ -19,8 +19,6 @@ #include #include -#include - #include #include @@ -31,14 +29,10 @@ #include #include -#include #include #include -using boost::lexical_cast; -using namespace isc::util; -using namespace isc::util::encode; using namespace isc::cryptolink; namespace { @@ -63,90 +57,6 @@ namespace { #define PUBLIC_EXPONENT 0x01, 0x00, 0x01 -#define PUBLIC_KEY \ -0x30, 0x81, 0x89, \ -0x02, 0x81, 0x81, 0x00, MODULUS, \ -0x02, 0x03, PUBLIC_EXPONENT - -#define PRIVATE_EXPONENT \ -0xa8, 0xc9, 0x93, 0x5f, 0xe4, 0x94, 0xf6, 0x45, \ -0x26, 0xb2, 0x1b, 0x8a, 0x18, 0xf2, 0x4b, 0x1f, \ -0x54, 0x2a, 0x4c, 0x18, 0xe6, 0x72, 0xfd, 0x9b, \ -0x06, 0xa0, 0x26, 0x5f, 0xd6, 0xb9, 0x32, 0xa0, \ -0x8e, 0x5c, 0x79, 0x43, 0xdf, 0x03, 0x40, 0xb7, \ -0x76, 0x21, 0x90, 0xa0, 0x37, 0x24, 0x8d, 0x07, \ -0x4a, 0xd4, 0x02, 0x1a, 0x0a, 0x31, 0x6b, 0x95, \ -0x42, 0x0f, 0xc1, 0x2f, 0xc2, 0x42, 0x3c, 0x7f, \ -0x33, 0xb3, 0x54, 0x2f, 0x83, 0xf8, 0x5d, 0x7f, \ -0x86, 0xa5, 0xe8, 0xbe, 0xae, 0x40, 0x41, 0x20, \ -0x5d, 0xa2, 0x66, 0x9a, 0x82, 0x66, 0x03, 0xfc, \ -0xf0, 0x62, 0x24, 0x08, 0x25, 0x99, 0xc6, 0x2b, \ -0xef, 0x9d, 0x79, 0x54, 0x21, 0x91, 0x62, 0x76, \ -0xe5, 0x0b, 0x30, 0xe7, 0x96, 0x9c, 0xfa, 0x45, \ -0xf1, 0x6f, 0xa7, 0x6b, 0x94, 0xa2, 0x70, 0x3d, \ -0xdd, 0x74, 0x6d, 0x4c, 0x8e, 0x8e, 0xe7, 0x01 - -#define PRIME1 \ -0xda, 0x36, 0xde, 0xd3, 0x0a, 0x15, 0x20, 0xac, \ -0x79, 0xa7, 0xe0, 0xa6, 0x55, 0x69, 0xea, 0xcd, \ -0xf7, 0xe7, 0xf3, 0xda, 0xf6, 0xeb, 0xdc, 0xdb, \ -0x7c, 0xdd, 0x13, 0x6c, 0xaa, 0xfd, 0x6e, 0x98, \ -0x7b, 0x54, 0x25, 0xc0, 0x3b, 0x7d, 0xf9, 0xb5, \ -0x5b, 0x97, 0x2f, 0xe6, 0xc1, 0x4d, 0x7d, 0x5e, \ -0x3b, 0x51, 0x9c, 0xc6, 0xb3, 0xd4, 0x23, 0x43, \ -0xbf, 0x42, 0x98, 0x50, 0x03, 0xfb, 0x0b, 0x51 - -#define PRIME2 \ -0xd2, 0x2b, 0x1c, 0x29, 0x83, 0x01, 0xfd, 0x41, \ -0x49, 0xfb, 0x95, 0x89, 0x7c, 0xaf, 0x81, 0x81, \ -0xce, 0xd1, 0x77, 0x5f, 0x65, 0x61, 0x61, 0x07, \ -0xd5, 0x45, 0x58, 0xc5, 0xdd, 0x73, 0x6b, 0x63, \ -0x3a, 0x82, 0x92, 0xad, 0xa6, 0x71, 0xa1, 0xcf, \ -0xe3, 0xb5, 0x10, 0x52, 0x42, 0xe5, 0x76, 0x8a, \ -0x1b, 0xca, 0x6a, 0x52, 0x9d, 0x54, 0x78, 0x07, \ -0xcf, 0x1e, 0xed, 0xe4, 0xf2, 0xf2, 0xba, 0x91 - -#define EXPONENT1 \ -0x6e, 0xf6, 0xa4, 0x0c, 0x90, 0xfd, 0xf9, 0x65, \ -0x7b, 0x5f, 0xa0, 0xdf, 0x34, 0x63, 0xed, 0xe0, \ -0xdb, 0x05, 0x7a, 0x7d, 0x88, 0x3e, 0x9c, 0x4a, \ -0x88, 0x8e, 0x2b, 0x08, 0x81, 0x52, 0xea, 0x60, \ -0x63, 0xa6, 0x80, 0xa3, 0xe6, 0x1c, 0xc3, 0x54, \ -0x33, 0xc5, 0x07, 0xb8, 0xc1, 0xe7, 0x53, 0xaf, \ -0x0d, 0x5f, 0x0c, 0xe8, 0x06, 0x1e, 0x03, 0xe8, \ -0xb9, 0x63, 0x75, 0xec, 0x8a, 0x79, 0xa8, 0x61 - -#define EXPONENT2 \ -0x7c, 0x6d, 0x29, 0x6f, 0x2a, 0x30, 0xb3, 0x4f, \ -0x44, 0x0d, 0xbe, 0xaa, 0x77, 0x37, 0x30, 0xe5, \ -0x39, 0x1c, 0xaa, 0x1f, 0xc0, 0x55, 0xb6, 0xac, \ -0x7c, 0x87, 0x61, 0xd7, 0x43, 0x14, 0x62, 0x2f, \ -0x8d, 0x24, 0x60, 0xd2, 0x8e, 0x08, 0x18, 0x54, \ -0x8b, 0xeb, 0x56, 0x8e, 0x5d, 0x2c, 0x9c, 0xd1, \ -0x87, 0x42, 0x7f, 0x50, 0x09, 0xf5, 0x48, 0x5a, \ -0xd7, 0x34, 0xe8, 0x82, 0xf3, 0x92, 0xe1, 0x01 - -#define COEFFICIENT \ -0x13, 0x5f, 0x97, 0x80, 0x10, 0x66, 0x54, 0x05, \ -0x55, 0x05, 0x03, 0x37, 0x96, 0xe0, 0xc0, 0xa7, \ -0x25, 0x7b, 0x70, 0x4a, 0xd2, 0x0e, 0xce, 0x82, \ -0x42, 0x3e, 0xb9, 0x5a, 0x2d, 0x87, 0xca, 0xfa, \ -0xaa, 0x82, 0xe4, 0xed, 0xdb, 0xbf, 0xbf, 0x26, \ -0x9b, 0x50, 0x84, 0x9e, 0xb0, 0xd0, 0x10, 0xb4, \ -0x79, 0x56, 0x1c, 0xd1, 0x49, 0xa1, 0x4f, 0xf8, \ -0x52, 0x6e, 0xb4, 0x1b, 0x1a, 0x5f, 0x48, 0x0c - -#define PRIVATE_KEY \ -0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, \ -0x02, 0x81, 0x81, 0x00, MODULUS, \ -0x02, 0x03, PUBLIC_EXPONENT, \ -0x02, 0x81, 0x81, 0x00, PRIVATE_EXPONENT, \ -0x02, 0x41, 0x00, PRIME1, \ -0x02, 0x41, 0x00, PRIME2, \ -0x02, 0x40, EXPONENT1, \ -0x02, 0x40, EXPONENT2, \ -0x02, 0x40, COEFFICIENT - /// @brief Public Key in PKCS#1 format const uint8_t pubpkcs1[] = { 0x30, // tag=SEQUENCE (RSAPublicKey) @@ -160,67 +70,6 @@ namespace { }; size_t pubpkcs1len = 140; - /// @brief Public Key in SubjectPublicKeyInfo format - const uint8_t pubspki[] = { - 0x30, // tag=SEQUENCE (SubjectPublicKeyInfo) - 0x81, 0x9f, // length=159 - 0x30, // tag=SEQUENCE (algorithm : AlgorithmIdentifier) - 0x0d, // length=13 - 0x06, // tag=OBJECTID (algorithm) - 0x09, // length=9 - 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, - 0x01, // value=rsaEncryption - 0x05, // tag=NULL (parameter) - 0x00, // length=00 - 0x03, // tag=BIT STRING (subjectPublicKey) - 0x81, 0x8d, // length=141 - 0x00, PUBLIC_KEY - }; - size_t pubspkilen = 162; - - /// @brief Public Key in DNSSEC format (length 132) - const uint8_t pubdns[] = { - 0x03, // length=3 - PUBLIC_EXPONENT, - MODULUS - }; - size_t pubdnslen = 132; - - /// @brief Private Key in PKCS#1 format - const uint8_t privpkcs1[] = { - 0x30, // tag=SEQUENCE (RSAPrivateKey) - 0x82, 0x02, 0x5c, // length=604 - 0x02, // tag=INTEGER (version : Version) - 0x01, // length=1 - 0x00, // value=0 - 0x02, // tag=INTEGER (modulus -- n) - 0x81, 0x81, // length=129 - 0x00, MODULUS, - 0x02, // tag=INTEGER (publicExponent -- e) - 0x03, // length=3 - PUBLIC_EXPONENT, - 0x02, // tag=INTEGER (privateExponent -- d) - 0x81, 0x81, // length=129 - 0x00, PRIVATE_EXPONENT, - 0x02, // tag=INTEGER (prime1 -- p) - 0x41, // length=65 - 0x00, PRIME1, - 0x02, // tag=INTEGER (prime2 -- q) - 0x41, // length=65 - 0x00, PRIME2, - 0x02, // tag=INTEGER (exponent1 -- d mod (p-1)) - 0x40, // length=64 - EXPONENT1, - 0x02, // tag=INTEGER (exponent2 -- d mod (q-1)) - 0x40, // length=64 - EXPONENT2, - 0x02, // tag=INTEGER (coefficient -- 1/q mod p) - 0x40, // length=64 - COEFFICIENT - }; - size_t privpkcs1len = 608; - /// @brief Public Key file (SubjectPublicKeyInfo in PEM) const std::string pubfile = TEST_DATA_SRCDIR "/pub.pem"; @@ -229,243 +78,6 @@ namespace { /// @brief Certificate file (X.509 Public Key Certificate in PEM) const std::string certfile = TEST_DATA_SRCDIR "/x509.pem"; - - /// @brief Compare data with expected value - /// @param data Value to compare - /// @param expected Expected value - /// @param len Length of the expected value - void checkData(const uint8_t* data, const uint8_t* expected, - size_t len) { - for (size_t i = 0; i < len; ++i) { - ASSERT_EQ(expected[i], data[i]); - } - } - - /// @brief Compare OutputBuffer with expected value - /// encapsulated checkData() - /// @param buf buffer to compare - /// @param expected Expected value - /// @param len Length of the expected value - void checkBuffer(const OutputBuffer& buf, const uint8_t* expected, - size_t len) - { - ASSERT_EQ(len, buf.getLength()); - checkData(static_cast(buf.getData()), expected, - len); - } - - /// @brief Sign and verify with an instantiation of an asymmetrical - /// cryptography object - /// See @ref doAsymTest for parameters - void doAsymTestDirect(const std::string& data, - const std::string& privfilename, - const std::string& password, - const std::string& pubfilename, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymFormat sig_format, - const uint8_t* expected_sig, - size_t sig_len) { - OutputBuffer data_buf(data.size()); - data_buf.writeData(data.c_str(), data.size()); - OutputBuffer sig(1); - CryptoLink& crypto = CryptoLink::getCryptoLink(); - - // Sign it - boost::shared_ptr rsa_sign(crypto.createAsym(privfilename, - password, - asym_algorithm, - hash_algorithm, - PRIVATE, - ASN1), - deleteAsym); - rsa_sign->update(data_buf.getData(), data_buf.getLength()); - rsa_sign->sign(sig, sig_len, sig_format); - - // Check if the signature is what we expect - checkBuffer(sig, expected_sig, sig_len); - - // Check whether we can verify it ourselves - boost::shared_ptr rsa_verify(crypto.createAsym(pubfilename, - "", - asym_algorithm, - hash_algorithm, - PUBLIC, - ASN1), - deleteAsym); - rsa_verify->update(data_buf.getData(), data_buf.getLength()); - EXPECT_TRUE(rsa_verify->verify(sig.getData(), - sig.getLength(), - sig_format)); - - // Change the length and check whether verification fails then - // Relies on the fact the length is checked first - EXPECT_FALSE(rsa_verify->verify(sig.getData(), - sig.getLength() - 1, - sig_format)); - EXPECT_FALSE(rsa_verify->verify(sig.getData(), - sig.getLength() + 1, - sig_format)); - - // Change the sig by flipping the first octet, and check - // whether verification fails then - sig.writeUint8At(~sig[0], 0); - EXPECT_FALSE(rsa_verify->verify(sig.getData(), - sig.getLength(), - sig_format)); - } - - /// @brief Sign and verify with vector representation of signature - /// cryptography object - /// See @ref doAsymTest for parameters - void doAsymTestVector(const std::string& data, - const std::string& privfilename, - const std::string& password, - const std::string& pubfilename, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymFormat sig_format, - const uint8_t* expected_sig, - size_t sig_len) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr rsa_sign(crypto.createAsym(privfilename, - password, - asym_algorithm, - hash_algorithm, - PRIVATE, - ASN1), - deleteAsym); - rsa_sign->update(data.c_str(), data.size()); - std::vector sig = rsa_sign->sign(sig_len, sig_format); - ASSERT_EQ(sig_len, sig.size()); - checkData(&sig[0], expected_sig, sig_len); - - boost::shared_ptr rsa_verify(crypto.createAsym(pubfilename, - "", - asym_algorithm, - hash_algorithm, - PUBLIC, - ASN1), - deleteAsym); - rsa_verify->update(data.c_str(), data.size()); - EXPECT_TRUE(rsa_verify->verify(&sig[0], sig.size(), sig_format)); - - EXPECT_FALSE(rsa_verify->verify(&sig[0], sig.size() - 1, sig_format)); - EXPECT_FALSE(rsa_verify->verify(&sig[0], sig.size() + 1, sig_format)); - - sig[0] = ~sig[0]; - EXPECT_FALSE(rsa_verify->verify(&sig[0], sig.size(), sig_format)); - } - - /// @brief Sign and verify with array representation of signature - /// cryptography object - /// See @ref doAsymTest for parameters - void doAsymTestArray(const std::string& data, - const std::string& privfilename, - const std::string& password, - const std::string& pubfilename, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymFormat sig_format, - const uint8_t* expected_sig, - size_t sig_len) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr rsa_sign(crypto.createAsym(privfilename, - password, - asym_algorithm, - hash_algorithm, - PRIVATE, - ASN1), - deleteAsym); - rsa_sign->update(data.c_str(), data.size()); - - // note: this is not exception-safe, and can leak, but - // if there is an unexpected exception in the code below we - // have more important things to fix. - uint8_t* sig = new uint8_t[sig_len]; - - rsa_sign->sign(sig, sig_len, sig_format); - checkData(sig, expected_sig, sig_len); - - boost::shared_ptr rsa_verify(crypto.createAsym(pubfilename, - "", - asym_algorithm, - hash_algorithm, - PUBLIC, - ASN1), - deleteAsym); - rsa_verify->update(data.c_str(), data.size()); - EXPECT_TRUE(rsa_verify->verify(sig, sig_len, sig_format)); - - EXPECT_FALSE(rsa_verify->verify(sig, sig_len - 1, sig_format)); - EXPECT_FALSE(rsa_verify->verify(sig, sig_len + 1, sig_format)); - - sig[0] = ~sig[0]; - EXPECT_FALSE(rsa_verify->verify(sig, sig_len, sig_format)); - - delete[] sig; - } - - /// @brief Sign and verify using all variants - /// @param data Input value - /// @param privfilename Private key file name - /// @param password Private key password - /// @param pubfilename Public key file name - /// @param asym_algorithm Asym algorithm enum - /// @param hash_algorithm Hash algorithm enum - /// @param sig_format Signature format enum - /// @param expected_sig Expected value - /// @param sig_len Expected value length - void doAsymTest(const std::string& data, - const std::string& privfilename, - const std::string& password, - const std::string& pubfilename, - const AsymAlgorithm asym_algorithm, - const HashAlgorithm hash_algorithm, - const AsymFormat sig_format, - const uint8_t* expected_sig, - size_t sig_len) { - doAsymTestDirect(data, privfilename, password, pubfilename, - asym_algorithm, hash_algorithm, sig_format, - expected_sig, sig_len); - doAsymTestVector(data, privfilename, password, pubfilename, - asym_algorithm, hash_algorithm, sig_format, - expected_sig, sig_len); - doAsymTestArray(data, privfilename, password, pubfilename, - asym_algorithm, hash_algorithm, sig_format, - expected_sig, sig_len); - } -} - -// -// Test values -// -TEST(AsymTest, RSA_SHA1) { - const uint8_t sig_expected[] = { - 0x16, 0xaa, 0xd3, 0x27, 0x5b, 0x22, 0xff, 0x2b, - 0x74, 0x77, 0x7a, 0x20, 0x6c, 0xdc, 0xa6, 0xb1, - 0x88, 0x1a, 0xb3, 0xc6, 0x5a, 0xae, 0x35, 0x3a, - 0x04, 0x8d, 0x7f, 0x81, 0x5b, 0xef, 0xd6, 0xe2, - 0x07, 0xee, 0xec, 0x1e, 0xf4, 0x89, 0x82, 0x6c, - 0x2c, 0x0c, 0x25, 0x8a, 0xf0, 0x8a, 0xde, 0x6c, - 0xf7, 0x66, 0x9d, 0xa6, 0xd5, 0x69, 0x1e, 0x47, - 0x76, 0xf3, 0xe7, 0x47, 0x12, 0xd5, 0x92, 0x45, - 0xb5, 0xc6, 0x50, 0x32, 0xe1, 0x25, 0xd9, 0xa1, - 0x23, 0xd1, 0x12, 0x6d, 0x1f, 0xa8, 0x9e, 0xc3, - 0xdb, 0x41, 0xb3, 0x13, 0x0b, 0x7a, 0xea, 0x72, - 0xa7, 0x60, 0xc8, 0xfd, 0x89, 0xee, 0x36, 0xe4, - 0x5c, 0xa8, 0xfa, 0x86, 0x4b, 0xcc, 0x15, 0x7d, - 0xcb, 0x79, 0x90, 0x51, 0xa2, 0x62, 0x43, 0xc7, - 0xe1, 0x04, 0x08, 0x13, 0x68, 0x6d, 0x7b, 0x4d, - 0x45, 0xca, 0x3e, 0x6c, 0xba, 0x62, 0x90, 0x0a, - // pad - 0x00 - }; - const size_t sig_len = 128; - doAsymTest("Permission to use, copy, modify, and/or " - "distribute this software\n", - privfile, "1234", pubfile, RSA_, SHA1, BASIC, - sig_expected, sig_len); } // @@ -494,414 +106,6 @@ TEST(AsymTest, BAD_ALGO) { UnsupportedAlgorithm); } -TEST(AsymTest, RSA_PUB_PKCS1) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr pub_key(crypto.createAsym(pubpkcs1, pubpkcs1len, - RSA_, SHA1, - PUBLIC, BASIC), - deleteAsym); - ASSERT_TRUE(pub_key->validate()); - EXPECT_EQ(RSA_, pub_key->getAsymAlgorithm()); - EXPECT_EQ(SHA1, pub_key->getHashAlgorithm()); - EXPECT_EQ(PUBLIC, pub_key->getAsymKeyKind()); - EXPECT_EQ(1024, pub_key->getKeySize()); - EXPECT_EQ(128, pub_key->getSignatureLength(BASIC)); - EXPECT_EQ(128, pub_key->getSignatureLength(ASN1)); - EXPECT_EQ(128, pub_key->getSignatureLength(DNS)); - - EXPECT_THROW(crypto.createAsym(pubpkcs1, pubpkcs1len - 1, - RSA_, SHA1, PUBLIC, BASIC), - BadKey); - - boost::shared_ptr ref_key(crypto.createAsym(pubfile, "", - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - EXPECT_TRUE(pub_key->compare(ref_key.get(), PUBLIC)); - EXPECT_TRUE(ref_key->compare(pub_key.get(), PUBLIC)); - EXPECT_FALSE(pub_key->compare(ref_key.get(), PRIVATE)); - EXPECT_FALSE(pub_key->compare(ref_key.get(), CERT)); - - const std::vector pubbin = ref_key->exportkey(PUBLIC, BASIC); - checkData(&pubbin[0], pubpkcs1, pubpkcs1len); -} - -TEST(AsymTest, RSA_PUB_SPKI) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr pub_key(crypto.createAsym(pubspki, pubspkilen, - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - ASSERT_TRUE(pub_key->validate()); - EXPECT_EQ(RSA_, pub_key->getAsymAlgorithm()); - EXPECT_EQ(SHA1, pub_key->getHashAlgorithm()); - EXPECT_EQ(PUBLIC, pub_key->getAsymKeyKind()); - EXPECT_EQ(1024, pub_key->getKeySize()); - - EXPECT_THROW(crypto.createAsym(pubspki, pubspkilen - 1, - RSA_, SHA1, PUBLIC, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(pubspki, pubspkilen, - RSA_, SHA1, PUBLIC, BASIC), - BadKey); - - boost::shared_ptr ref_key(crypto.createAsym(pubfile, "", - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - EXPECT_TRUE(pub_key->compare(ref_key.get(), PUBLIC)); - EXPECT_TRUE(ref_key->compare(pub_key.get(), PUBLIC)); - EXPECT_FALSE(pub_key->compare(ref_key.get(), PRIVATE)); - EXPECT_FALSE(pub_key->compare(ref_key.get(), CERT)); - - const std::vector pubbin = ref_key->exportkey(PUBLIC, ASN1); - checkData(&pubbin[0], pubspki, pubspkilen); -} - -TEST(AsymTest, RSA_PUB_DNS) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr pub_key(crypto.createAsym(pubdns, pubdnslen, - RSA_, SHA1, - PUBLIC, DNS), - deleteAsym); - ASSERT_TRUE(pub_key->validate()); - EXPECT_EQ(RSA_, pub_key->getAsymAlgorithm()); - EXPECT_EQ(SHA1, pub_key->getHashAlgorithm()); - EXPECT_EQ(PUBLIC, pub_key->getAsymKeyKind()); - EXPECT_EQ(1024, pub_key->getKeySize()); - - boost::shared_ptr ref_key(crypto.createAsym(pubfile, "", - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - EXPECT_TRUE(pub_key->compare(ref_key.get(), PUBLIC)); - EXPECT_TRUE(ref_key->compare(pub_key.get(), PUBLIC)); - EXPECT_FALSE(pub_key->compare(ref_key.get(), PRIVATE)); - EXPECT_FALSE(pub_key->compare(ref_key.get(), CERT)); - - const std::vector pubbin = ref_key->exportkey(PUBLIC, DNS); - EXPECT_EQ(pubbin.size(), pubdnslen); - checkData(&pubbin[0], pubdns, pubdnslen); - - const std::string keystr = - "AwEAAbMlwgHujJFdo+pVkKIss7E1GHuhAIBPITKU0aLDGrwK7s1/IxJd+JLLh2n" - "9hQ8lV4hpS16TEjqTqSNkD3yqIMpWk4HpZLIgrVUlh7GFyNb+X6nNUy6vnlOk+7r" - "vMFOdAe63/6reevpX+99j85x3LqSXEDDBFUhrAR5XjV3r/ELh"; - std::vector keybin; - decodeBase64(keystr, keybin); - EXPECT_EQ(keybin.size(), pubdnslen); - checkData(&keybin[0], pubdns, pubdnslen); - - const std::string dnsfile = TEST_DATA_SRCDIR "/Kexample.+005+18330.key"; - boost::shared_ptr dns_key(crypto.createAsym(dnsfile, "", - RSA_, SHA1, - PUBLIC, DNS), - deleteAsym); - EXPECT_TRUE(dns_key->compare(ref_key.get(), PUBLIC)); - EXPECT_TRUE(ref_key->compare(dns_key.get(), PUBLIC)); -} - -TEST(AsymTest, RSA_PRIV_PKCS1) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr priv_key(crypto.createAsym(privpkcs1, privpkcs1len, - RSA_, SHA1, - PRIVATE, BASIC), - deleteAsym); - ASSERT_TRUE(priv_key->validate()); - EXPECT_EQ(RSA_, priv_key->getAsymAlgorithm()); - EXPECT_EQ(SHA1, priv_key->getHashAlgorithm()); - EXPECT_EQ(PRIVATE, priv_key->getAsymKeyKind()); - EXPECT_EQ(1024, priv_key->getKeySize()); - EXPECT_EQ(128, priv_key->getSignatureLength(BASIC)); - EXPECT_EQ(128, priv_key->getSignatureLength(ASN1)); - EXPECT_EQ(128, priv_key->getSignatureLength(DNS)); - - EXPECT_THROW(crypto.createAsym(privpkcs1, privpkcs1len - 1, - RSA_, SHA1, PRIVATE, BASIC), - BadKey); - - boost::shared_ptr ref_key(crypto.createAsym(privfile, "1234", - RSA_, SHA1, - PRIVATE, ASN1), - deleteAsym); - EXPECT_TRUE(priv_key->compare(ref_key.get(), PRIVATE)); - EXPECT_TRUE(ref_key->compare(priv_key.get(), PRIVATE)); - EXPECT_TRUE(priv_key->compare(ref_key.get(), PUBLIC)); - EXPECT_FALSE(priv_key->compare(ref_key.get(), CERT)); - - const std::vector privbin = ref_key->exportkey(PRIVATE, BASIC); - checkData(&privbin[0], privpkcs1, privpkcs1len); - - boost::shared_ptr pub_key(crypto.createAsym(pubfile, "", - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - EXPECT_TRUE(priv_key->compare(pub_key.get(), PUBLIC)); - EXPECT_TRUE(pub_key->compare(priv_key.get(), PUBLIC)); -} - -TEST(AsymTest, RSA_PRIV_PKCS) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr ref_key(crypto.createAsym(privfile, "1234", - RSA_, SHA1, - PRIVATE, ASN1), - deleteAsym); -#ifndef WITH_BOTAN - const std::string pkcs1file = TEST_DATA_SRCDIR "/priv.pem"; - boost::shared_ptr pkcs1_key(crypto.createAsym(pkcs1file, "", - RSA_, SHA1, - PRIVATE, BASIC), - deleteAsym); - EXPECT_TRUE(pkcs1_key->validate()); - EXPECT_TRUE(pkcs1_key->compare(ref_key.get(), PRIVATE)); - EXPECT_TRUE(ref_key->compare(pkcs1_key.get(), PRIVATE)); -#endif - - // PKCS#8 without encryption - const std::string nefile = TEST_DATA_SRCDIR "/pkcs8ne.pem"; - boost::shared_ptr ne_key(crypto.createAsym(nefile, "", - RSA_, SHA1, - PRIVATE, ASN1), - deleteAsym); - EXPECT_TRUE(ne_key->validate()); - EXPECT_TRUE(ne_key->compare(ref_key.get(), PRIVATE)); - EXPECT_TRUE(ref_key->compare(ne_key.get(), PRIVATE)); -} - -TEST(AsymTest, RSA_PRIV_DNS) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - const std::string privdnsfile = - TEST_DATA_SRCDIR "/Kexample.+005+18330.private"; - boost::shared_ptr dns_key(crypto.createAsym(privdnsfile, "", - RSA_, SHA1, - PRIVATE, DNS), - deleteAsym); - EXPECT_TRUE(dns_key->validate()); - EXPECT_EQ(RSA_, dns_key->getAsymAlgorithm()); - EXPECT_EQ(SHA1, dns_key->getHashAlgorithm()); - EXPECT_EQ(PRIVATE, dns_key->getAsymKeyKind()); - EXPECT_EQ(1024, dns_key->getKeySize()); - -#ifndef WITH_BOTAN - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, SHA1, PRIVATE, BASIC), - BadKey); -#endif - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, SHA1, PRIVATE, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, MD5, PRIVATE, DNS), - BadKey); - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, SHA256, PRIVATE, DNS), - BadKey); - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, SHA512, PRIVATE, DNS), - BadKey); - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, SHA224, PRIVATE, DNS), - UnsupportedAlgorithm); - EXPECT_THROW(crypto.createAsym(privdnsfile, "", - RSA_, SHA384, PRIVATE, DNS), - UnsupportedAlgorithm); - - boost::shared_ptr ref_key(crypto.createAsym(privfile, "1234", - RSA_, SHA1, - PRIVATE, ASN1), - deleteAsym); - EXPECT_TRUE(dns_key->compare(ref_key.get(), PRIVATE)); - EXPECT_TRUE(ref_key->compare(dns_key.get(), PRIVATE)); - EXPECT_TRUE(dns_key->compare(ref_key.get(), PUBLIC)); - EXPECT_FALSE(dns_key->compare(ref_key.get(), CERT)); - - char tempname[] = "/tmp/privateXXXXXX"; - const std::string testfile = mktemp(tempname); - ref_key->exportkey(testfile, "", PRIVATE, DNS); - FILE* fp; - fp = fopen(testfile.c_str(), "r"); - ASSERT_TRUE(fp != NULL); - std::vector testbuf(1024); - size_t tcc = fread(&testbuf[0], 1024, 1, fp); - testbuf.resize(tcc); - fclose(fp); - fp = fopen(privdnsfile.c_str(), "r"); - ASSERT_TRUE(fp != NULL); - std::vector refbuf(1024); - int rcc = fread(&refbuf[0], 1024, 1, fp); - refbuf.resize(rcc); - fclose(fp); - EXPECT_EQ(rcc, tcc); - EXPECT_TRUE(testbuf == refbuf); - unlink(testfile.c_str()); -} - -TEST(AsymTest, CERTIFICATE) { - CryptoLink& crypto = CryptoLink::getCryptoLink(); - boost::shared_ptr from_file(crypto.createAsym(certfile, "", - RSA_, SHA1, - CERT, ASN1), - deleteAsym); - EXPECT_TRUE(from_file->validate()); - EXPECT_EQ(RSA_, from_file->getAsymAlgorithm()); - EXPECT_EQ(SHA1, from_file->getHashAlgorithm()); - EXPECT_EQ(CERT, from_file->getAsymKeyKind()); - EXPECT_EQ(1024, from_file->getKeySize()); - - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA1, PUBLIC, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA1, PRIVATE, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA1, CERT, BASIC), - UnsupportedAlgorithm); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA1, CERT, DNS), - UnsupportedAlgorithm); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, MD5, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA224, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA256, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA384, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(certfile, "", RSA_, SHA512, CERT, ASN1), - BadKey); - - boost::shared_ptr pub_key(crypto.createAsym(pubfile, "", - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - EXPECT_TRUE(from_file->compare(pub_key.get(), PUBLIC)); - EXPECT_TRUE(pub_key->compare(from_file.get(), PUBLIC)); - EXPECT_FALSE(from_file->compare(pub_key.get(), PRIVATE)); - EXPECT_FALSE(pub_key->compare(from_file.get(), PRIVATE)); - - std::vector certbin = from_file->exportkey(CERT, ASN1); - boost::shared_ptr from_bin(crypto.createAsym(&certbin[0], - certbin.size(), - RSA_, SHA1, - CERT, ASN1), - deleteAsym); - EXPECT_TRUE(from_bin->validate()); - EXPECT_TRUE(from_file->compare(from_bin.get(), PUBLIC)); - EXPECT_TRUE(from_bin->compare(from_file.get(), PUBLIC)); - EXPECT_TRUE(from_file->compare(from_bin.get(), CERT)); - EXPECT_TRUE(from_bin->compare(from_file.get(), CERT)); - - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size() - 1, - RSA_, SHA1, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, SHA1, CERT, BASIC), - UnsupportedAlgorithm); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, SHA1, CERT, DNS), - UnsupportedAlgorithm); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, MD5, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, SHA224, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, SHA256, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, SHA384, CERT, ASN1), - BadKey); - EXPECT_THROW(crypto.createAsym(&certbin[0], certbin.size(), - RSA_, SHA512, CERT, ASN1), - BadKey); - - certbin[certbin.size() - 1] = ~certbin[certbin.size() - 1]; - boost::shared_ptr bad_bin(crypto.createAsym(&certbin[0], - certbin.size(), - RSA_, SHA1, - CERT, ASN1), - deleteAsym); - EXPECT_FALSE(bad_bin->validate()); -} - -// -// Multiple signatures -// -TEST(AsymTest, doubleSign) { - std::string data = "Kea provides DHCPv4 and DHCPv6 servers"; - OutputBuffer data_buf(data.size()); - data_buf.writeData(data.c_str(), data.size()); - CryptoLink& crypto = CryptoLink::getCryptoLink(); - - // Sign it - boost::shared_ptr rsa_sign(crypto.createAsym(privfile, "1234", - RSA_, SHA1, - PRIVATE, ASN1), - deleteAsym); - ASSERT_TRUE(rsa_sign); - - OutputBuffer sig1(1); - size_t sig1_len = rsa_sign->getSignatureLength(BASIC); - EXPECT_EQ(128, sig1_len); - rsa_sign->update(data_buf.getData(), data_buf.getLength()); - rsa_sign->sign(sig1, sig1_len, BASIC); - ASSERT_EQ(sig1_len, sig1.getLength()); - - // Clear state - rsa_sign->clear(); - - // Sign it again - OutputBuffer sig2(1); - size_t sig2_len = rsa_sign->getSignatureLength(BASIC); - EXPECT_EQ(128, sig2_len); - rsa_sign->update(data_buf.getData(), data_buf.getLength()); - rsa_sign->sign(sig2, sig2_len, BASIC); - EXPECT_EQ(sig2_len, sig2.getLength()); - - // Compare - ASSERT_EQ(sig1_len, sig2_len); - EXPECT_TRUE(std::memcmp(sig1.getData(), sig2.getData(), sig1_len) == 0); -} - -// -// Multiple verifies -// -TEST(AsymTest, doubleVerify) { - std::string data = "Kea provides DHCPv4 and DHCPv6 servers"; - OutputBuffer data_buf(data.size()); - data_buf.writeData(data.c_str(), data.size()); - CryptoLink& crypto = CryptoLink::getCryptoLink(); - - // Sign it - boost::shared_ptr rsa_sign(crypto.createAsym(privfile, "1234", - RSA_, SHA1, - PRIVATE, ASN1), - deleteAsym); - ASSERT_TRUE(rsa_sign); - - OutputBuffer sig(1); - size_t sig_len = rsa_sign->getSignatureLength(BASIC); - EXPECT_EQ(128, sig_len); - rsa_sign->update(data_buf.getData(), data_buf.getLength()); - rsa_sign->sign(sig, sig_len, BASIC); - EXPECT_EQ(sig_len, sig.getLength()); - - // Verify - boost::shared_ptr rsa_verify(crypto.createAsym(pubfile, "", - RSA_, SHA1, - PUBLIC, ASN1), - deleteAsym); - ASSERT_TRUE(rsa_verify); - - rsa_verify->update(data_buf.getData(), data_buf.getLength()); - EXPECT_TRUE(rsa_verify->verify(sig.getData(), sig.getLength(), BASIC)); - - // Clear state - rsa_verify->clear(); - - // Verify again - rsa_verify->update(data_buf.getData(), data_buf.getLength()); - EXPECT_TRUE(rsa_verify->verify(sig.getData(), sig.getLength(), BASIC)); -} - namespace { std::string callout_name(""); @@ -948,4 +152,7 @@ TEST(AsymTest, callout) { EXPECT_TRUE(std::memcmp(&bin[0], &callout_cert[0], bin.size()) == 0); ASSERT_EQ(1, callout_argument_names.size()); EXPECT_TRUE(callout_argument_names[0].compare("certificate") == 0); + + EXPECT_NO_THROW(preCLH.deregisterCallout("validate_certificate", + validate_certificate_callout)); } diff --git a/src/lib/cryptolink/tests/ecdsa_unittests.cc b/src/lib/cryptolink/tests/ecdsa_unittests.cc index b63b140255..f974897f45 100644 --- a/src/lib/cryptolink/tests/ecdsa_unittests.cc +++ b/src/lib/cryptolink/tests/ecdsa_unittests.cc @@ -108,7 +108,7 @@ namespace { /// @brief ASN.1 ECDSA Signature layout const uint8_t asn1sig[] = { 0x30, // tag=SEQUENCE - 0x45, // length=69 + 0x46, // length=70 0x02, // tag=INTEGER 0x21, // length=33 0x00, SIGNATURE_R, @@ -398,12 +398,12 @@ TEST(EcDSATest, SHA256) { size_t nsig_len = ecdsa_sign->getSignatureLength(BASIC); ecdsa_sign->sign(nsig, nsig_len, BASIC); - boost::shared_ptr ecdsa_verify(crypto.createAsym(pubfile, - "", + boost::shared_ptr ecdsa_verify(crypto.createAsym(pubkey, + pubkeylen, ECDSA_, SHA256, PUBLIC, - ASN1), + DNS), deleteAsym); ASSERT_TRUE(ecdsa_verify);