提交 d2d7aaac 编写于 作者: M Marek Vavruša 提交者: alexey-milovidov

contrib/libpoco: update Crypto to last stable

the last stable version 1.7.8 fixes build with
newer OpenSSL that’s in most of the distribution
上级 cb890e26
......@@ -96,7 +96,7 @@ public:
ENC_BASE64 = 0x01, /// Base64-encoded output
ENC_BINHEX = 0x02, /// BinHex-encoded output
ENC_BASE64_NO_LF = 0x81, /// Base64-encoded output, no linefeeds
ENC_BINHEX_NO_LF = 0x82, /// BinHex-encoded output, no linefeeds
ENC_BINHEX_NO_LF = 0x82 /// BinHex-encoded output, no linefeeds
};
......
......@@ -22,7 +22,6 @@
#define Crypto_Crypto_INCLUDED
#pragma GCC diagnostic push
#if defined(__APPLE__)
// OS X 10.7 deprecates some OpenSSL functions
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
......@@ -116,6 +115,5 @@ void Crypto_API uninitializeCrypto();
} } // namespace Poco::Crypto
#pragma GCC diagnostic pop
#endif // Crypto_Crypto_INCLUDED
......@@ -61,7 +61,7 @@ protected:
private:
std::string _name;
EVP_MD_CTX* _ctx;
EVP_MD_CTX* _pContext;
Poco::DigestEngine::Digest _digest;
OpenSSLInitializer _openSSLInitializer;
};
......
......@@ -130,6 +130,14 @@ public:
/// Returns true if verification against the issuer certificate
/// was successfull, false otherwise.
bool equals(const X509Certificate& otherCertificate) const;
/// Checks whether the certificate is equal to
/// the other certificate, by comparing the hashes
/// of both certificates.
///
/// Returns true if both certificates are identical,
/// otherwise false.
const X509* certificate() const;
/// Returns the underlying OpenSSL certificate.
......
......@@ -30,7 +30,7 @@ namespace
{
unsigned long err;
std::string msg;
while ((err = ERR_get_error()))
{
if (!msg.empty())
......@@ -60,24 +60,28 @@ namespace
Direction dir);
~CryptoTransformImpl();
std::size_t blockSize() const;
int setPadding(int padding);
int setPadding(int padding);
std::streamsize transform(
const unsigned char* input,
std::streamsize inputLength,
unsigned char* output,
std::streamsize outputLength);
std::streamsize finalize(
unsigned char* output,
std::streamsize length);
private:
const EVP_CIPHER* _pCipher;
EVP_CIPHER_CTX _ctx;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_CIPHER_CTX* _pContext;
#else
EVP_CIPHER_CTX _context;
#endif
ByteVec _key;
ByteVec _iv;
};
......@@ -92,32 +96,54 @@ namespace
_key(key),
_iv(iv)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
_pContext = EVP_CIPHER_CTX_new();
EVP_CipherInit(
&_ctx,
_pContext,
_pCipher,
&_key[0],
_iv.empty() ? 0 : &_iv[0],
(dir == DIR_ENCRYPT) ? 1 : 0);
#else
EVP_CipherInit(
&_context,
_pCipher,
&_key[0],
_iv.empty() ? 0 : &_iv[0],
(dir == DIR_ENCRYPT) ? 1 : 0);
#endif
}
CryptoTransformImpl::~CryptoTransformImpl()
{
EVP_CIPHER_CTX_cleanup(&_ctx);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_CIPHER_CTX_cleanup(_pContext);
#else
EVP_CIPHER_CTX_cleanup(&_context);
#endif
}
std::size_t CryptoTransformImpl::blockSize() const
{
return EVP_CIPHER_CTX_block_size(&_ctx);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
return EVP_CIPHER_CTX_block_size(_pContext);
#else
return EVP_CIPHER_CTX_block_size(&_context);
#endif
}
int CryptoTransformImpl::setPadding(int padding)
{
return EVP_CIPHER_CTX_set_padding(&_ctx, padding);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
return EVP_CIPHER_CTX_block_size(_pContext);
#else
return EVP_CIPHER_CTX_set_padding(&_context, padding);
#endif
}
std::streamsize CryptoTransformImpl::transform(
const unsigned char* input,
......@@ -125,16 +151,24 @@ namespace
unsigned char* output,
std::streamsize outputLength)
{
poco_assert (outputLength >= std::streamsize(inputLength + blockSize() - 1));
poco_assert (outputLength >= (inputLength + blockSize() - 1));
int outLen = static_cast<int>(outputLength);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
int rc = EVP_CipherUpdate(
&_ctx,
_pContext,
output,
&outLen,
input,
static_cast<int>(inputLength));
#else
int rc = EVP_CipherUpdate(
&_context,
output,
&outLen,
input,
static_cast<int>(inputLength));
#endif
if (rc == 0)
throwError();
......@@ -146,18 +180,22 @@ namespace
unsigned char* output,
std::streamsize length)
{
poco_assert (length >= (std::streamsize)blockSize());
poco_assert (length >= blockSize());
int len = static_cast<int>(length);
// Use the '_ex' version that does not perform implicit cleanup since we
// will call EVP_CIPHER_CTX_cleanup() from the dtor as there is no
// guarantee that finalize() will be called if an error occurred.
int rc = EVP_CipherFinal_ex(&_ctx, output, &len);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
int rc = EVP_CipherFinal_ex(_pContext, output, &len);
#else
int rc = EVP_CipherFinal_ex(&_context, output, &len);
#endif
if (rc == 0)
throwError();
return static_cast<std::streamsize>(len);
}
}
......
......@@ -27,8 +27,8 @@ namespace Poco {
namespace Crypto {
CipherKeyImpl::CipherKeyImpl(const std::string& name,
const std::string& passphrase,
CipherKeyImpl::CipherKeyImpl(const std::string& name,
const std::string& passphrase,
const std::string& salt,
int iterationCount):
_pCipher(0),
......@@ -48,8 +48,8 @@ CipherKeyImpl::CipherKeyImpl(const std::string& name,
}
CipherKeyImpl::CipherKeyImpl(const std::string& name,
const ByteVec& key,
CipherKeyImpl::CipherKeyImpl(const std::string& name,
const ByteVec& key,
const ByteVec& iv):
_pCipher(0),
_name(name),
......@@ -64,7 +64,7 @@ CipherKeyImpl::CipherKeyImpl(const std::string& name,
throw Poco::NotFoundException("Cipher " + name + " was not found");
}
CipherKeyImpl::CipherKeyImpl(const std::string& name):
_pCipher(0),
_name(name),
......@@ -117,7 +117,7 @@ void CipherKeyImpl::generateKey()
getRandomBytes(vec, keySize());
setKey(vec);
getRandomBytes(vec, ivSize());
setIV(vec);
}
......@@ -126,11 +126,11 @@ void CipherKeyImpl::generateKey()
void CipherKeyImpl::getRandomBytes(ByteVec& vec, std::size_t count)
{
Poco::RandomInputStream random;
vec.clear();
vec.reserve(count);
for (std::size_t i = 0; i < count; ++i)
for (int i = 0; i < count; ++i)
vec.push_back(static_cast<unsigned char>(random.get()));
}
......
......@@ -43,7 +43,7 @@ CryptoStreamBuf::CryptoStreamBuf(std::istream& istr, CryptoTransform* pTransform
_buffer(static_cast<std::size_t>(bufferSize))
{
poco_check_ptr (pTransform);
poco_assert ((size_t)bufferSize > 2 * pTransform->blockSize());
poco_assert (bufferSize > 2 * pTransform->blockSize());
}
......@@ -56,7 +56,7 @@ CryptoStreamBuf::CryptoStreamBuf(std::ostream& ostr, CryptoTransform* pTransform
_buffer(static_cast<std::size_t>(bufferSize))
{
poco_check_ptr (pTransform);
poco_assert ((size_t)bufferSize > 2 * pTransform->blockSize());
poco_assert (bufferSize > 2 * pTransform->blockSize());
}
......@@ -88,10 +88,10 @@ void CryptoStreamBuf::close()
// thrown.
std::ostream* pOstr = _pOstr;
_pOstr = 0;
// Finalize transformation.
std::streamsize n = _pTransform->finalize(_buffer.begin(), static_cast<std::streamsize>(_buffer.size()));
if (n > 0)
{
pOstr->write(reinterpret_cast<char*>(_buffer.begin()), n);
......@@ -159,7 +159,7 @@ int CryptoStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
std::size_t maxChunkSize = _buffer.size()/2;
std::size_t count = 0;
while (count < (size_t)length)
while (count < length)
{
// Truncate chunk size so that the maximum output fits into _buffer.
std::size_t n = static_cast<std::size_t>(length) - count;
......
......@@ -23,46 +23,51 @@ namespace Crypto {
DigestEngine::DigestEngine(const std::string& name):
_name(name)
_name(name),
_pContext(EVP_MD_CTX_create())
{
const EVP_MD* md = EVP_get_digestbyname(_name.c_str());
if (!md) throw Poco::NotFoundException(_name);
_ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(_ctx, md, NULL);
EVP_DigestInit_ex(_pContext, md, NULL);
}
DigestEngine::~DigestEngine()
{
EVP_MD_CTX_destroy(_ctx);
EVP_MD_CTX_destroy(_pContext);
}
int DigestEngine::nid() const
{
return EVP_MD_nid(_ctx->digest);
return EVP_MD_nid(EVP_MD_CTX_md(_pContext));
}
std::size_t DigestEngine::digestLength() const
{
return EVP_MD_CTX_size(_ctx);
return EVP_MD_CTX_size(_pContext);
}
void DigestEngine::reset()
{
EVP_MD_CTX_cleanup(_ctx);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_MD_CTX_free(_pContext);
_pContext = EVP_MD_CTX_create();
#else
EVP_MD_CTX_cleanup(_pContext);
#endif
const EVP_MD* md = EVP_get_digestbyname(_name.c_str());
if (!md) throw Poco::NotFoundException(_name);
EVP_DigestInit_ex(_ctx, md, NULL);
EVP_DigestInit_ex(_pContext, md, NULL);
}
const Poco::DigestEngine::Digest& DigestEngine::digest()
{
_digest.clear();
unsigned len = EVP_MD_CTX_size(_ctx);
unsigned len = EVP_MD_CTX_size(_pContext);
_digest.resize(len);
EVP_DigestFinal_ex(_ctx, &_digest[0], &len);
EVP_DigestFinal_ex(_pContext, &_digest[0], &len);
reset();
return _digest;
}
......@@ -70,7 +75,7 @@ const Poco::DigestEngine::Digest& DigestEngine::digest()
void DigestEngine::updateImpl(const void* data, std::size_t length)
{
EVP_DigestUpdate(_ctx, data, length);
EVP_DigestUpdate(_pContext, data, length);
}
......
......@@ -32,7 +32,7 @@ namespace
{
unsigned long err;
std::string msg;
while ((err = ERR_get_error()))
{
if (!msg.empty())
......@@ -68,7 +68,7 @@ namespace
public:
RSAEncryptImpl(const RSA* pRSA, RSAPaddingMode paddingMode);
~RSAEncryptImpl();
std::size_t blockSize() const;
std::size_t maxDataSize() const;
......@@ -77,7 +77,7 @@ namespace
std::streamsize inputLength,
unsigned char* output,
std::streamsize outputLength);
std::streamsize finalize(unsigned char* output, std::streamsize length);
private:
......@@ -156,7 +156,7 @@ namespace
output += n;
outputLength -= n;
_pos = 0;
}
else
{
......@@ -175,8 +175,8 @@ namespace
std::streamsize RSAEncryptImpl::finalize(unsigned char* output, std::streamsize length)
{
poco_assert ((size_t)length >= blockSize());
poco_assert ((size_t)_pos <= maxDataSize());
poco_assert (length >= blockSize());
poco_assert (_pos <= maxDataSize());
int rc = 0;
if (_pos > 0)
{
......@@ -192,7 +192,7 @@ namespace
public:
RSADecryptImpl(const RSA* pRSA, RSAPaddingMode paddingMode);
~RSADecryptImpl();
std::size_t blockSize() const;
std::streamsize transform(
......@@ -200,7 +200,7 @@ namespace
std::streamsize inputLength,
unsigned char* output,
std::streamsize outputLength);
std::streamsize finalize(
unsigned char* output,
std::streamsize length);
......@@ -241,7 +241,7 @@ namespace
unsigned char* output,
std::streamsize outputLength)
{
// always fill up the buffer before decrypting!
std::streamsize rsaSize = static_cast<std::streamsize>(blockSize());
poco_assert_dbg(_pos <= rsaSize);
......@@ -261,7 +261,7 @@ namespace
output += tmp;
outputLength -= tmp;
_pos = 0;
}
else
{
......@@ -280,7 +280,7 @@ namespace
std::streamsize RSADecryptImpl::finalize(unsigned char* output, std::streamsize length)
{
poco_assert ((size_t)length >= blockSize());
poco_assert (length >= blockSize());
int rc = 0;
if (_pos > 0)
{
......
......@@ -207,19 +207,43 @@ int RSAKeyImpl::size() const
RSAKeyImpl::ByteVec RSAKeyImpl::modulus() const
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const BIGNUM* n = 0;
const BIGNUM* e = 0;
const BIGNUM* d = 0;
RSA_get0_key(_pRSA, &n, &e, &d);
return convertToByteVec(n);
#else
return convertToByteVec(_pRSA->n);
#endif
}
RSAKeyImpl::ByteVec RSAKeyImpl::encryptionExponent() const
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const BIGNUM* n = 0;
const BIGNUM* e = 0;
const BIGNUM* d = 0;
RSA_get0_key(_pRSA, &n, &e, &d);
return convertToByteVec(e);
#else
return convertToByteVec(_pRSA->e);
#endif
}
RSAKeyImpl::ByteVec RSAKeyImpl::decryptionExponent() const
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const BIGNUM* n = 0;
const BIGNUM* e = 0;
const BIGNUM* d = 0;
RSA_get0_key(_pRSA, &n, &e, &d);
return convertToByteVec(d);
#else
return convertToByteVec(_pRSA->d);
#endif
}
......
......@@ -59,7 +59,11 @@ X509Certificate::X509Certificate(X509* pCert, bool shared):
if (shared)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
X509_up_ref(_pCert);
#else
_pCert->references++;
#endif
}
init();
......@@ -205,10 +209,10 @@ std::string X509Certificate::issuerName(NID nid) const
if (X509_NAME* issuer = X509_get_issuer_name(_pCert))
{
char buffer[NAME_BUFFER_SIZE];
X509_NAME_get_text_by_NID(issuer, nid, buffer, sizeof(buffer));
return std::string(buffer);
if (X509_NAME_get_text_by_NID(issuer, nid, buffer, sizeof(buffer)) >= 0)
return std::string(buffer);
}
else return std::string();
return std::string();
}
......@@ -217,10 +221,10 @@ std::string X509Certificate::subjectName(NID nid) const
if (X509_NAME* subj = X509_get_subject_name(_pCert))
{
char buffer[NAME_BUFFER_SIZE];
X509_NAME_get_text_by_NID(subj, nid, buffer, sizeof(buffer));
return std::string(buffer);
if (X509_NAME_get_text_by_NID(subj, nid, buffer, sizeof(buffer)) >= 0)
return std::string(buffer);
}
else return std::string();
return std::string();
}
......@@ -280,4 +284,12 @@ bool X509Certificate::issuedBy(const X509Certificate& issuerCertificate) const
}
bool X509Certificate::equals(const X509Certificate& otherCertificate) const
{
X509* pCert = const_cast<X509*>(_pCert);
X509* pOtherCert = const_cast<X509*>(otherCertificate.certificate());
return X509_cmp(pCert, pOtherCert) == 0;
}
} } // namespace Poco::Crypto
......@@ -246,6 +246,11 @@ void CryptoTest::testCertificate()
// fails with recent OpenSSL versions:
// assert (cert.issuedBy(cert));
std::istringstream otherCertStream(APPINF_PEM);
X509Certificate otherCert(otherCertStream);
assert (cert.equals(otherCert));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册