From: Remi Gacogne Date: Mon, 15 Oct 2018 15:22:30 +0000 (+0200) Subject: Use unique pointers in the OpenSSL signer X-Git-Tag: dnsdist-1.3.3~34^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F7069%2Fhead;p=thirdparty%2Fpdns.git Use unique pointers in the OpenSSL signer --- diff --git a/pdns/opensslsigners.cc b/pdns/opensslsigners.cc index ee26780d5f..dc746006d5 100644 --- a/pdns/opensslsigners.cc +++ b/pdns/opensslsigners.cc @@ -177,7 +177,7 @@ void openssl_seed() class OpenSSLRSADNSCryptoKeyEngine : public DNSCryptoKeyEngine { public: - explicit OpenSSLRSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo) + explicit OpenSSLRSADNSCryptoKeyEngine(unsigned int algo): DNSCryptoKeyEngine(algo), d_key(std::unique_ptr(nullptr, RSA_free)) { int ret = RAND_status(); if (ret != 1) { @@ -187,12 +187,10 @@ public: ~OpenSSLRSADNSCryptoKeyEngine() { - if (d_key) - RSA_free(d_key); } string getName() const override { return "OpenSSL RSA"; } - int getBits() const override { return RSA_size(d_key) << 3; } + int getBits() const override { return RSA_size(d_key.get()) << 3; } void create(unsigned int bits) override; storvector_t convertToISCVector() const override; @@ -213,7 +211,7 @@ public: private: static int hashSizeToKind(size_t hashSize); - RSA* d_key{NULL}; + std::unique_ptr d_key; }; @@ -232,36 +230,29 @@ void OpenSSLRSADNSCryptoKeyEngine::create(unsigned int bits) throw runtime_error(getName()+" RSASHA512 key generation failed for invalid bits size " + std::to_string(bits)); } - BIGNUM *e = BN_new(); + auto e = std::unique_ptr(BN_new(), BN_clear_free); if (!e) { throw runtime_error(getName()+" key generation failed, unable to allocate e"); } /* RSA_F4 is a public exponent value of 65537 */ - int res = BN_set_word(e, RSA_F4); + int res = BN_set_word(e.get(), RSA_F4); if (res == 0) { - BN_free(e); throw runtime_error(getName()+" key generation failed while setting e"); } - RSA* key = RSA_new(); - if (key == NULL) { - BN_free(e); + auto key = std::unique_ptr(RSA_new(), RSA_free); + if (!key) { throw runtime_error(getName()+" allocation of key structure failed"); } - res = RSA_generate_key_ex(key, bits, e, NULL); - BN_free(e); + res = RSA_generate_key_ex(key.get(), bits, e.get(), nullptr); if (res == 0) { - RSA_free(key); throw runtime_error(getName()+" key generation failed"); } - if (d_key) - RSA_free(d_key); - - d_key = key; + d_key = std::move(key); } @@ -271,9 +262,9 @@ DNSCryptoKeyEngine::storvector_t OpenSSLRSADNSCryptoKeyEngine::convertToISCVecto typedef vector > outputs_t; outputs_t outputs; const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; - RSA_get0_key(d_key, &n, &e, &d); - RSA_get0_factors(d_key, &p, &q); - RSA_get0_crt_params(d_key, &dmp1, &dmq1, &iqmp); + RSA_get0_key(d_key.get(), &n, &e, &d); + RSA_get0_factors(d_key.get(), &p, &q); + RSA_get0_crt_params(d_key.get(), &dmp1, &dmq1, &iqmp); outputs.push_back(make_pair("Modulus", n)); outputs.push_back(make_pair("PublicExponent", e)); outputs.push_back(make_pair("PrivateExponent", d)); @@ -356,10 +347,10 @@ std::string OpenSSLRSADNSCryptoKeyEngine::sign(const std::string& msg) const string hash = this->hash(msg); int hashKind = hashSizeToKind(hash.size()); std::string signature; - signature.resize(RSA_size(d_key)); + signature.resize(RSA_size(d_key.get())); unsigned int signatureLen = 0; - int res = RSA_sign(hashKind, reinterpret_cast(&hash.at(0)), hash.length(), reinterpret_cast(&signature.at(0)), &signatureLen, d_key); + int res = RSA_sign(hashKind, reinterpret_cast(&hash.at(0)), hash.length(), reinterpret_cast(&signature.at(0)), &signatureLen, d_key.get()); if (res != 1) { throw runtime_error(getName()+" failed to generate signature"); } @@ -374,7 +365,7 @@ bool OpenSSLRSADNSCryptoKeyEngine::verify(const std::string& msg, const std::str string hash = this->hash(msg); int hashKind = hashSizeToKind(hash.size()); - int ret = RSA_verify(hashKind, (const unsigned char*) hash.c_str(), hash.length(), (unsigned char*) signature.c_str(), signature.length(), d_key); + int ret = RSA_verify(hashKind, (const unsigned char*) hash.c_str(), hash.length(), (unsigned char*) signature.c_str(), signature.length(), d_key.get()); return (ret == 1); } @@ -383,7 +374,7 @@ bool OpenSSLRSADNSCryptoKeyEngine::verify(const std::string& msg, const std::str std::string OpenSSLRSADNSCryptoKeyEngine::getPubKeyHash() const { const BIGNUM *n, *e, *d; - RSA_get0_key(d_key, &n, &e, &d); + RSA_get0_key(d_key.get(), &n, &e, &d); std::vector tmp; tmp.resize(std::max(BN_num_bytes(e), BN_num_bytes(n))); unsigned char hash[SHA_DIGEST_LENGTH]; @@ -419,7 +410,7 @@ std::string OpenSSLRSADNSCryptoKeyEngine::getPubKeyHash() const std::string OpenSSLRSADNSCryptoKeyEngine::getPublicKeyString() const { const BIGNUM *n, *e, *d; - RSA_get0_key(d_key, &n, &e, &d); + RSA_get0_key(d_key.get(), &n, &e, &d); string keystring; std::string tmp; tmp.resize(std::max(BN_num_bytes(e), BN_num_bytes(n))); @@ -446,64 +437,56 @@ void OpenSSLRSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map { typedef map places_t; places_t places; - RSA* key = RSA_new(); - if (key == NULL) { + auto key = std::unique_ptr(RSA_new(), RSA_free); + if (!key) { throw runtime_error(getName()+" allocation of key structure failed"); } BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; n = BN_new(); - if (n == NULL) { - RSA_free(key); + if (n == nullptr) { throw runtime_error(getName()+" allocation of BIGNUM n failed"); } e = BN_new(); - if (e == NULL) { - RSA_free(key); + if (e == nullptr) { BN_clear_free(n); throw runtime_error(getName()+" allocation of BIGNUM e failed"); } d = BN_new(); - if (d == NULL) { - RSA_free(key); + if (d == nullptr) { BN_clear_free(n); BN_clear_free(e); throw runtime_error(getName()+" allocation of BIGNUM d failed"); } - RSA_set0_key(key, n, e, d); + RSA_set0_key(key.get(), n, e, d); p = BN_new(); - if (p == NULL) { - RSA_free(key); + if (p == nullptr) { throw runtime_error(getName()+" allocation of BIGNUM p failed"); } q = BN_new(); - if (q == NULL) { - RSA_free(key); + if (q == nullptr) { BN_clear_free(p); throw runtime_error(getName()+" allocation of BIGNUM q failed"); } - RSA_set0_factors(key, p, q); + RSA_set0_factors(key.get(), p, q); dmp1 = BN_new(); - if (dmp1 == NULL) { - RSA_free(key); + if (dmp1 == nullptr) { throw runtime_error(getName()+" allocation of BIGNUM dmp1 failed"); } dmq1 = BN_new(); - if (dmq1 == NULL) { - RSA_free(key); + if (dmq1 == nullptr) { BN_clear_free(dmp1); throw runtime_error(getName()+" allocation of BIGNUM dmq1 failed"); } iqmp = BN_new(); - if (iqmp == NULL) { - RSA_free(key); + if (iqmp == nullptr) { BN_clear_free(dmq1); BN_clear_free(dmp1); throw runtime_error(getName()+" allocation of BIGNUM iqmp failed"); } - RSA_set0_crt_params(key, dmp1, dmq1, iqmp); + RSA_set0_crt_params(key.get(), dmp1, dmq1, iqmp); places["Modulus"]=&n; places["PublicExponent"]=&e; @@ -525,25 +508,20 @@ void OpenSSLRSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map *val.second = BN_bin2bn((unsigned char*) raw.c_str(), raw.length(), *val.second); if (!*val.second) { - RSA_free(key); throw runtime_error(getName()+" error loading " + val.first); } } if (drc.d_algorithm != d_algorithm) { - RSA_free(key); throw runtime_error(getName()+" tried to feed an algorithm "+std::to_string(drc.d_algorithm)+" to a "+std::to_string(d_algorithm)+" key"); } - if (d_key) - RSA_free(d_key); - - d_key = key; + d_key = std::move(key); } bool OpenSSLRSADNSCryptoKeyEngine::checkKey() const { - return (RSA_check_key(d_key) == 1); + return (RSA_check_key(d_key.get()) == 1); } void OpenSSLRSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& input) @@ -575,35 +553,29 @@ void OpenSSLRSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& input) modulus = input.substr(exponentSize + 3); } - RSA* key = RSA_new(); - if (key == NULL) { + auto key = std::unique_ptr(RSA_new(), RSA_free); + if (!key) { throw runtime_error(getName()+" allocation of key structure failed"); } - BIGNUM *e = BN_bin2bn((unsigned char*)exponent.c_str(), exponent.length(), NULL); + auto e = std::unique_ptr(BN_bin2bn((unsigned char*)exponent.c_str(), exponent.length(), nullptr), BN_clear_free); if (!e) { - RSA_free(key); throw runtime_error(getName()+" error loading e value of public key"); } - BIGNUM *n = BN_bin2bn((unsigned char*)modulus.c_str(), modulus.length(), NULL); + auto n = std::unique_ptr(BN_bin2bn((unsigned char*)modulus.c_str(), modulus.length(), nullptr), BN_clear_free); if (!n) { - RSA_free(key); - BN_clear_free(e); throw runtime_error(getName()+" error loading n value of public key"); } - if (d_key) - RSA_free(d_key); - - RSA_set0_key(key, n, e, NULL); - d_key = key; + RSA_set0_key(key.get(), n.release(), e.release(), nullptr); + d_key = std::move(key); } #ifdef HAVE_LIBCRYPTO_ECDSA class OpenSSLECDSADNSCryptoKeyEngine : public DNSCryptoKeyEngine { public: - explicit OpenSSLECDSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo) + explicit OpenSSLECDSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo), d_eckey(std::unique_ptr(EC_KEY_new(), EC_KEY_free)), d_ecgroup(std::unique_ptr(nullptr, EC_GROUP_clear_free)) { int ret = RAND_status(); @@ -611,41 +583,32 @@ public: throw runtime_error(getName()+" insufficient entropy"); } - d_eckey = EC_KEY_new(); - if (d_eckey == NULL) { + if (!d_eckey) { throw runtime_error(getName()+" allocation of key structure failed"); } if(d_algorithm == 13) { - d_ecgroup = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + d_ecgroup = std::unique_ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1), EC_GROUP_clear_free); d_len = 32; } else if (d_algorithm == 14) { - d_ecgroup = EC_GROUP_new_by_curve_name(NID_secp384r1); + d_ecgroup = std::unique_ptr(EC_GROUP_new_by_curve_name(NID_secp384r1), EC_GROUP_clear_free); d_len = 48; } else { - EC_KEY_free(d_eckey); throw runtime_error(getName()+" unknown algorithm "+std::to_string(d_algorithm)); } - if (d_ecgroup == NULL) { - EC_KEY_free(d_eckey); + if (!d_ecgroup) { throw runtime_error(getName()+" allocation of group structure failed"); } - ret = EC_KEY_set_group(d_eckey, d_ecgroup); + ret = EC_KEY_set_group(d_eckey.get(), d_ecgroup.get()); if (ret != 1) { - EC_KEY_free(d_eckey); - EC_GROUP_free(d_ecgroup); throw runtime_error(getName()+" setting key group failed"); } - } ~OpenSSLECDSADNSCryptoKeyEngine() { - EC_KEY_free(d_eckey); - EC_GROUP_free(d_ecgroup); - BN_CTX_free(d_ctx); } string getName() const override { return "OpenSSL ECDSA"; } @@ -670,9 +633,8 @@ public: private: unsigned int d_len; - EC_KEY *d_eckey = NULL; - EC_GROUP *d_ecgroup = NULL; - BN_CTX *d_ctx = NULL; + std::unique_ptr d_eckey; + std::unique_ptr d_ecgroup; }; @@ -682,7 +644,7 @@ void OpenSSLECDSADNSCryptoKeyEngine::create(unsigned int bits) throw runtime_error(getName()+" unknown key length of "+std::to_string(bits)+" bits requested"); } - int res = EC_KEY_generate_key(d_eckey); + int res = EC_KEY_generate_key(d_eckey.get()); if (res == 0) { throw runtime_error(getName()+" key generation failed"); } @@ -703,8 +665,8 @@ DNSCryptoKeyEngine::storvector_t OpenSSLECDSADNSCryptoKeyEngine::convertToISCVec storvect.push_back(make_pair("Algorithm", algorithm)); - const BIGNUM *key = EC_KEY_get0_private_key(d_eckey); - if (key == NULL) { + const BIGNUM *key = EC_KEY_get0_private_key(d_eckey.get()); + if (key == nullptr) { throw runtime_error(getName()+" private key not set"); } @@ -743,8 +705,8 @@ std::string OpenSSLECDSADNSCryptoKeyEngine::sign(const std::string& msg) const { string hash = this->hash(msg); - ECDSA_SIG *signature = ECDSA_do_sign((unsigned char*) hash.c_str(), hash.length(), d_eckey); - if (NULL == signature) { + auto signature = std::unique_ptr(ECDSA_do_sign((unsigned char*) hash.c_str(), hash.length(), d_eckey.get()), ECDSA_SIG_free); + if (!signature) { throw runtime_error(getName()+" failed to generate signature"); } @@ -753,7 +715,7 @@ std::string OpenSSLECDSADNSCryptoKeyEngine::sign(const std::string& msg) const tmp.resize(d_len); const BIGNUM *pr, *ps; - ECDSA_SIG_get0(signature, &pr, &ps); + ECDSA_SIG_get0(signature.get(), &pr, &ps); int len = BN_bn2bin(pr, reinterpret_cast(&tmp.at(0))); if (d_len - len) ret.append(d_len - len, 0x00); @@ -764,8 +726,6 @@ std::string OpenSSLECDSADNSCryptoKeyEngine::sign(const std::string& msg) const ret.append(d_len - len, 0x00); ret.append(&tmp.at(0), len); - ECDSA_SIG_free(signature); - return ret; } @@ -778,30 +738,19 @@ bool OpenSSLECDSADNSCryptoKeyEngine::verify(const std::string& msg, const std::s string hash = this->hash(msg); - ECDSA_SIG *sig; - sig = ECDSA_SIG_new(); - if (sig == NULL) { + auto sig = std::unique_ptr(ECDSA_SIG_new(), ECDSA_SIG_free); + if (!sig) { throw runtime_error(getName()+" allocation of signature structure failed"); } - BIGNUM *r, *s; - r = BN_bin2bn((unsigned char*) signature.c_str(), d_len, NULL); - s = BN_bin2bn((unsigned char*) signature.c_str() + d_len, d_len, NULL); + auto r = std::unique_ptr(BN_bin2bn((unsigned char*) signature.c_str(), d_len, nullptr), BN_clear_free); + auto s = std::unique_ptr(BN_bin2bn((unsigned char*) signature.c_str() + d_len, d_len, nullptr), BN_clear_free); if (!r || !s) { - if (r) { - BN_clear_free(r); - } - if (s) { - BN_clear_free(s); - } - ECDSA_SIG_free(sig); throw runtime_error(getName()+" invalid signature"); } - ECDSA_SIG_set0(sig, r, s); - int ret = ECDSA_do_verify((unsigned char*) hash.c_str(), hash.length(), sig, d_eckey); - - ECDSA_SIG_free(sig); + ECDSA_SIG_set0(sig.get(), r.release(), s.release()); + int ret = ECDSA_do_verify((unsigned char*) hash.c_str(), hash.length(), sig.get(), d_eckey.get()); if (ret == -1){ throw runtime_error(getName()+" verify error"); @@ -825,7 +774,7 @@ std::string OpenSSLECDSADNSCryptoKeyEngine::getPublicKeyString() const std::string binaryPoint; binaryPoint.resize((d_len * 2) + 1); - int ret = EC_POINT_point2oct(d_ecgroup, EC_KEY_get0_public_key(d_eckey), POINT_CONVERSION_UNCOMPRESSED, reinterpret_cast(&binaryPoint.at(0)), binaryPoint.size(), d_ctx); + int ret = EC_POINT_point2oct(d_ecgroup.get(), EC_KEY_get0_public_key(d_eckey.get()), POINT_CONVERSION_UNCOMPRESSED, reinterpret_cast(&binaryPoint.at(0)), binaryPoint.size(), nullptr); if (ret == 0) { throw runtime_error(getName()+" exporting point to binary failed"); } @@ -848,44 +797,35 @@ void OpenSSLECDSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::m string privateKey = stormap["privatekey"]; - BIGNUM *prv_key = BN_bin2bn((unsigned char*) privateKey.c_str(), privateKey.length(), NULL); - if (prv_key == NULL) { + auto prv_key = std::unique_ptr(BN_bin2bn((unsigned char*) privateKey.c_str(), privateKey.length(), nullptr), BN_clear_free); + if (!prv_key) { throw runtime_error(getName()+" reading private key from binary failed"); } - int ret = EC_KEY_set_private_key(d_eckey, prv_key); + int ret = EC_KEY_set_private_key(d_eckey.get(), prv_key.get()); if (ret != 1) { - BN_clear_free(prv_key); throw runtime_error(getName()+" setting private key failed"); } - EC_POINT *pub_key = EC_POINT_new(d_ecgroup); - if (pub_key == NULL) { - BN_clear_free(prv_key); + auto pub_key = std::unique_ptr(EC_POINT_new(d_ecgroup.get()), EC_POINT_free); + if (!pub_key) { throw runtime_error(getName()+" allocation of public key point failed"); } - ret = EC_POINT_mul(d_ecgroup, pub_key, prv_key, NULL, NULL, d_ctx); + ret = EC_POINT_mul(d_ecgroup.get(), pub_key.get(), prv_key.get(), nullptr, nullptr, nullptr); if (ret != 1) { - EC_POINT_free(pub_key); - BN_clear_free(prv_key); throw runtime_error(getName()+" computing public key from private failed"); } - BN_clear_free(prv_key); - - ret = EC_KEY_set_public_key(d_eckey, pub_key); + ret = EC_KEY_set_public_key(d_eckey.get(), pub_key.get()); if (ret != 1) { - EC_POINT_free(pub_key); throw runtime_error(getName()+" setting public key failed"); } - - EC_POINT_free(pub_key); } bool OpenSSLECDSADNSCryptoKeyEngine::checkKey() const { - return (EC_KEY_check_key(d_eckey) == 1); + return (EC_KEY_check_key(d_eckey.get()) == 1); } void OpenSSLECDSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& input) @@ -895,30 +835,25 @@ void OpenSSLECDSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& inpu string ecdsaPoint= "\x04"; ecdsaPoint.append(input); - EC_POINT *pub_key = EC_POINT_new(d_ecgroup); - if (pub_key == NULL) { + auto pub_key = std::unique_ptr(EC_POINT_new(d_ecgroup.get()), EC_POINT_free); + if (!pub_key) { throw runtime_error(getName()+" allocation of point structure failed"); } - int ret = EC_POINT_oct2point(d_ecgroup, pub_key, (unsigned char*) ecdsaPoint.c_str(), ecdsaPoint.length(), d_ctx); + int ret = EC_POINT_oct2point(d_ecgroup.get(), pub_key.get(), (unsigned char*) ecdsaPoint.c_str(), ecdsaPoint.length(), nullptr); if (ret != 1) { - EC_POINT_free(pub_key); throw runtime_error(getName()+" reading ECP point from binary failed"); } - ret = EC_KEY_set_private_key(d_eckey, NULL); + ret = EC_KEY_set_private_key(d_eckey.get(), nullptr); if (ret == 1) { - EC_POINT_free(pub_key); throw runtime_error(getName()+" setting private key failed"); } - ret = EC_KEY_set_public_key(d_eckey, pub_key); + ret = EC_KEY_set_public_key(d_eckey.get(), pub_key.get()); if (ret != 1) { - EC_POINT_free(pub_key); throw runtime_error(getName()+" setting public key failed"); } - - EC_POINT_free(pub_key); } #endif @@ -926,7 +861,7 @@ void OpenSSLECDSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& inpu class OpenSSLEDDSADNSCryptoKeyEngine : public DNSCryptoKeyEngine { public: - explicit OpenSSLEDDSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo) + explicit OpenSSLEDDSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo), d_edkey(std::unique_ptr(nullptr, EVP_PKEY_free)) { int ret = RAND_status(); @@ -934,11 +869,6 @@ public: throw runtime_error(getName()+" insufficient entropy"); } - d_edkey = EVP_PKEY_new(); - if (d_edkey == nullptr) { - throw runtime_error(getName()+" allocation of key structure failed"); - } - #ifdef HAVE_LIBCRYPTO_ED25519 if(d_algorithm == 15) { d_len = 32; @@ -952,14 +882,12 @@ public: } #endif if (d_len == 0) { - EVP_PKEY_free(d_edkey); throw runtime_error(getName()+" unknown algorithm "+std::to_string(d_algorithm)); } } ~OpenSSLEDDSADNSCryptoKeyEngine() { - EVP_PKEY_free(d_edkey); } string getName() const override { return "OpenSSL EDDSA"; } @@ -984,29 +912,28 @@ private: size_t d_len{0}; int d_id{0}; - EVP_PKEY *d_edkey = nullptr; + std::unique_ptr d_edkey; }; bool OpenSSLEDDSADNSCryptoKeyEngine::checkKey() const { - return (d_edkey != nullptr); + return (d_edkey ? true : false); } void OpenSSLEDDSADNSCryptoKeyEngine::create(unsigned int bits) { - auto pctx = EVP_PKEY_CTX_new_id(d_id, nullptr); - if (pctx == nullptr) { + auto pctx = std::unique_ptr(EVP_PKEY_CTX_new_id(d_id, nullptr), EVP_PKEY_CTX_free); + if (!pctx) { throw runtime_error(getName()+" context initialization failed"); } - if (EVP_PKEY_keygen_init(pctx) < 1) { - EVP_PKEY_CTX_free(pctx); + if (EVP_PKEY_keygen_init(pctx.get()) < 1) { throw runtime_error(getName()+" keygen initialization failed"); } - if (EVP_PKEY_keygen(pctx, &d_edkey) < 1) { - EVP_PKEY_CTX_free(pctx); + EVP_PKEY* newKey = nullptr; + if (EVP_PKEY_keygen(pctx.get(), &newKey) < 1) { throw runtime_error(getName()+" key generation failed"); } - EVP_PKEY_CTX_free(pctx); + d_edkey = std::unique_ptr(newKey, EVP_PKEY_free); } DNSCryptoKeyEngine::storvector_t OpenSSLEDDSADNSCryptoKeyEngine::convertToISCVector() const @@ -1033,7 +960,7 @@ DNSCryptoKeyEngine::storvector_t OpenSSLEDDSADNSCryptoKeyEngine::convertToISCVec string buf; size_t len = d_len; buf.resize(len); - if (EVP_PKEY_get_raw_private_key(d_edkey, reinterpret_cast(&buf.at(0)), &len) < 1) { + if (EVP_PKEY_get_raw_private_key(d_edkey.get(), reinterpret_cast(&buf.at(0)), &len) < 1) { throw runtime_error(getName() + " Could not get private key from d_edkey"); } storvect.push_back(make_pair("PrivateKey", buf)); @@ -1042,12 +969,11 @@ DNSCryptoKeyEngine::storvector_t OpenSSLEDDSADNSCryptoKeyEngine::convertToISCVec std::string OpenSSLEDDSADNSCryptoKeyEngine::sign(const std::string& msg) const { - auto mdctx = EVP_MD_CTX_new(); - if (mdctx == nullptr) { + auto mdctx = std::unique_ptr(EVP_MD_CTX_new(), EVP_MD_CTX_free); + if (!mdctx) { throw runtime_error(getName()+" MD context initialization failed"); } - if(EVP_DigestSignInit(mdctx, nullptr, nullptr, nullptr, d_edkey) < 1) { - EVP_MD_CTX_free(mdctx); + if(EVP_DigestSignInit(mdctx.get(), nullptr, nullptr, nullptr, d_edkey.get()) < 1) { throw runtime_error(getName()+" unable to initialize signer"); } @@ -1057,39 +983,35 @@ std::string OpenSSLEDDSADNSCryptoKeyEngine::sign(const std::string& msg) const string signature; signature.resize(siglen); - if (EVP_DigestSign(mdctx, + if (EVP_DigestSign(mdctx.get(), reinterpret_cast(&signature.at(0)), &siglen, reinterpret_cast(&msgToSign.at(0)), msgToSign.length()) < 1) { - EVP_MD_CTX_free(mdctx); throw runtime_error(getName()+" signing error"); } - EVP_MD_CTX_free(mdctx); + return signature; } bool OpenSSLEDDSADNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const { - auto mdctx = EVP_MD_CTX_new(); - if (mdctx == nullptr) { + auto mdctx = std::unique_ptr(EVP_MD_CTX_new(), EVP_MD_CTX_free); + if (!mdctx) { throw runtime_error(getName()+" MD context initialization failed"); } - if(EVP_DigestVerifyInit(mdctx, nullptr, nullptr, nullptr, d_edkey) < 1) { - EVP_MD_CTX_free(mdctx); + if(EVP_DigestVerifyInit(mdctx.get(), nullptr, nullptr, nullptr, d_edkey.get()) < 1) { throw runtime_error(getName()+" unable to initialize signer"); } string checkSignature = signature; string checkMsg = msg; - auto r = EVP_DigestVerify(mdctx, + auto r = EVP_DigestVerify(mdctx.get(), reinterpret_cast(&checkSignature.at(0)), checkSignature.length(), reinterpret_cast(&checkMsg.at(0)), checkMsg.length()); if (r < 0) { - EVP_MD_CTX_free(mdctx); throw runtime_error(getName()+" verification failure"); } - EVP_MD_CTX_free(mdctx); return (r == 1); } @@ -1103,7 +1025,7 @@ std::string OpenSSLEDDSADNSCryptoKeyEngine::getPublicKeyString() const string buf; size_t len = d_len; buf.resize(len); - if (EVP_PKEY_get_raw_public_key(d_edkey, reinterpret_cast(&buf.at(0)), &len) < 1) { + if (EVP_PKEY_get_raw_public_key(d_edkey.get(), reinterpret_cast(&buf.at(0)), &len) < 1) { throw std::runtime_error(getName() + " unable to get public key from key struct"); } return buf; @@ -1115,8 +1037,8 @@ void OpenSSLEDDSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::m throw runtime_error(getName()+" tried to feed an algorithm "+std::to_string(drc.d_algorithm)+" to a "+std::to_string(d_algorithm)+" key"); } - d_edkey = EVP_PKEY_new_raw_private_key(d_id, nullptr, reinterpret_cast(&stormap["privatekey"].at(0)), stormap["privatekey"].length()); - if (d_edkey == nullptr) { + d_edkey = std::unique_ptr(EVP_PKEY_new_raw_private_key(d_id, nullptr, reinterpret_cast(&stormap["privatekey"].at(0)), stormap["privatekey"].length()), EVP_PKEY_free); + if (!d_edkey) { throw std::runtime_error(getName() + " could not create key structure from private key"); } } @@ -1129,8 +1051,8 @@ void OpenSSLEDDSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& cont const unsigned char* raw = reinterpret_cast(content.c_str()); - d_edkey = EVP_PKEY_new_raw_public_key(d_id, nullptr, raw, d_len); - if (d_edkey == nullptr) { + d_edkey = std::unique_ptr(EVP_PKEY_new_raw_public_key(d_id, nullptr, raw, d_len), EVP_PKEY_free); + if (!d_edkey) { throw runtime_error(getName()+" allocation of public key structure failed"); } }