]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[sedhcpv6] fixed OpenSSL ECDSA, still Botan ECDSA to do
authorFrancis Dupont <fdupont@isc.org>
Sun, 7 Jun 2015 16:40:39 +0000 (18:40 +0200)
committerFrancis Dupont <fdupont@isc.org>
Sun, 7 Jun 2015 16:40:39 +0000 (18:40 +0200)
src/lib/cryptolink/Makefile.am
src/lib/cryptolink/botan_rsa.h
src/lib/cryptolink/openssl_asym.cc
src/lib/cryptolink/openssl_common.h
src/lib/cryptolink/openssl_ecdsa.cc
src/lib/cryptolink/openssl_ecdsa.h
src/lib/cryptolink/openssl_rsa.cc
src/lib/cryptolink/openssl_rsa.h
src/lib/cryptolink/tests/Makefile.am
src/lib/cryptolink/tests/asym_unittests.cc
src/lib/cryptolink/tests/ecdsa_unittests.cc

index 980c1157d76ff8f1c3d1d1b3003c7209770f05f6..30dd02ef020333ac434bc525a7653ff0c20111ae 100644 (file)
@@ -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}
index 6329946fe0b9b933d61339d8c7588dcc65a9d47a..3c6db360af8f71367650ce8bb1adc5112914e0c6 100644 (file)
@@ -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,
index 1907fd5dc8ded402ea89c572cb41426aef45b759..014b6bd036e68deec9de8f4cf6b5300d6efc7eee 100644 (file)
 #include <cryptolink/crypto_asym.h>
 
 #include <openssl/evp.h>
+#include <openssl/ec.h>
 
 #include <hooks/hooks_manager.h>
 #include <hooks/callout_handle.h>
 #include <cryptolink/openssl_common.h>
 #include <cryptolink/openssl_rsa.h>
+#include <cryptolink/openssl_ecdsa.h>
 
 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<uint8_t> 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<const RsaAsymImpl*>(other->impl_);
         return (impl->compare(oimpl, key_kind));
+    } else if (getAsymAlgorithm() == ECDSA_) {
+        const EcDsaAsymImpl* impl = dynamic_cast<const EcDsaAsymImpl*>(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<const EcDsaAsymImpl*>(other->impl_);
+        return (impl->compare(oimpl, key_kind));
     }
+
     isc_throw(UnsupportedAlgorithm, "compare");
 }
 
index 065203724772138608bb7468619e9c5233b1d3af..fb19c9f2d66be8789760b9a6fd2581c0f7c02d75 100644 (file)
@@ -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_;
index 2e43febdacc92481c17409f939f83dbdc8c18744..f1db80e3c6189e6a6fdf97279e0bb5ec0b835b7a 100644 (file)
@@ -18,6 +18,7 @@
 #include <boost/scoped_ptr.hpp>
 
 #include <openssl/pem.h>
+#include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/ec.h>
 #include <openssl/ecdsa.h>
 #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<long>(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<int>(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<long>(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<int>(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<int>(sig_format));
     }
