mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-21 06:37:42 +01:00
fix incomplete EC key creation from curve name; make sure tests use curves that exist; add validation checks on EC key creation
This commit is contained in:
parent
ba5af017cc
commit
8fff0cf586
@ -78,7 +78,16 @@ public:
|
||||
|
||||
ECKeyImpl::Ptr impl() const;
|
||||
/// Returns the impl object.
|
||||
|
||||
|
||||
static std::string getCurveName(int nid = -1);
|
||||
/// Returns elliptical curve name corresponding to
|
||||
/// the given nid; if nid is not found, returns
|
||||
/// empty string.
|
||||
///
|
||||
/// If nid is -1, returns first curve name.
|
||||
///
|
||||
/// If no curves are found, returns empty string;
|
||||
|
||||
private:
|
||||
ECKeyImpl::Ptr _pImpl;
|
||||
};
|
||||
@ -93,6 +102,12 @@ inline ECKeyImpl::Ptr ECKey::impl() const
|
||||
}
|
||||
|
||||
|
||||
inline std::string ECKey::getCurveName(int nid)
|
||||
{
|
||||
return ECKeyImpl::getCurveName(nid);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Crypto
|
||||
|
||||
|
||||
|
@ -104,7 +104,17 @@ public:
|
||||
/// If a null pointer is passed for a stream, the corresponding
|
||||
/// key is not exported.
|
||||
|
||||
static std::string getCurveName(int nid = -1);
|
||||
/// Returns elliptical curve name corresponding to
|
||||
/// the given nid; if nid is not found, returns
|
||||
/// empty string.
|
||||
///
|
||||
/// If nid is -1, returns first curve name.
|
||||
///
|
||||
/// If no curves are found, returns empty string;
|
||||
|
||||
private:
|
||||
void checkEC(const std::string& method, const std::string& func) const;
|
||||
void freeEC();
|
||||
|
||||
EC_KEY* _pEC;
|
||||
|
@ -194,7 +194,11 @@ private:
|
||||
*ppKey = (K*)getFunc(pKey);
|
||||
EVP_PKEY_free(pKey);
|
||||
}
|
||||
else *ppKey = (K*)pKey;
|
||||
else
|
||||
{
|
||||
poco_assert_dbg (typeid(K*) == typeid(EVP_PKEY*));
|
||||
*ppKey = (K*)pKey;
|
||||
}
|
||||
if(!*ppKey) goto error;
|
||||
return true;
|
||||
}
|
||||
@ -250,7 +254,11 @@ private:
|
||||
*ppKey = (K*)getFunc(pKey);
|
||||
EVP_PKEY_free(pKey);
|
||||
}
|
||||
else *ppKey = (K*)pKey;
|
||||
else
|
||||
{
|
||||
poco_assert_dbg (typeid(K*) == typeid(EVP_PKEY*));
|
||||
*ppKey = (K*)pKey;
|
||||
}
|
||||
if (!*ppKey) goto error;
|
||||
return true;
|
||||
}
|
||||
@ -278,12 +286,12 @@ private:
|
||||
// inlines
|
||||
//
|
||||
|
||||
|
||||
inline bool EVPPKey::operator == (const EVPPKey& other) const
|
||||
{
|
||||
poco_assert_dbg(other._pEVPPKey && _pEVPPKey);
|
||||
int r = EVP_PKEY_cmp(_pEVPPKey, other._pEVPPKey);
|
||||
if (r < 0) throw OpenSSLException("EVPPKey::operator ==()");
|
||||
return (1 == r);
|
||||
poco_check_ptr (other._pEVPPKey);
|
||||
poco_check_ptr (_pEVPPKey);
|
||||
return (1 == EVP_PKEY_cmp(_pEVPPKey, other._pEVPPKey));
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "Poco/Crypto/X509Certificate.h"
|
||||
#include "Poco/Crypto/PKCS12Container.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include <sstream>
|
||||
#include <openssl/evp.h>
|
||||
@ -33,7 +34,7 @@ ECKeyImpl::ECKeyImpl(const EVPPKey& key):
|
||||
KeyPairImpl("ec", KT_EC_IMPL),
|
||||
_pEC(EVP_PKEY_get1_EC_KEY(const_cast<EVP_PKEY*>((const EVP_PKEY*)key)))
|
||||
{
|
||||
if (!_pEC) throw OpenSSLException("ECKeyImpl(const EVPPKey&)");
|
||||
checkEC("ECKeyImpl(const EVPPKey&)", "EVP_PKEY_get1_EC_KEY()");
|
||||
}
|
||||
|
||||
|
||||
@ -49,6 +50,7 @@ ECKeyImpl::ECKeyImpl(const X509Certificate& cert):
|
||||
{
|
||||
_pEC = EVP_PKEY_get1_EC_KEY(pKey);
|
||||
EVP_PKEY_free(pKey);
|
||||
checkEC("ECKeyImpl(const const X509Certificate&)", "EVP_PKEY_get1_EC_KEY()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -60,7 +62,7 @@ ECKeyImpl::ECKeyImpl(const PKCS12Container& cont):
|
||||
KeyPairImpl("ec", KT_EC_IMPL),
|
||||
_pEC(EVP_PKEY_get1_EC_KEY(cont.getKey()))
|
||||
{
|
||||
if (!_pEC) throw OpenSSLException();
|
||||
checkEC("ECKeyImpl(const PKCS12Container&)", "EVP_PKEY_get1_EC_KEY()");
|
||||
}
|
||||
|
||||
|
||||
@ -68,8 +70,11 @@ ECKeyImpl::ECKeyImpl(int curve):
|
||||
KeyPairImpl("ec", KT_EC_IMPL),
|
||||
_pEC(EC_KEY_new_by_curve_name(curve))
|
||||
{
|
||||
if (!EC_KEY_generate_key(_pEC))
|
||||
throw OpenSSLException("ECKeyImpl(int)");
|
||||
poco_check_ptr(_pEC);
|
||||
EC_KEY_set_asn1_flag(_pEC, OPENSSL_EC_NAMED_CURVE);
|
||||
if (!(EC_KEY_generate_key(_pEC)))
|
||||
throw OpenSSLException("ECKeyImpl(int curve): EC_KEY_generate_key()");
|
||||
checkEC("ECKeyImpl(int curve)", "EC_KEY_generate_key()");
|
||||
}
|
||||
|
||||
|
||||
@ -78,13 +83,21 @@ ECKeyImpl::ECKeyImpl(const std::string& publicKeyFile,
|
||||
const std::string& privateKeyPassphrase): KeyPairImpl("ec", KT_EC_IMPL), _pEC(0)
|
||||
{
|
||||
if (EVPPKey::loadKey(&_pEC, PEM_read_PrivateKey, EVP_PKEY_get1_EC_KEY, privateKeyFile, privateKeyPassphrase))
|
||||
{
|
||||
checkEC(Poco::format("ECKeyImpl(%s, %s, %s)",
|
||||
publicKeyFile, privateKeyFile, privateKeyPassphrase.empty() ? "" : "***"),
|
||||
"PEM_read_PrivateKey() or EVP_PKEY_get1_EC_KEY()");
|
||||
return; // private key is enough
|
||||
}
|
||||
|
||||
// no private key, this must be public key only, otherwise throw
|
||||
if (!EVPPKey::loadKey(&_pEC, PEM_read_PUBKEY, EVP_PKEY_get1_EC_KEY, publicKeyFile))
|
||||
{
|
||||
throw OpenSSLException("ECKeyImpl(const string&, const string&, const string&");
|
||||
}
|
||||
checkEC(Poco::format("ECKeyImpl(%s, %s, %s)",
|
||||
publicKeyFile, privateKeyFile, privateKeyPassphrase.empty() ? "" : "***"),
|
||||
"PEM_read_PUBKEY() or EVP_PKEY_get1_EC_KEY()");
|
||||
}
|
||||
|
||||
|
||||
@ -93,13 +106,21 @@ ECKeyImpl::ECKeyImpl(std::istream* pPublicKeyStream,
|
||||
const std::string& privateKeyPassphrase): KeyPairImpl("ec", KT_EC_IMPL), _pEC(0)
|
||||
{
|
||||
if (EVPPKey::loadKey(&_pEC, PEM_read_bio_PrivateKey, EVP_PKEY_get1_EC_KEY, pPrivateKeyStream, privateKeyPassphrase))
|
||||
{
|
||||
checkEC(Poco::format("ECKeyImpl(stream, stream, %s)",
|
||||
privateKeyPassphrase.empty() ? "" : "***"),
|
||||
"PEM_read_bio_PrivateKey() or EVP_PKEY_get1_EC_KEY()");
|
||||
return; // private key is enough
|
||||
}
|
||||
|
||||
// no private key, this must be public key only, otherwise throw
|
||||
if (!EVPPKey::loadKey(&_pEC, PEM_read_bio_PUBKEY, EVP_PKEY_get1_EC_KEY, pPublicKeyStream))
|
||||
{
|
||||
throw OpenSSLException("ECKeyImpl(istream*, istream*, const string&");
|
||||
}
|
||||
checkEC(Poco::format("ECKeyImpl(stream, stream, %s)",
|
||||
privateKeyPassphrase.empty() ? "" : "***"),
|
||||
"PEM_read_bio_PUBKEY() or EVP_PKEY_get1_EC_KEY()");
|
||||
}
|
||||
|
||||
|
||||
@ -109,6 +130,14 @@ ECKeyImpl::~ECKeyImpl()
|
||||
}
|
||||
|
||||
|
||||
void ECKeyImpl::checkEC(const std::string& method, const std::string& func) const
|
||||
{
|
||||
if (!_pEC) throw OpenSSLException(Poco::format("%s: %s", method, func));
|
||||
if (!EC_KEY_check_key(_pEC))
|
||||
throw OpenSSLException(Poco::format("%s: EC_KEY_check_key()", method));
|
||||
}
|
||||
|
||||
|
||||
void ECKeyImpl::freeEC()
|
||||
{
|
||||
if (_pEC)
|
||||
@ -151,4 +180,28 @@ int ECKeyImpl::groupId() const
|
||||
}
|
||||
|
||||
|
||||
std::string ECKeyImpl::getCurveName(int nid)
|
||||
{
|
||||
std::string curveName;
|
||||
size_t len = EC_get_builtin_curves(NULL, 0);
|
||||
EC_builtin_curve* pCurves =
|
||||
(EC_builtin_curve*) OPENSSL_malloc(sizeof(EC_builtin_curve) * len);
|
||||
if (!pCurves) return curveName;
|
||||
|
||||
if (!EC_get_builtin_curves(pCurves, len))
|
||||
{
|
||||
OPENSSL_free(pCurves);
|
||||
return curveName;
|
||||
}
|
||||
|
||||
if (-1 == nid) nid = pCurves[0].nid;
|
||||
int bufLen = 128;
|
||||
char buf[bufLen] = {0};
|
||||
OBJ_obj2txt(buf, bufLen, OBJ_nid2obj(nid), 0);
|
||||
curveName = buf;
|
||||
OPENSSL_free(pCurves);
|
||||
return curveName;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Crypto
|
||||
|
@ -37,24 +37,30 @@ void ECTest::testECNewKeys()
|
||||
{
|
||||
try
|
||||
{
|
||||
ECKey key("secp521r1");
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv, "testpwd");
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
ECKey key(curveName);
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv, "testpwd");
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
ECKey key2(&iPub, &iPriv, "testpwd");
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
ECKey key2(&iPub, &iPriv, "testpwd");
|
||||
|
||||
std::istringstream iPriv2(privKey);
|
||||
ECKey key3(0, &iPriv2, "testpwd");
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
std::istringstream iPriv2(privKey);
|
||||
ECKey key3(0, &iPriv2, "testpwd");
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -68,24 +74,30 @@ void ECTest::testECNewKeysNoPassphrase()
|
||||
{
|
||||
try
|
||||
{
|
||||
ECKey key("secp521r1");
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv);
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
ECKey key(curveName);
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv);
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
ECKey key2(&iPub, &iPriv);
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
ECKey key2(&iPub, &iPriv);
|
||||
|
||||
std::istringstream iPriv2(privKey);
|
||||
ECKey key3(0, &iPriv2);
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
std::istringstream iPriv2(privKey);
|
||||
ECKey key3(0, &iPriv2);
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -99,21 +111,27 @@ void ECTest::testECDSASignSha256()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string msg("Test this sign message");
|
||||
ECKey key("secp521r1");
|
||||
ECDSADigestEngine eng(key, "SHA256");
|
||||
eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
|
||||
const Poco::DigestEngine::Digest& sig = eng.signature();
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
std::string msg("Test this sign message");
|
||||
ECKey key(curveName);
|
||||
ECDSADigestEngine eng(key, "SHA256");
|
||||
eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
|
||||
const Poco::DigestEngine::Digest& sig = eng.signature();
|
||||
|
||||
// verify
|
||||
std::ostringstream strPub;
|
||||
key.save(&strPub);
|
||||
std::string pubKey = strPub.str();
|
||||
std::istringstream iPub(pubKey);
|
||||
ECKey keyPub(&iPub);
|
||||
ECDSADigestEngine eng2(keyPub, "SHA256");
|
||||
eng2.update(msg.c_str(), static_cast<unsigned>(msg.length()));
|
||||
assert(eng2.verify(sig));
|
||||
// verify
|
||||
std::ostringstream strPub;
|
||||
key.save(&strPub);
|
||||
std::string pubKey = strPub.str();
|
||||
std::istringstream iPub(pubKey);
|
||||
ECKey keyPub(&iPub);
|
||||
ECDSADigestEngine eng2(keyPub, "SHA256");
|
||||
eng2.update(msg.c_str(), static_cast<unsigned>(msg.length()));
|
||||
assert(eng2.verify(sig));
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -127,23 +145,29 @@ void ECTest::testECDSASignManipulated()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string msg("Test this sign message");
|
||||
std::string msgManip("Test that sign message");
|
||||
ECKey key("secp521r1");
|
||||
ECDSADigestEngine eng(key, "SHA256");
|
||||
eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
|
||||
const Poco::DigestEngine::Digest& sig = eng.signature();
|
||||
std::string hexDig = Poco::DigestEngine::digestToHex(sig);
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
std::string msg("Test this sign message");
|
||||
std::string msgManip("Test that sign message");
|
||||
ECKey key(curveName);
|
||||
ECDSADigestEngine eng(key, "SHA256");
|
||||
eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
|
||||
const Poco::DigestEngine::Digest& sig = eng.signature();
|
||||
std::string hexDig = Poco::DigestEngine::digestToHex(sig);
|
||||
|
||||
// verify
|
||||
std::ostringstream strPub;
|
||||
key.save(&strPub);
|
||||
std::string pubKey = strPub.str();
|
||||
std::istringstream iPub(pubKey);
|
||||
ECKey keyPub(&iPub);
|
||||
ECDSADigestEngine eng2(keyPub, "SHA256");
|
||||
eng2.update(msgManip.c_str(), static_cast<unsigned>(msgManip.length()));
|
||||
assert (!eng2.verify(sig));
|
||||
// verify
|
||||
std::ostringstream strPub;
|
||||
key.save(&strPub);
|
||||
std::string pubKey = strPub.str();
|
||||
std::istringstream iPub(pubKey);
|
||||
ECKey keyPub(&iPub);
|
||||
ECDSADigestEngine eng2(keyPub, "SHA256");
|
||||
eng2.update(msgManip.c_str(), static_cast<unsigned>(msgManip.length()));
|
||||
assert (!eng2.verify(sig));
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
|
@ -217,85 +217,91 @@ void EVPTest::testECEVPPKey()
|
||||
{
|
||||
try
|
||||
{
|
||||
EVPPKey* pKey = new EVPPKey("secp521r1");
|
||||
assert (pKey != 0);
|
||||
assert (!pKey->isSupported(0));
|
||||
assert (!pKey->isSupported(-1));
|
||||
assert (pKey->isSupported(pKey->type()));
|
||||
assert (pKey->type() == EVP_PKEY_EC);
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
EVPPKey* pKey = new EVPPKey(curveName);
|
||||
assert (pKey != 0);
|
||||
assert (!pKey->isSupported(0));
|
||||
assert (!pKey->isSupported(-1));
|
||||
assert (pKey->isSupported(pKey->type()));
|
||||
assert (pKey->type() == EVP_PKEY_EC);
|
||||
|
||||
BIO* bioPriv1 = BIO_new(BIO_s_mem());
|
||||
BIO* bioPub1 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv1, *pKey, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub1, *pKey));
|
||||
char* pPrivData1;
|
||||
long sizePriv1 = BIO_get_mem_data(bioPriv1, &pPrivData1);
|
||||
char* pPubData1;
|
||||
long sizePub1 = BIO_get_mem_data(bioPub1, &pPubData1);
|
||||
BIO* bioPriv1 = BIO_new(BIO_s_mem());
|
||||
BIO* bioPub1 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv1, *pKey, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub1, *pKey));
|
||||
char* pPrivData1;
|
||||
long sizePriv1 = BIO_get_mem_data(bioPriv1, &pPrivData1);
|
||||
char* pPubData1;
|
||||
long sizePub1 = BIO_get_mem_data(bioPub1, &pPubData1);
|
||||
|
||||
// construct EVPPKey from EVP_PKEY*
|
||||
EVPPKey evpPKey(pKey->operator EVP_PKEY*());
|
||||
assert (evpPKey.type() == EVP_PKEY_EC);
|
||||
// EVPPKey makes duplicate, so freeing the original must be ok
|
||||
delete pKey;
|
||||
// construct EVPPKey from EVP_PKEY*
|
||||
EVPPKey evpPKey(pKey->operator EVP_PKEY*());
|
||||
assert (evpPKey.type() == EVP_PKEY_EC);
|
||||
// EVPPKey makes duplicate, so freeing the original must be ok
|
||||
delete pKey;
|
||||
|
||||
BIO* bioPriv2 = BIO_new(BIO_s_mem());
|
||||
BIO* bioPub2 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv2, evpPKey, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub2, evpPKey));
|
||||
char* pPrivData2;
|
||||
long sizePriv2 = BIO_get_mem_data(bioPriv2, &pPrivData2);
|
||||
char* pPubData2;
|
||||
long sizePub2 = BIO_get_mem_data(bioPub2, &pPubData2);
|
||||
BIO* bioPriv2 = BIO_new(BIO_s_mem());
|
||||
BIO* bioPub2 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv2, evpPKey, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub2, evpPKey));
|
||||
char* pPrivData2;
|
||||
long sizePriv2 = BIO_get_mem_data(bioPriv2, &pPrivData2);
|
||||
char* pPubData2;
|
||||
long sizePub2 = BIO_get_mem_data(bioPub2, &pPubData2);
|
||||
|
||||
assert (sizePriv1 && (sizePriv1 == sizePriv2));
|
||||
assert (0 == memcmp(pPrivData1, pPrivData2, sizePriv1));
|
||||
assert (sizePub1 && (sizePub1 == sizePub2));
|
||||
assert (0 == memcmp(pPubData1, pPubData2, sizePub1));
|
||||
assert (sizePriv1 && (sizePriv1 == sizePriv2));
|
||||
assert (0 == memcmp(pPrivData1, pPrivData2, sizePriv1));
|
||||
assert (sizePub1 && (sizePub1 == sizePub2));
|
||||
assert (0 == memcmp(pPubData1, pPubData2, sizePub1));
|
||||
|
||||
BIO_free(bioPub2);
|
||||
BIO_free(bioPriv2);
|
||||
BIO_free(bioPub2);
|
||||
BIO_free(bioPriv2);
|
||||
|
||||
// copy
|
||||
EVPPKey evpPKey2(evpPKey);
|
||||
assert (evpPKey2.type() == EVP_PKEY_EC);
|
||||
bioPriv2 = BIO_new(BIO_s_mem());
|
||||
bioPub2 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv2, evpPKey2, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub2, evpPKey2));
|
||||
sizePriv2 = BIO_get_mem_data(bioPriv2, &pPrivData2);
|
||||
sizePub2 = BIO_get_mem_data(bioPub2, &pPubData2);
|
||||
// copy
|
||||
EVPPKey evpPKey2(evpPKey);
|
||||
assert (evpPKey2.type() == EVP_PKEY_EC);
|
||||
bioPriv2 = BIO_new(BIO_s_mem());
|
||||
bioPub2 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv2, evpPKey2, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub2, evpPKey2));
|
||||
sizePriv2 = BIO_get_mem_data(bioPriv2, &pPrivData2);
|
||||
sizePub2 = BIO_get_mem_data(bioPub2, &pPubData2);
|
||||
|
||||
assert (sizePriv1 && (sizePriv1 == sizePriv2));
|
||||
assert (0 == memcmp(pPrivData1, pPrivData2, sizePriv1));
|
||||
assert (sizePub1 && (sizePub1 == sizePub2));
|
||||
assert (0 == memcmp(pPubData1, pPubData2, sizePub1));
|
||||
assert (sizePriv1 && (sizePriv1 == sizePriv2));
|
||||
assert (0 == memcmp(pPrivData1, pPrivData2, sizePriv1));
|
||||
assert (sizePub1 && (sizePub1 == sizePub2));
|
||||
assert (0 == memcmp(pPubData1, pPubData2, sizePub1));
|
||||
|
||||
#ifdef POCO_ENABLE_CPP11
|
||||
#ifdef POCO_ENABLE_CPP11
|
||||
|
||||
BIO_free(bioPub2);
|
||||
BIO_free(bioPriv2);
|
||||
BIO_free(bioPub2);
|
||||
BIO_free(bioPriv2);
|
||||
|
||||
// move
|
||||
EVPPKey evpPKey3(std::move(evpPKey2));
|
||||
assert (evpPKey3.type() == EVP_PKEY_EC);
|
||||
bioPriv2 = BIO_new(BIO_s_mem());
|
||||
bioPub2 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv2, evpPKey3, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub2, evpPKey3));
|
||||
sizePriv2 = BIO_get_mem_data(bioPriv2, &pPrivData2);
|
||||
sizePub2 = BIO_get_mem_data(bioPub2, &pPubData2);
|
||||
// move
|
||||
EVPPKey evpPKey3(std::move(evpPKey2));
|
||||
assert (evpPKey3.type() == EVP_PKEY_EC);
|
||||
bioPriv2 = BIO_new(BIO_s_mem());
|
||||
bioPub2 = BIO_new(BIO_s_mem());
|
||||
assert (0 != PEM_write_bio_PrivateKey(bioPriv2, evpPKey3, NULL, NULL, 0, 0, NULL));
|
||||
assert (0 != PEM_write_bio_PUBKEY(bioPub2, evpPKey3));
|
||||
sizePriv2 = BIO_get_mem_data(bioPriv2, &pPrivData2);
|
||||
sizePub2 = BIO_get_mem_data(bioPub2, &pPubData2);
|
||||
|
||||
assert (sizePriv1 && (sizePriv1 == sizePriv2));
|
||||
assert (0 == memcmp(pPrivData1, pPrivData2, sizePriv1));
|
||||
assert (sizePub1 && (sizePub1 == sizePub2));
|
||||
assert (0 == memcmp(pPubData1, pPubData2, sizePub1));
|
||||
#endif // POCO_ENABLE_CPP11
|
||||
assert (sizePriv1 && (sizePriv1 == sizePriv2));
|
||||
assert (0 == memcmp(pPrivData1, pPrivData2, sizePriv1));
|
||||
assert (sizePub1 && (sizePub1 == sizePub2));
|
||||
assert (0 == memcmp(pPubData1, pPubData2, sizePub1));
|
||||
#endif // POCO_ENABLE_CPP11
|
||||
|
||||
BIO_free(bioPub2);
|
||||
BIO_free(bioPriv2);
|
||||
BIO_free(bioPub1);
|
||||
BIO_free(bioPriv1);
|
||||
BIO_free(bioPub2);
|
||||
BIO_free(bioPriv2);
|
||||
BIO_free(bioPub1);
|
||||
BIO_free(bioPriv1);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -309,43 +315,48 @@ void EVPTest::testECEVPSaveLoadStream()
|
||||
{
|
||||
try
|
||||
{
|
||||
EVPPKey key("secp521r1");
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv, "testpwd");
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
EVPPKey key(curveName);
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv, "testpwd");
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
EVPPKey key2(&iPub, &iPriv, "testpwd");
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
EVPPKey key2(&iPub, &iPriv, "testpwd");
|
||||
|
||||
std::ostringstream strPubE;
|
||||
std::ostringstream strPrivE;
|
||||
key2.save(&strPubE, &strPrivE, "testpwd");
|
||||
assert (strPubE.str() == pubKey);
|
||||
/*TODO: figure out why EVP_PKEY_cmp() fails for identical public keys
|
||||
assert (key == key2);
|
||||
assert (!(key != key2));*/
|
||||
ECKey ecKeyNE("secp112r2");
|
||||
EVPPKey keyNE(&ecKeyNE);
|
||||
assert (key != keyNE);
|
||||
assert (!(key == keyNE));
|
||||
assert (key2 != keyNE);
|
||||
assert (!(key2 == keyNE));
|
||||
std::ostringstream strPubE;
|
||||
std::ostringstream strPrivE;
|
||||
key2.save(&strPubE, &strPrivE, "testpwd");
|
||||
assert (strPubE.str() == pubKey);
|
||||
assert (key == key2);
|
||||
assert (!(key != key2));
|
||||
ECKey ecKeyNE("secp112r2");
|
||||
EVPPKey keyNE(&ecKeyNE);
|
||||
assert (key != keyNE);
|
||||
assert (!(key == keyNE));
|
||||
assert (key2 != keyNE);
|
||||
assert (!(key2 == keyNE));
|
||||
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2, "testpwd");
|
||||
assert (strPub2.str() == pubKey);
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2, "testpwd");
|
||||
assert (strPub2.str() == pubKey);
|
||||
|
||||
std::istringstream iPriv2(strPriv2.str());
|
||||
EVPPKey key3(0, &iPriv2, "testpwd");
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
std::istringstream iPriv2(strPriv2.str());
|
||||
EVPPKey key3(0, &iPriv2, "testpwd");
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -359,44 +370,49 @@ void EVPTest::testECEVPSaveLoadStreamNoPass()
|
||||
{
|
||||
try
|
||||
{
|
||||
EVPPKey key("secp521r1");
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv);
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
EVPPKey key(curveName);
|
||||
std::ostringstream strPub;
|
||||
std::ostringstream strPriv;
|
||||
key.save(&strPub, &strPriv);
|
||||
std::string pubKey = strPub.str();
|
||||
std::string privKey = strPriv.str();
|
||||
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
EVPPKey key2(&iPub, &iPriv);
|
||||
// now do the round trip
|
||||
std::istringstream iPub(pubKey);
|
||||
std::istringstream iPriv(privKey);
|
||||
EVPPKey key2(&iPub, &iPriv);
|
||||
|
||||
std::ostringstream strPubE;
|
||||
std::ostringstream strPrivE;
|
||||
key2.save(&strPubE, &strPrivE);
|
||||
assert (strPubE.str() == pubKey);
|
||||
/*TODO: figure out why EVP_PKEY_cmp() fails for identical public keys
|
||||
assert (key == key2);
|
||||
assert (!(key != key2));*/
|
||||
ECKey ecKeyNE("secp112r2");
|
||||
EVPPKey keyNE(&ecKeyNE);
|
||||
assert (key != keyNE);
|
||||
assert (!(key == keyNE));
|
||||
assert (key2 != keyNE);
|
||||
assert (!(key2 == keyNE));
|
||||
std::ostringstream strPubE;
|
||||
std::ostringstream strPrivE;
|
||||
key2.save(&strPubE, &strPrivE);
|
||||
assert (strPubE.str() == pubKey);
|
||||
assert (key == key2);
|
||||
assert (!(key != key2));
|
||||
ECKey ecKeyNE("secp112r2");
|
||||
EVPPKey keyNE(&ecKeyNE);
|
||||
assert (key != keyNE);
|
||||
assert (!(key == keyNE));
|
||||
assert (key2 != keyNE);
|
||||
assert (!(key2 == keyNE));
|
||||
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2);
|
||||
assert (strPub2.str() == pubKey);
|
||||
assert (strPriv2.str() == privKey);
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2);
|
||||
assert (strPub2.str() == pubKey);
|
||||
assert (strPriv2.str() == privKey);
|
||||
|
||||
std::istringstream iPriv2(privKey);
|
||||
EVPPKey key3(0, &iPriv2);
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
std::istringstream iPriv2(privKey);
|
||||
EVPPKey key3(0, &iPriv2);
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -410,43 +426,48 @@ void EVPTest::testECEVPSaveLoadFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
EVPPKey key("secp521r1");
|
||||
TemporaryFile filePub;
|
||||
TemporaryFile filePriv;
|
||||
key.save(filePub.path(), filePriv.path(), "testpwd");
|
||||
std::ifstream ifPub(filePub.path().c_str());
|
||||
std::ifstream ifPriv(filePriv.path().c_str());
|
||||
std::string pubKey;
|
||||
std::string privKey;
|
||||
StreamCopier::copyToString(ifPub, pubKey);
|
||||
StreamCopier::copyToString(ifPriv, privKey);
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
EVPPKey key(curveName);
|
||||
TemporaryFile filePub;
|
||||
TemporaryFile filePriv;
|
||||
key.save(filePub.path(), filePriv.path(), "testpwd");
|
||||
std::ifstream ifPub(filePub.path().c_str());
|
||||
std::ifstream ifPriv(filePriv.path().c_str());
|
||||
std::string pubKey;
|
||||
std::string privKey;
|
||||
StreamCopier::copyToString(ifPub, pubKey);
|
||||
StreamCopier::copyToString(ifPriv, privKey);
|
||||
|
||||
EVPPKey key2(filePub.path(), filePriv.path(), "testpwd");
|
||||
EVPPKey key2(filePub.path(), filePriv.path(), "testpwd");
|
||||
|
||||
std::ostringstream strPubE;
|
||||
std::ostringstream strPrivE;
|
||||
key2.save(&strPubE, &strPrivE, "testpwd");
|
||||
assert (strPubE.str() == pubKey);
|
||||
/*TODO: figure out why EVP_PKEY_cmp() fails for identical public keys
|
||||
assert (key == key2);
|
||||
assert (!(key != key2));*/
|
||||
ECKey ecKeyNE("secp112r2");
|
||||
EVPPKey keyNE(&ecKeyNE);
|
||||
assert (key != keyNE);
|
||||
assert (!(key == keyNE));
|
||||
assert (key2 != keyNE);
|
||||
assert (!(key2 == keyNE));
|
||||
std::ostringstream strPubE;
|
||||
std::ostringstream strPrivE;
|
||||
key2.save(&strPubE, &strPrivE, "testpwd");
|
||||
assert (strPubE.str() == pubKey);
|
||||
assert (key == key2);
|
||||
assert (!(key != key2));
|
||||
ECKey ecKeyNE("secp112r2");
|
||||
EVPPKey keyNE(&ecKeyNE);
|
||||
assert (key != keyNE);
|
||||
assert (!(key == keyNE));
|
||||
assert (key2 != keyNE);
|
||||
assert (!(key2 == keyNE));
|
||||
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2, "testpwd");
|
||||
assert (strPub2.str() == pubKey);
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2, "testpwd");
|
||||
assert (strPub2.str() == pubKey);
|
||||
|
||||
EVPPKey key3("", filePriv.path(), "testpwd");
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
EVPPKey key3("", filePriv.path(), "testpwd");
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
@ -460,28 +481,34 @@ void EVPTest::testECEVPSaveLoadFileNoPass()
|
||||
{
|
||||
try
|
||||
{
|
||||
EVPPKey key("secp521r1");
|
||||
TemporaryFile filePub;
|
||||
TemporaryFile filePriv;
|
||||
key.save(filePub.path(), filePriv.path());
|
||||
std::ifstream ifPub(filePub.path().c_str());
|
||||
std::ifstream ifPriv(filePriv.path().c_str());
|
||||
std::string pubKey;
|
||||
std::string privKey;
|
||||
StreamCopier::copyToString(ifPub, pubKey);
|
||||
StreamCopier::copyToString(ifPriv, privKey);
|
||||
std::string curveName = ECKey::getCurveName();
|
||||
if (!curveName.empty())
|
||||
{
|
||||
EVPPKey key(curveName);
|
||||
TemporaryFile filePub;
|
||||
TemporaryFile filePriv;
|
||||
key.save(filePub.path(), filePriv.path());
|
||||
std::ifstream ifPub(filePub.path().c_str());
|
||||
std::ifstream ifPriv(filePriv.path().c_str());
|
||||
std::string pubKey;
|
||||
std::string privKey;
|
||||
StreamCopier::copyToString(ifPub, pubKey);
|
||||
StreamCopier::copyToString(ifPriv, privKey);
|
||||
|
||||
EVPPKey key2(filePub.path(), filePriv.path());
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2);
|
||||
assert (strPub2.str() == pubKey);
|
||||
EVPPKey key2(filePub.path(), filePriv.path());
|
||||
std::ostringstream strPub2;
|
||||
std::ostringstream strPriv2;
|
||||
key2.save(&strPub2, &strPriv2);
|
||||
assert (strPub2.str() == pubKey);
|
||||
|
||||
EVPPKey key3("", filePriv.path());
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
EVPPKey key3("", filePriv.path());
|
||||
std::ostringstream strPub3;
|
||||
key3.save(&strPub3);
|
||||
std::string pubFromPrivate = strPub3.str();
|
||||
assert (pubFromPrivate == pubKey);
|
||||
}
|
||||
else
|
||||
std::cerr << "No elliptic curves found!" << std::endl;
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user