mirror of
https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
synced 2025-11-01 19:17:59 +00:00
Crypto: complete merge to 1.4.2
This commit is contained in:
@@ -1,291 +1,339 @@
|
||||
//
|
||||
// RSAKeyImpl.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Crypto/src/RSAKeyImpl.cpp#3 $
|
||||
//
|
||||
// Library: Crypto
|
||||
// Package: RSA
|
||||
// Module: RSAKeyImpl
|
||||
//
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Crypto/RSAKeyImpl.h"
|
||||
#include "Poco/Crypto/X509Certificate.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/TemporaryFile.h"
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Crypto {
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(const X509Certificate& cert):
|
||||
_pRSA(0)
|
||||
{
|
||||
const X509* pCert = cert.certificate();
|
||||
EVP_PKEY* pKey = X509_get_pubkey(const_cast<X509*>(pCert));
|
||||
|
||||
RSA* pRSA = pKey->pkey.rsa;
|
||||
_pRSA = RSAPublicKey_dup(pRSA);
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent):
|
||||
_pRSA(0)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
_pRSA = RSA_new();
|
||||
int ret = 0;
|
||||
BIGNUM* bn = 0;
|
||||
try
|
||||
{
|
||||
bn = BN_new();
|
||||
BN_set_word(bn, exponent);
|
||||
ret = RSA_generate_key_ex(_pRSA, keyLength, bn, 0);
|
||||
BN_free(bn);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BN_free(bn);
|
||||
throw;
|
||||
}
|
||||
if (!ret) throw Poco::InvalidArgumentException("Failed to create RSA context");
|
||||
#else
|
||||
_pRSA = RSA_generate_key(keyLength, exponent, 0, 0);
|
||||
if (!_pRSA) throw Poco::InvalidArgumentException("Failed to create RSA context");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(
|
||||
const std::string& publicKeyFile,
|
||||
const std::string& privateKeyFile,
|
||||
const std::string& privateKeyPassphrase):
|
||||
_pRSA(0)
|
||||
{
|
||||
init(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase):
|
||||
_pRSA(0)
|
||||
{
|
||||
// due to C lib not supporting streams, we create two temporary files
|
||||
std::string publicKeyFile;
|
||||
Poco::TemporaryFile pubFile;
|
||||
if (pPublicKeyStream)
|
||||
{
|
||||
if (!pubFile.createFile())
|
||||
throw Poco::CreateFileException("Cannot create temporary file for writing public key");
|
||||
publicKeyFile = pubFile.path();
|
||||
Poco::FileOutputStream fout(publicKeyFile);
|
||||
Poco::StreamCopier::copyStream(*pPublicKeyStream, fout);
|
||||
}
|
||||
std::string privateKeyFile;
|
||||
Poco::TemporaryFile privFile;
|
||||
if (pPrivateKeyStream)
|
||||
{
|
||||
if (!privFile.createFile())
|
||||
throw Poco::CreateFileException("Cannot create temporary file for writing private key");
|
||||
privateKeyFile = privFile.path();
|
||||
Poco::FileOutputStream fout(privateKeyFile);
|
||||
Poco::StreamCopier::copyStream(*pPrivateKeyStream, fout);
|
||||
|
||||
}
|
||||
init(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::init(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase)
|
||||
{
|
||||
poco_assert_dbg(_pRSA == 0);
|
||||
|
||||
_pRSA = RSA_new();
|
||||
if (!publicKeyFile.empty())
|
||||
{
|
||||
BIO* out = BIO_new(BIO_s_file());
|
||||
if (!out) throw Poco::IOException("Cannot create BIO for reading public key", publicKeyFile);
|
||||
int rc = BIO_read_filename(out, publicKeyFile.c_str());
|
||||
if (rc)
|
||||
{
|
||||
RSA* pubKey = PEM_read_bio_RSAPublicKey(out, &_pRSA, 0, 0);
|
||||
BIO_free(out);
|
||||
if (!pubKey)
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileException("Failed to load public key", publicKeyFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileNotFoundException("Public key file", publicKeyFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!privateKeyFile.empty())
|
||||
{
|
||||
BIO* out = BIO_new(BIO_s_file());
|
||||
if (!out) throw Poco::IOException("Cannot create BIO for reading private key", privateKeyFile);
|
||||
int rc = BIO_read_filename(out, privateKeyFile.c_str());
|
||||
if (rc)
|
||||
{
|
||||
RSA* privKey = 0;
|
||||
if (privateKeyPassphrase.empty())
|
||||
privKey = PEM_read_bio_RSAPrivateKey(out, &_pRSA, 0, 0);
|
||||
else
|
||||
privKey = PEM_read_bio_RSAPrivateKey(out, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
|
||||
BIO_free(out);
|
||||
if (!privKey)
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileException("Failed to load private key", privateKeyFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileNotFoundException("Private key file", privateKeyFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::~RSAKeyImpl()
|
||||
{
|
||||
freeRSA();
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::freeRSA()
|
||||
{
|
||||
if (_pRSA)
|
||||
RSA_free(_pRSA);
|
||||
_pRSA = 0;
|
||||
}
|
||||
|
||||
|
||||
int RSAKeyImpl::size() const
|
||||
{
|
||||
return RSA_size(_pRSA);
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::save(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase)
|
||||
{
|
||||
if (!publicKeyFile.empty())
|
||||
{
|
||||
BIO* out = BIO_new(BIO_s_file());
|
||||
if (!out) throw Poco::IOException("Cannot create BIO for writing public key file", publicKeyFile);
|
||||
try
|
||||
{
|
||||
if (BIO_write_filename(out, const_cast<char*>(publicKeyFile.c_str())))
|
||||
{
|
||||
if (!PEM_write_bio_RSAPublicKey(out, _pRSA))
|
||||
throw Poco::WriteFileException("Failed to write public key to file", publicKeyFile);
|
||||
}
|
||||
else throw Poco::CreateFileException("Cannot create public key file");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BIO_free(out);
|
||||
throw;
|
||||
}
|
||||
BIO_free(out);
|
||||
}
|
||||
|
||||
if (!privateKeyFile.empty())
|
||||
{
|
||||
BIO* out = BIO_new(BIO_s_file());
|
||||
if (!out) throw Poco::IOException("Cannot create BIO for writing private key file", privateKeyFile);
|
||||
try
|
||||
{
|
||||
if (BIO_write_filename(out, const_cast<char*>(privateKeyFile.c_str())))
|
||||
{
|
||||
int rc = 0;
|
||||
if (privateKeyPassphrase.empty())
|
||||
rc = PEM_write_bio_RSAPrivateKey(out, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0);
|
||||
else
|
||||
rc = PEM_write_bio_RSAPrivateKey(out, _pRSA, EVP_des_ede3_cbc(),
|
||||
reinterpret_cast<unsigned char*>(const_cast<char*>(privateKeyPassphrase.c_str())),
|
||||
static_cast<int>(privateKeyPassphrase.length()), 0, 0);
|
||||
if (!rc) throw Poco::FileException("Failed to write private key to file", privateKeyFile);
|
||||
}
|
||||
else throw Poco::CreateFileException("Cannot create private key file", privateKeyFile);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BIO_free(out);
|
||||
throw;
|
||||
}
|
||||
BIO_free(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream, const std::string& privateKeyPassphrase)
|
||||
{
|
||||
if (!pPublicKeyStream && !pPrivateKeyStream) return;
|
||||
|
||||
// due to C lib not supporting streams, we create two temporary files
|
||||
std::string publicKeyFile;
|
||||
Poco::TemporaryFile pubFile;
|
||||
if (pPublicKeyStream)
|
||||
{
|
||||
publicKeyFile = pubFile.path();
|
||||
if (!pubFile.createFile())
|
||||
throw Poco::CreateFileException("Cannot create temporary public file");
|
||||
}
|
||||
std::string privateKeyFile;
|
||||
Poco::TemporaryFile privFile;
|
||||
if (pPrivateKeyStream)
|
||||
{
|
||||
privateKeyFile = privFile.path();
|
||||
if (!privFile.createFile())
|
||||
throw Poco::FileException("Cannot crate temporary private key file");
|
||||
}
|
||||
save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
||||
|
||||
// now copy everything from the temp files to the original streams
|
||||
if (pPublicKeyStream)
|
||||
{
|
||||
Poco::FileInputStream istr(publicKeyFile);
|
||||
Poco::StreamCopier::copyStream(istr, *pPublicKeyStream);
|
||||
}
|
||||
if (pPrivateKeyStream)
|
||||
{
|
||||
Poco::FileInputStream istr(privateKeyFile);
|
||||
Poco::StreamCopier::copyStream(istr, *pPrivateKeyStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Crypto
|
||||
//
|
||||
// RSAKeyImpl.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Crypto/src/RSAKeyImpl.cpp#1 $
|
||||
//
|
||||
// Library: Crypto
|
||||
// Package: RSA
|
||||
// Module: RSAKeyImpl
|
||||
//
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Crypto/RSAKeyImpl.h"
|
||||
#include "Poco/Crypto/X509Certificate.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include <sstream>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
#include <openssl/bn.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Crypto {
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(const X509Certificate& cert):
|
||||
_pRSA(0)
|
||||
{
|
||||
const X509* pCert = cert.certificate();
|
||||
EVP_PKEY* pKey = X509_get_pubkey(const_cast<X509*>(pCert));
|
||||
_pRSA = EVP_PKEY_get1_RSA(pKey);
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent):
|
||||
_pRSA(0)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
_pRSA = RSA_new();
|
||||
int ret = 0;
|
||||
BIGNUM* bn = 0;
|
||||
try
|
||||
{
|
||||
bn = BN_new();
|
||||
BN_set_word(bn, exponent);
|
||||
ret = RSA_generate_key_ex(_pRSA, keyLength, bn, 0);
|
||||
BN_free(bn);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BN_free(bn);
|
||||
throw;
|
||||
}
|
||||
if (!ret) throw Poco::InvalidArgumentException("Failed to create RSA context");
|
||||
#else
|
||||
_pRSA = RSA_generate_key(keyLength, exponent, 0, 0);
|
||||
if (!_pRSA) throw Poco::InvalidArgumentException("Failed to create RSA context");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(
|
||||
const std::string& publicKeyFile,
|
||||
const std::string& privateKeyFile,
|
||||
const std::string& privateKeyPassphrase):
|
||||
_pRSA(0)
|
||||
{
|
||||
poco_assert_dbg(_pRSA == 0);
|
||||
|
||||
_pRSA = RSA_new();
|
||||
if (!publicKeyFile.empty())
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_file());
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for reading public key", publicKeyFile);
|
||||
int rc = BIO_read_filename(bio, publicKeyFile.c_str());
|
||||
if (rc)
|
||||
{
|
||||
RSA* pubKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0);
|
||||
BIO_free(bio);
|
||||
if (!pubKey)
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileException("Failed to load public key", publicKeyFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileNotFoundException("Public key file", publicKeyFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!privateKeyFile.empty())
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_file());
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for reading private key", privateKeyFile);
|
||||
int rc = BIO_read_filename(bio, privateKeyFile.c_str());
|
||||
if (rc)
|
||||
{
|
||||
RSA* privKey = 0;
|
||||
if (privateKeyPassphrase.empty())
|
||||
privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0);
|
||||
else
|
||||
privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
|
||||
BIO_free(bio);
|
||||
if (!privKey)
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileException("Failed to load private key", privateKeyFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileNotFoundException("Private key file", privateKeyFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase):
|
||||
_pRSA(0)
|
||||
{
|
||||
poco_assert_dbg(_pRSA == 0);
|
||||
|
||||
_pRSA = RSA_new();
|
||||
if (pPublicKeyStream)
|
||||
{
|
||||
std::string publicKeyData;
|
||||
Poco::StreamCopier::copyToString(*pPublicKeyStream, publicKeyData);
|
||||
BIO* bio = BIO_new_mem_buf(const_cast<char*>(publicKeyData.data()), static_cast<int>(publicKeyData.size()));
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for reading public key");
|
||||
RSA* publicKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0);
|
||||
BIO_free(bio);
|
||||
if (!publicKey)
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileException("Failed to load public key");
|
||||
}
|
||||
}
|
||||
|
||||
if (pPrivateKeyStream)
|
||||
{
|
||||
std::string privateKeyData;
|
||||
Poco::StreamCopier::copyToString(*pPrivateKeyStream, privateKeyData);
|
||||
BIO* bio = BIO_new_mem_buf(const_cast<char*>(privateKeyData.data()), static_cast<int>(privateKeyData.size()));
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for reading private key");
|
||||
RSA* privateKey = 0;
|
||||
if (privateKeyPassphrase.empty())
|
||||
privateKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0);
|
||||
else
|
||||
privateKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
|
||||
BIO_free(bio);
|
||||
if (!privateKey)
|
||||
{
|
||||
freeRSA();
|
||||
throw Poco::FileException("Failed to load private key");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::~RSAKeyImpl()
|
||||
{
|
||||
freeRSA();
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::freeRSA()
|
||||
{
|
||||
if (_pRSA)
|
||||
RSA_free(_pRSA);
|
||||
_pRSA = 0;
|
||||
}
|
||||
|
||||
|
||||
int RSAKeyImpl::size() const
|
||||
{
|
||||
return RSA_size(_pRSA);
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::ByteVec RSAKeyImpl::modulus() const
|
||||
{
|
||||
return convertToByteVec(_pRSA->n);
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::ByteVec RSAKeyImpl::encryptionExponent() const
|
||||
{
|
||||
return convertToByteVec(_pRSA->e);
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::ByteVec RSAKeyImpl::decryptionExponent() const
|
||||
{
|
||||
return convertToByteVec(_pRSA->d);
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::save(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase)
|
||||
{
|
||||
if (!publicKeyFile.empty())
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_file());
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for writing public key file", publicKeyFile);
|
||||
try
|
||||
{
|
||||
if (BIO_write_filename(bio, const_cast<char*>(publicKeyFile.c_str())))
|
||||
{
|
||||
if (!PEM_write_bio_RSAPublicKey(bio, _pRSA))
|
||||
throw Poco::WriteFileException("Failed to write public key to file", publicKeyFile);
|
||||
}
|
||||
else throw Poco::CreateFileException("Cannot create public key file");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BIO_free(bio);
|
||||
throw;
|
||||
}
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
if (!privateKeyFile.empty())
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_file());
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for writing private key file", privateKeyFile);
|
||||
try
|
||||
{
|
||||
if (BIO_write_filename(bio, const_cast<char*>(privateKeyFile.c_str())))
|
||||
{
|
||||
int rc = 0;
|
||||
if (privateKeyPassphrase.empty())
|
||||
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0);
|
||||
else
|
||||
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(),
|
||||
reinterpret_cast<unsigned char*>(const_cast<char*>(privateKeyPassphrase.c_str())),
|
||||
static_cast<int>(privateKeyPassphrase.length()), 0, 0);
|
||||
if (!rc) throw Poco::FileException("Failed to write private key to file", privateKeyFile);
|
||||
}
|
||||
else throw Poco::CreateFileException("Cannot create private key file", privateKeyFile);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BIO_free(bio);
|
||||
throw;
|
||||
}
|
||||
BIO_free(bio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RSAKeyImpl::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream, const std::string& privateKeyPassphrase)
|
||||
{
|
||||
if (pPublicKeyStream)
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for writing public key");
|
||||
if (!PEM_write_bio_RSAPublicKey(bio, _pRSA))
|
||||
{
|
||||
BIO_free(bio);
|
||||
throw Poco::WriteFileException("Failed to write public key to stream");
|
||||
}
|
||||
char* pData;
|
||||
long size = BIO_get_mem_data(bio, &pData);
|
||||
pPublicKeyStream->write(pData, static_cast<std::streamsize>(size));
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
if (pPrivateKeyStream)
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
if (!bio) throw Poco::IOException("Cannot create BIO for writing public key");
|
||||
int rc = 0;
|
||||
if (privateKeyPassphrase.empty())
|
||||
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0);
|
||||
else
|
||||
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(),
|
||||
reinterpret_cast<unsigned char*>(const_cast<char*>(privateKeyPassphrase.c_str())),
|
||||
static_cast<int>(privateKeyPassphrase.length()), 0, 0);
|
||||
if (!rc)
|
||||
{
|
||||
BIO_free(bio);
|
||||
throw Poco::FileException("Failed to write private key to stream");
|
||||
}
|
||||
char* pData;
|
||||
long size = BIO_get_mem_data(bio, &pData);
|
||||
pPrivateKeyStream->write(pData, static_cast<std::streamsize>(size));
|
||||
BIO_free(bio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RSAKeyImpl::ByteVec RSAKeyImpl::convertToByteVec(const BIGNUM* bn)
|
||||
{
|
||||
int numBytes = BN_num_bytes(bn);
|
||||
ByteVec byteVector(numBytes);
|
||||
|
||||
ByteVec::value_type* buffer = new ByteVec::value_type[numBytes];
|
||||
BN_bn2bin(bn, buffer);
|
||||
|
||||
for (int i = 0; i < numBytes; ++i)
|
||||
byteVector[i] = buffer[i];
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
return byteVector;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Crypto
|
||||
|
||||
Reference in New Issue
Block a user