+
+    // Get the digest
+    size_t digest_len = EVP_MD_CTX_size(mdctx_.get());
+    ossl::SecBuf<uint8_t> 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<uint8_t> buf(size);
-    ECDSA_SIG* sig = ECDSA_do_sign(&tbs_[0],
-                                   static_cast<int>(tbs_.size()),
+    ECDSA_SIG* sig = ECDSA_do_sign(&digest[0],
+                                   static_cast<int>(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<int>(sig_format));
     }
+
+    // Get the digest
+    size_t digest_len = EVP_MD_CTX_size(mdctx_.get());
+    ossl::SecBuf<uint8_t> 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<uint8_t> buf(size);
-    ECDSA_SIG* sig = ECDSA_do_sign(&tbs_[0],
-                                   static_cast<int>(tbs_.size()),
+    ECDSA_SIG* sig = ECDSA_do_sign(&digest[0],
+                                   static_cast<int>(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<uint8_t> 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<uint8_t> EcDsaAsymImpl::sign(size_t len,
                   "Unknown Signature format: " <<
                   static_cast<int>(sig_format));
     }
+
+    // Get the digest
+    size_t digest_len = EVP_MD_CTX_size(mdctx_.get());
+    ossl::SecBuf<uint8_t> 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<uint8_t> buf(size);
-    ECDSA_SIG* sig = ECDSA_do_sign(&tbs_[0],
-                                   static_cast<int>(tbs_.size()),
+    ECDSA_SIG* sig = ECDSA_do_sign(&digest[0],
+                                   static_cast<int>(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<uint8_t> 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<int>(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<uint8_t> 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 uint8_t*>(const_cast<void*>(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<int>(tbs_.size()),
+
+    // Check the signature
+    int status = ECDSA_do_verify(&digest[0],
+                                 static_cast<int>(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
index 277953225465066be1f45f000bc311bfc4e27b15..4b270a4392a0985e42410a2b1ea82253f93f5364 100644 (file)
@@ -133,8 +133,12 @@ private:
     HashAlgorithm hash_;
     /// @brief The key kind
     AsymKeyKind kind_;
-    /// @brief The to be signed cache
-    ossl::SecBuf<uint8_t> tbs_;
+    /// @brief the hash algorithm
+    const EVP_MD* md_;
+    /// @brief The protected pointer to the OpenSSL EVP_MD_CTX structure
+    boost::scoped_ptr<EVP_MD_CTX> 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.
index 8958cc3785f26a0488cc9e47315b774928705b8e..a8e1e8c1d431d4e02ac14725cfcf631861bd08b0 100644 (file)
@@ -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<int>(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<int>(hash_));
     }
@@ -380,7 +380,7 @@ RsaAsymImpl::RsaAsymImpl(const std::string& filename,
                 int len = static_cast<int>(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<int>(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<unsigned char> 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<uint8_t> RsaAsymImpl::sign(size_t len,
-                                      const AsymFormat sig_format) {
+                                       const AsymFormat sig_format) {
     unsigned int size = getSignatureLength(sig_format);
     ossl::SecBuf<unsigned char> sig(size);
     if (!EVP_SignFinal(mdctx_.get(), &sig[0], &size, pkey_)) {
@@ -893,7 +893,7 @@ std::vector<uint8_t> 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<int>(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<uint8_t>
 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;
     }
index 9b675e0a9f17c49cb4bf5aca0bb84cc162c18a12..d6473573cae612e1d264ab9fb4fd8073cedb7410 100644 (file)
@@ -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<EVP_MD_CTX> mdctx_;
     /// @brief The raw pointer to the OpenSSL EVP_PKEY structure
index 4f40874a52e32ef6d7a7266d8469ad55c9b27dc0..1f0f347df3739bb526139336f834bea314283073 100644 (file)
@@ -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)
index 6db19ed700fcd9cf5192a1552ee05f5f5db81d71..f7c0608930e8426d4abd02075e3556c5fdd189bd 100644 (file)
@@ -19,8 +19,6 @@
 #include <vector>
 #include <stdlib.h>
 
-#include <boost/lexical_cast.hpp>
-
 #include <gtest/gtest.h>
 
 #include <util/encode/base64.h>
 #include <cryptolink/cryptolink.h>
 #include <cryptolink/crypto_asym.h>
 
-#include <util/buffer.h>
 #include <exceptions/exceptions.h>
 
 #include <boost/shared_ptr.hpp>
 
-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<const uint8_t*>(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<Asym> 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<Asym> 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<Asym> rsa_sign(crypto.createAsym(privfilename,
-                                                           password,
-                                                           asym_algorithm,
-                                                           hash_algorithm,
-                                                           PRIVATE,
-                                                           ASN1),
-                                         deleteAsym);
-        rsa_sign->update(data.c_str(), data.size());
-        std::vector<uint8_t> sig = rsa_sign->sign(sig_len, sig_format);
-        ASSERT_EQ(sig_len, sig.size());
-        checkData(&sig[0], expected_sig, sig_len);
-
-        boost::shared_ptr<Asym> 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<Asym> 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<Asym> 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<Asym> 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<Asym> 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<uint8_t> pubbin = ref_key->exportkey(PUBLIC, BASIC);
-    checkData(&pubbin[0], pubpkcs1, pubpkcs1len);
-}
-
-TEST(AsymTest, RSA_PUB_SPKI) {
-    CryptoLink& crypto = CryptoLink::getCryptoLink();
-    boost::shared_ptr<Asym> 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<Asym> 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<uint8_t> pubbin = ref_key->exportkey(PUBLIC, ASN1);
-    checkData(&pubbin[0], pubspki, pubspkilen);
-}
-
-TEST(AsymTest, RSA_PUB_DNS) {
-    CryptoLink& crypto = CryptoLink::getCryptoLink();
-    boost::shared_ptr<Asym> 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<Asym> 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<uint8_t> 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<uint8_t> 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<Asym> 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<Asym> 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<Asym> 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<uint8_t> privbin = ref_key->exportkey(PRIVATE, BASIC);
-    checkData(&privbin[0], privpkcs1, privpkcs1len);
-
-    boost::shared_ptr<Asym> 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<Asym> 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<Asym> 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<Asym> 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<Asym> 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<Asym> 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<char> 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<char> 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<Asym> 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<Asym> 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<uint8_t> certbin = from_file->exportkey(CERT, ASN1);
-    boost::shared_ptr<Asym> 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<Asym> 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<Asym> 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<Asym> 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<Asym> 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));
 }
index b63b1402557a2bff74c5ba5b286365f448355ae9..f974897f45dc300ba1b31a86ccfcdc3c3e011513 100644 (file)
@@ -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<Asym> ecdsa_verify(crypto.createAsym(pubfile,
-                                                           "",
+    boost::shared_ptr<Asym> ecdsa_verify(crypto.createAsym(pubkey,
+                                                           pubkeylen,
                                                            ECDSA_,
                                                            SHA256,
                                                            PUBLIC,
-                                                           ASN1),
+                                                           DNS),
                                          deleteAsym);
     ASSERT_TRUE(ecdsa_verify);