From d2d7aaac692d30ef8422774f1a8d0bd327546061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Vavru=C5=A1a?= Date: Mon, 1 May 2017 10:24:08 -0700 Subject: [PATCH] contrib/libpoco: update Crypto to last stable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the last stable version 1.7.8 fixes build with newer OpenSSL that’s in most of the distribution --- .../Crypto/include/Poco/Crypto/Cipher.h | 2 +- .../Crypto/include/Poco/Crypto/Crypto.h | 2 - .../Crypto/include/Poco/Crypto/DigestEngine.h | 2 +- .../include/Poco/Crypto/X509Certificate.h | 8 ++ contrib/libpoco/Crypto/src/CipherImpl.cpp | 74 ++++++++++++++----- contrib/libpoco/Crypto/src/CipherKeyImpl.cpp | 16 ++-- contrib/libpoco/Crypto/src/CryptoStream.cpp | 10 +-- contrib/libpoco/Crypto/src/DigestEngine.cpp | 27 ++++--- contrib/libpoco/Crypto/src/RSACipherImpl.cpp | 22 +++--- contrib/libpoco/Crypto/src/RSAKeyImpl.cpp | 24 ++++++ .../libpoco/Crypto/src/X509Certificate.cpp | 24 ++++-- .../Crypto/testsuite/src/CryptoTest.cpp | 5 ++ 12 files changed, 153 insertions(+), 63 deletions(-) diff --git a/contrib/libpoco/Crypto/include/Poco/Crypto/Cipher.h b/contrib/libpoco/Crypto/include/Poco/Crypto/Cipher.h index 30d17f3cd0..92ba5da9f4 100644 --- a/contrib/libpoco/Crypto/include/Poco/Crypto/Cipher.h +++ b/contrib/libpoco/Crypto/include/Poco/Crypto/Cipher.h @@ -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 }; diff --git a/contrib/libpoco/Crypto/include/Poco/Crypto/Crypto.h b/contrib/libpoco/Crypto/include/Poco/Crypto/Crypto.h index 1ed50941da..fcfb20ec26 100644 --- a/contrib/libpoco/Crypto/include/Poco/Crypto/Crypto.h +++ b/contrib/libpoco/Crypto/include/Poco/Crypto/Crypto.h @@ -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 diff --git a/contrib/libpoco/Crypto/include/Poco/Crypto/DigestEngine.h b/contrib/libpoco/Crypto/include/Poco/Crypto/DigestEngine.h index 5de75392a8..e2121c414d 100644 --- a/contrib/libpoco/Crypto/include/Poco/Crypto/DigestEngine.h +++ b/contrib/libpoco/Crypto/include/Poco/Crypto/DigestEngine.h @@ -61,7 +61,7 @@ protected: private: std::string _name; - EVP_MD_CTX* _ctx; + EVP_MD_CTX* _pContext; Poco::DigestEngine::Digest _digest; OpenSSLInitializer _openSSLInitializer; }; diff --git a/contrib/libpoco/Crypto/include/Poco/Crypto/X509Certificate.h b/contrib/libpoco/Crypto/include/Poco/Crypto/X509Certificate.h index 472c537637..a6d8690124 100644 --- a/contrib/libpoco/Crypto/include/Poco/Crypto/X509Certificate.h +++ b/contrib/libpoco/Crypto/include/Poco/Crypto/X509Certificate.h @@ -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. diff --git a/contrib/libpoco/Crypto/src/CipherImpl.cpp b/contrib/libpoco/Crypto/src/CipherImpl.cpp index c953aae52e..b8708a78c8 100644 --- a/contrib/libpoco/Crypto/src/CipherImpl.cpp +++ b/contrib/libpoco/Crypto/src/CipherImpl.cpp @@ -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(outputLength); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L int rc = EVP_CipherUpdate( - &_ctx, + _pContext, output, &outLen, input, static_cast(inputLength)); - +#else + int rc = EVP_CipherUpdate( + &_context, + output, + &outLen, + input, + static_cast(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(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(len); } } diff --git a/contrib/libpoco/Crypto/src/CipherKeyImpl.cpp b/contrib/libpoco/Crypto/src/CipherKeyImpl.cpp index 58b51c9424..bcd7452c69 100644 --- a/contrib/libpoco/Crypto/src/CipherKeyImpl.cpp +++ b/contrib/libpoco/Crypto/src/CipherKeyImpl.cpp @@ -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(random.get())); } diff --git a/contrib/libpoco/Crypto/src/CryptoStream.cpp b/contrib/libpoco/Crypto/src/CryptoStream.cpp index 34ce13b4c3..97e73ce810 100644 --- a/contrib/libpoco/Crypto/src/CryptoStream.cpp +++ b/contrib/libpoco/Crypto/src/CryptoStream.cpp @@ -43,7 +43,7 @@ CryptoStreamBuf::CryptoStreamBuf(std::istream& istr, CryptoTransform* pTransform _buffer(static_cast(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(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(_buffer.size())); - + if (n > 0) { pOstr->write(reinterpret_cast(_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(length) - count; diff --git a/contrib/libpoco/Crypto/src/DigestEngine.cpp b/contrib/libpoco/Crypto/src/DigestEngine.cpp index 6e574ab42e..64042589f1 100644 --- a/contrib/libpoco/Crypto/src/DigestEngine.cpp +++ b/contrib/libpoco/Crypto/src/DigestEngine.cpp @@ -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); } diff --git a/contrib/libpoco/Crypto/src/RSACipherImpl.cpp b/contrib/libpoco/Crypto/src/RSACipherImpl.cpp index 01b2385128..91c5b815d6 100644 --- a/contrib/libpoco/Crypto/src/RSACipherImpl.cpp +++ b/contrib/libpoco/Crypto/src/RSACipherImpl.cpp @@ -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(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) { diff --git a/contrib/libpoco/Crypto/src/RSAKeyImpl.cpp b/contrib/libpoco/Crypto/src/RSAKeyImpl.cpp index 8333453cee..3a1580f691 100644 --- a/contrib/libpoco/Crypto/src/RSAKeyImpl.cpp +++ b/contrib/libpoco/Crypto/src/RSAKeyImpl.cpp @@ -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 } diff --git a/contrib/libpoco/Crypto/src/X509Certificate.cpp b/contrib/libpoco/Crypto/src/X509Certificate.cpp index dd9ebd2cab..f7f37965ed 100644 --- a/contrib/libpoco/Crypto/src/X509Certificate.cpp +++ b/contrib/libpoco/Crypto/src/X509Certificate.cpp @@ -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(_pCert); + X509* pOtherCert = const_cast(otherCertificate.certificate()); + return X509_cmp(pCert, pOtherCert) == 0; +} + + } } // namespace Poco::Crypto diff --git a/contrib/libpoco/Crypto/testsuite/src/CryptoTest.cpp b/contrib/libpoco/Crypto/testsuite/src/CryptoTest.cpp index 8c40347095..53764df137 100644 --- a/contrib/libpoco/Crypto/testsuite/src/CryptoTest.cpp +++ b/contrib/libpoco/Crypto/testsuite/src/CryptoTest.cpp @@ -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)); } -- GitLab