diff options
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/CppunitTest_comphelper_test.mk | 1 | ||||
-rw-r--r-- | comphelper/Library_comphelper.mk | 1 | ||||
-rw-r--r-- | comphelper/qa/unit/CryptoTest.cxx | 100 | ||||
-rw-r--r-- | comphelper/source/crypto/Crypto.cxx | 574 |
4 files changed, 676 insertions, 0 deletions
diff --git a/comphelper/CppunitTest_comphelper_test.mk b/comphelper/CppunitTest_comphelper_test.mk index 17de701aca26..3fe7c53f746e 100644 --- a/comphelper/CppunitTest_comphelper_test.mk +++ b/comphelper/CppunitTest_comphelper_test.mk @@ -20,6 +20,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,comphelper_test, \ comphelper/qa/unit/types_test \ comphelper/qa/unit/test_guards \ comphelper/qa/unit/test_traceevent \ + comphelper/qa/unit/CryptoTest \ )) $(eval $(call gb_CppunitTest_use_ure,comphelper_test)) diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk index 2ab1b1bfa5d7..159aaa65248d 100644 --- a/comphelper/Library_comphelper.mk +++ b/comphelper/Library_comphelper.mk @@ -75,6 +75,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\ comphelper/source/container/enumerablemap \ comphelper/source/container/enumhelper \ comphelper/source/container/namecontainer \ + comphelper/source/crypto/Crypto \ comphelper/source/eventattachermgr/eventattachermgr \ comphelper/source/misc/accessiblecomponenthelper \ comphelper/source/misc/accessibleeventnotifier \ diff --git a/comphelper/qa/unit/CryptoTest.cxx b/comphelper/qa/unit/CryptoTest.cxx new file mode 100644 index 000000000000..2b0dac47416f --- /dev/null +++ b/comphelper/qa/unit/CryptoTest.cxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> +#include <config_oox.h> +#include <comphelper/crypto/Crypto.hxx> +#include <comphelper/hash.hxx> + +#include <rtl/ustring.hxx> + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#if USE_TLS_NSS +#include <nss.h> +#endif + +class CryptoTest : public CppUnit::TestFixture +{ +public: + virtual void tearDown() + { +#if USE_TLS_NSS + NSS_Shutdown(); +#endif + } + + void testCryptoHash(); + void testRoundUp(); + + CPPUNIT_TEST_SUITE(CryptoTest); + CPPUNIT_TEST(testCryptoHash); + CPPUNIT_TEST(testRoundUp); + CPPUNIT_TEST_SUITE_END(); +}; + +void CryptoTest::testCryptoHash() +{ + // Check examples from Wikipedia (https://en.wikipedia.org/wiki/HMAC) + OString aContentString("The quick brown fox jumps over the lazy dog"_ostr); + std::vector<sal_uInt8> aContent(aContentString.getStr(), + aContentString.getStr() + aContentString.getLength()); + std::vector<sal_uInt8> aKey = { 'k', 'e', 'y' }; + { + comphelper::CryptoHash aCryptoHash(aKey, comphelper::CryptoHashType::SHA1); + aCryptoHash.update(aContent); + std::vector<sal_uInt8> aHash = aCryptoHash.finalize(); + CPPUNIT_ASSERT_EQUAL(std::string("de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"), + comphelper::hashToString(aHash)); + } + + { + comphelper::CryptoHash aCryptoHash(aKey, comphelper::CryptoHashType::SHA256); + aCryptoHash.update(aContent); + std::vector<sal_uInt8> aHash = aCryptoHash.finalize(); + CPPUNIT_ASSERT_EQUAL( + std::string("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"), + comphelper::hashToString(aHash)); + } + + { + comphelper::CryptoHash aCryptoHash(aKey, comphelper::CryptoHashType::SHA384); + aCryptoHash.update(aContent); + std::vector<sal_uInt8> aHash = aCryptoHash.finalize(); + CPPUNIT_ASSERT_EQUAL(std::string("d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1" + "ae50700582a96cf35e1e554995fe4e03381c237"), + comphelper::hashToString(aHash)); + } + + { + comphelper::CryptoHash aCryptoHash(aKey, comphelper::CryptoHashType::SHA512); + aCryptoHash.update(aContent); + std::vector<sal_uInt8> aHash = aCryptoHash.finalize(); + CPPUNIT_ASSERT_EQUAL( + std::string("b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549" + "f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a"), + comphelper::hashToString(aHash)); + } +} + +void CryptoTest::testRoundUp() +{ + CPPUNIT_ASSERT_EQUAL(16, comphelper::roundUp(16, 16)); + CPPUNIT_ASSERT_EQUAL(32, comphelper::roundUp(32, 16)); + CPPUNIT_ASSERT_EQUAL(64, comphelper::roundUp(64, 16)); + + CPPUNIT_ASSERT_EQUAL(16, comphelper::roundUp(01, 16)); + CPPUNIT_ASSERT_EQUAL(32, comphelper::roundUp(17, 16)); + CPPUNIT_ASSERT_EQUAL(32, comphelper::roundUp(31, 16)); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoTest); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/crypto/Crypto.cxx b/comphelper/source/crypto/Crypto.cxx new file mode 100644 index 000000000000..a9f8b63a635d --- /dev/null +++ b/comphelper/source/crypto/Crypto.cxx @@ -0,0 +1,574 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <comphelper/crypto/Crypto.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <sal/types.h> + +#include <config_oox.h> + +#if USE_TLS_OPENSSL +#include <openssl/evp.h> +#include <openssl/sha.h> +#include <openssl/hmac.h> +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS +#include <nss.h> +#include <nspr.h> +#include <pk11pub.h> +#endif // USE_TLS_NSS + +namespace comphelper +{ +#if USE_TLS_OPENSSL + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + +static HMAC_CTX* HMAC_CTX_new(void) +{ + HMAC_CTX* pContext = new HMAC_CTX; + HMAC_CTX_init(pContext); + return pContext; +} + +static void HMAC_CTX_free(HMAC_CTX* pContext) +{ + HMAC_CTX_cleanup(pContext); + delete pContext; +} +#endif + +namespace +{ +struct cipher_delete +{ + void operator()(EVP_CIPHER_CTX* p) { EVP_CIPHER_CTX_free(p); } +}; + +struct hmac_delete +{ + SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'HMAC_CTX_free' is deprecated + void + operator()(HMAC_CTX* p) + { + HMAC_CTX_free(p); + } + SAL_WNODEPRECATED_DECLARATIONS_POP +}; +} + +struct CryptoImpl +{ + std::unique_ptr<EVP_CIPHER_CTX, cipher_delete> mpContext; + std::unique_ptr<HMAC_CTX, hmac_delete> mpHmacContext; + + CryptoImpl() = default; + + void setupEncryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, + Crypto::CryptoType eType) + { + mpContext.reset(EVP_CIPHER_CTX_new()); + EVP_CIPHER_CTX_init(mpContext.get()); + + const EVP_CIPHER* cipher = getCipher(eType); + if (cipher == nullptr) + return; + + if (iv.empty()) + EVP_EncryptInit_ex(mpContext.get(), cipher, nullptr, key.data(), nullptr); + else + EVP_EncryptInit_ex(mpContext.get(), cipher, nullptr, key.data(), iv.data()); + EVP_CIPHER_CTX_set_padding(mpContext.get(), 0); + } + + void setupDecryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, + Crypto::CryptoType eType) + { + mpContext.reset(EVP_CIPHER_CTX_new()); + EVP_CIPHER_CTX_init(mpContext.get()); + + const EVP_CIPHER* pCipher = getCipher(eType); + if (pCipher == nullptr) + return; + + const size_t nMinKeySize = EVP_CIPHER_key_length(pCipher); + if (key.size() < nMinKeySize) + key.resize(nMinKeySize, 0); + + if (iv.empty()) + EVP_DecryptInit_ex(mpContext.get(), pCipher, nullptr, key.data(), nullptr); + else + { + const size_t nMinIVSize = EVP_CIPHER_iv_length(pCipher); + if (iv.size() < nMinIVSize) + iv.resize(nMinIVSize, 0); + + EVP_DecryptInit_ex(mpContext.get(), pCipher, nullptr, key.data(), iv.data()); + } + EVP_CIPHER_CTX_set_padding(mpContext.get(), 0); + } + + void setupCryptoHashContext(std::vector<sal_uInt8>& rKey, CryptoHashType eType) + { + SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'HMAC_CTX_new' is deprecated + mpHmacContext.reset(HMAC_CTX_new()); + SAL_WNODEPRECATED_DECLARATIONS_POP + const EVP_MD* aEvpMd = nullptr; + switch (eType) + { + case CryptoHashType::SHA1: + aEvpMd = EVP_sha1(); + break; + case CryptoHashType::SHA256: + aEvpMd = EVP_sha256(); + break; + case CryptoHashType::SHA384: + aEvpMd = EVP_sha384(); + break; + case CryptoHashType::SHA512: + aEvpMd = EVP_sha512(); + break; + } + SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'HMAC_Init_ex' is deprecated + HMAC_Init_ex(mpHmacContext.get(), rKey.data(), rKey.size(), aEvpMd, nullptr); + SAL_WNODEPRECATED_DECLARATIONS_POP + } + + ~CryptoImpl() + { + if (mpContext) + EVP_CIPHER_CTX_cleanup(mpContext.get()); + } + + static const EVP_CIPHER* getCipher(Crypto::CryptoType type) + { + switch (type) + { + case Crypto::CryptoType::AES_128_ECB: + return EVP_aes_128_ecb(); + case Crypto::CryptoType::AES_128_CBC: + return EVP_aes_128_cbc(); + case Crypto::CryptoType::AES_256_CBC: + return EVP_aes_256_cbc(); + default: + break; + } + return nullptr; + } +}; + +#elif USE_TLS_NSS + +#define MAX_WRAPPED_KEY_LEN 128 + +struct CryptoImpl +{ + PK11SlotInfo* mSlot; + PK11Context* mContext; + SECItem* mSecParam; + PK11SymKey* mSymKey; + PK11Context* mWrapKeyContext; + PK11SymKey* mWrapKey; + + CryptoImpl() + : mSlot(nullptr) + , mContext(nullptr) + , mSecParam(nullptr) + , mSymKey(nullptr) + , mWrapKeyContext(nullptr) + , mWrapKey(nullptr) + { + // Initialize NSS, database functions are not needed + if (!NSS_IsInitialized()) + { + auto const e = NSS_NoDB_Init(nullptr); + if (e != SECSuccess) + { + PRErrorCode error = PR_GetError(); + const char* errorText = PR_ErrorToName(error); + throw css::uno::RuntimeException( + "NSS_NoDB_Init failed with " + + OUString(errorText, strlen(errorText), RTL_TEXTENCODING_UTF8) + " (" + + OUString::number(static_cast<int>(error)) + ")"); + } + } + } + + ~CryptoImpl() + { + if (mContext) + PK11_DestroyContext(mContext, PR_TRUE); + if (mSecParam) + SECITEM_FreeItem(mSecParam, PR_TRUE); + if (mSymKey) + PK11_FreeSymKey(mSymKey); + if (mWrapKeyContext) + PK11_DestroyContext(mWrapKeyContext, PR_TRUE); + if (mWrapKey) + PK11_FreeSymKey(mWrapKey); + if (mSlot) + PK11_FreeSlot(mSlot); + } + + PK11SymKey* ImportSymKey(CK_MECHANISM_TYPE mechanism, CK_ATTRIBUTE_TYPE operation, SECItem* key) + { + mSymKey = PK11_ImportSymKey(mSlot, mechanism, PK11_OriginUnwrap, operation, key, nullptr); + if (!mSymKey) //rhbz#1614419 maybe failed due to FIPS, use rhbz#1461450 style workaround + { + /* + * Without FIPS it would be possible to just use + * mSymKey = PK11_ImportSymKey( mSlot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr ); + * with FIPS NSS Level 2 certification has to be "workarounded" (so it becomes Level 1) by using + * following method: + * 1. Generate wrap key + * 2. Encrypt authkey with wrap key + * 3. Unwrap encrypted authkey using wrap key + */ + + /* + * Generate wrapping key + */ + CK_MECHANISM_TYPE wrap_mechanism = PK11_GetBestWrapMechanism(mSlot); + int wrap_key_len = PK11_GetBestKeyLength(mSlot, wrap_mechanism); + mWrapKey = PK11_KeyGen(mSlot, wrap_mechanism, nullptr, wrap_key_len, nullptr); + if (!mWrapKey) + throw css::uno::RuntimeException(u"PK11_KeyGen SymKey failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + /* + * Encrypt authkey with wrapping key + */ + + /* + * Initialization of IV is not needed because PK11_GetBestWrapMechanism should return ECB mode + */ + SECItem tmp_sec_item = {}; + mWrapKeyContext + = PK11_CreateContextBySymKey(wrap_mechanism, CKA_ENCRYPT, mWrapKey, &tmp_sec_item); + if (!mWrapKeyContext) + throw css::uno::RuntimeException(u"PK11_CreateContextBySymKey failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + unsigned char wrapped_key_data[MAX_WRAPPED_KEY_LEN]; + int wrapped_key_len = sizeof(wrapped_key_data); + + if (PK11_CipherOp(mWrapKeyContext, wrapped_key_data, &wrapped_key_len, + sizeof(wrapped_key_data), key->data, key->len) + != SECSuccess) + { + throw css::uno::RuntimeException(u"PK11_CipherOp failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + } + + if (PK11_Finalize(mWrapKeyContext) != SECSuccess) + throw css::uno::RuntimeException(u"PK11_Finalize failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + /* + * Finally unwrap sym key + */ + SECItem wrapped_key = {}; + wrapped_key.data = wrapped_key_data; + wrapped_key.len = wrapped_key_len; + + mSymKey = PK11_UnwrapSymKey(mWrapKey, wrap_mechanism, &tmp_sec_item, &wrapped_key, + mechanism, operation, key->len); + } + return mSymKey; + } + + void setupEncryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, + CryptoType type) + { + setupCryptoContext(key, iv, type, CKA_ENCRYPT); + } + + void setupDecryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, + CryptoType type) + { + setupCryptoContext(key, iv, type, CKA_DECRYPT); + } + + void setupCryptoContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, + CryptoType type, CK_ATTRIBUTE_TYPE operation) + { + CK_MECHANISM_TYPE mechanism = static_cast<CK_ULONG>(-1); + + SECItem ivItem; + ivItem.type = siBuffer; + if (iv.empty()) + ivItem.data = nullptr; + else + ivItem.data = iv.data(); + ivItem.len = iv.size(); + + SECItem* pIvItem = nullptr; + + switch (type) + { + case CryptoType::AES_128_ECB: + mechanism = CKM_AES_ECB; + break; + case CryptoType::AES_128_CBC: + mechanism = CKM_AES_CBC; + pIvItem = &ivItem; + break; + case CryptoType::AES_256_CBC: + mechanism = CKM_AES_CBC; + pIvItem = &ivItem; + break; + default: + break; + } + + mSlot = PK11_GetBestSlot(mechanism, nullptr); + + if (!mSlot) + throw css::uno::RuntimeException(u"NSS Slot failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + SECItem keyItem; + keyItem.type = siBuffer; + keyItem.data = key.data(); + keyItem.len = key.size(); + + mSymKey = ImportSymKey(mechanism, CKA_ENCRYPT, &keyItem); + if (!mSymKey) + throw css::uno::RuntimeException(u"NSS SymKey failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + mSecParam = PK11_ParamFromIV(mechanism, pIvItem); + mContext = PK11_CreateContextBySymKey(mechanism, operation, mSymKey, mSecParam); + } + + void setupCryptoHashContext(std::vector<sal_uInt8>& rKey, CryptoHashType eType) + { + CK_MECHANISM_TYPE aMechanism = static_cast<CK_ULONG>(-1); + + switch (eType) + { + case CryptoHashType::SHA1: + aMechanism = CKM_SHA_1_HMAC; + break; + case CryptoHashType::SHA256: + aMechanism = CKM_SHA256_HMAC; + break; + case CryptoHashType::SHA384: + aMechanism = CKM_SHA384_HMAC; + break; + case CryptoHashType::SHA512: + aMechanism = CKM_SHA512_HMAC; + break; + } + + mSlot = PK11_GetBestSlot(aMechanism, nullptr); + + if (!mSlot) + throw css::uno::RuntimeException(u"NSS Slot failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + SECItem aKeyItem; + aKeyItem.data = rKey.data(); + aKeyItem.len = rKey.size(); + + mSymKey = ImportSymKey(aMechanism, CKA_SIGN, &aKeyItem); + if (!mSymKey) + throw css::uno::RuntimeException(u"NSS SymKey failure"_ustr, + css::uno::Reference<css::uno::XInterface>()); + + SECItem param; + param.data = nullptr; + param.len = 0; + mContext = PK11_CreateContextBySymKey(aMechanism, CKA_SIGN, mSymKey, ¶m); + } +}; +#else +struct CryptoImpl +{ +}; +#endif + +Crypto::Crypto() + : mpImpl(std::make_unique<CryptoImpl>()) +{ +} + +Crypto::~Crypto() {} + +// DECRYPT + +Decrypt::Decrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type) +{ +#if USE_TLS_OPENSSL + USE_TLS_NSS == 0 + (void)key; + (void)iv; + (void)type; +#else + mpImpl->setupDecryptContext(key, iv, type); +#endif +} + +sal_uInt32 Decrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, + sal_uInt32 inputLength) +{ + int outputLength = 0; + +#if USE_TLS_OPENSSL + USE_TLS_NSS > 0 + sal_uInt32 actualInputLength + = inputLength == 0 || inputLength > input.size() ? input.size() : inputLength; +#else + (void)output; + (void)input; + (void)inputLength; +#endif + +#if USE_TLS_OPENSSL + (void)EVP_DecryptUpdate(mpImpl->mpContext.get(), output.data(), &outputLength, input.data(), + actualInputLength); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + if (!mpImpl->mContext) + return 0; + (void)PK11_CipherOp(mpImpl->mContext, output.data(), &outputLength, actualInputLength, + input.data(), actualInputLength); +#endif // USE_TLS_NSS + + return static_cast<sal_uInt32>(outputLength); +} + +sal_uInt32 Decrypt::aes128ecb(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, + std::vector<sal_uInt8>& key) +{ + sal_uInt32 outputLength = 0; + std::vector<sal_uInt8> iv; + Decrypt crypto(key, iv, CryptoType::AES_128_ECB); + outputLength = crypto.update(output, input); + return outputLength; +} + +// ENCRYPT + +Encrypt::Encrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type) +{ +#if USE_TLS_OPENSSL + USE_TLS_NSS == 0 + (void)key; + (void)iv; + (void)type; +#else + mpImpl->setupEncryptContext(key, iv, type); +#endif +} + +sal_uInt32 Encrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, + sal_uInt32 inputLength) +{ + int outputLength = 0; + +#if USE_TLS_OPENSSL + USE_TLS_NSS > 0 + sal_uInt32 actualInputLength + = inputLength == 0 || inputLength > input.size() ? input.size() : inputLength; +#else + (void)output; + (void)input; + (void)inputLength; +#endif + +#if USE_TLS_OPENSSL + (void)EVP_EncryptUpdate(mpImpl->mpContext.get(), output.data(), &outputLength, input.data(), + actualInputLength); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + (void)PK11_CipherOp(mpImpl->mContext, output.data(), &outputLength, actualInputLength, + input.data(), actualInputLength); +#endif // USE_TLS_NSS + + return static_cast<sal_uInt32>(outputLength); +} + +// CryptoHash - HMAC + +namespace +{ +sal_Int32 getSizeForHashType(CryptoHashType eType) +{ + switch (eType) + { + case CryptoHashType::SHA1: + return 20; + case CryptoHashType::SHA256: + return 32; + case CryptoHashType::SHA384: + return 48; + case CryptoHashType::SHA512: + return 64; + } + return 0; +} + +} // end anonymous namespace + +CryptoHash::CryptoHash(std::vector<sal_uInt8>& rKey, CryptoHashType eType) + : mnHashSize(getSizeForHashType(eType)) +{ +#if USE_TLS_OPENSSL + USE_TLS_NSS > 0 + mpImpl->setupCryptoHashContext(rKey, eType); + +#if USE_TLS_NSS + PK11_DigestBegin(mpImpl->mContext); +#endif + +#else + (void)rKey; +#endif +} + +bool CryptoHash::update(std::vector<sal_uInt8>& rInput, sal_uInt32 nInputLength) +{ +#if USE_TLS_OPENSSL + USE_TLS_NSS > 0 + sal_uInt32 nActualInputLength + = (nInputLength == 0 || nInputLength > rInput.size()) ? rInput.size() : nInputLength; +#else + (void)rInput; + (void)nInputLength; +#endif + +#if USE_TLS_OPENSSL + SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'HMAC_Update' is deprecated + return HMAC_Update(mpImpl->mpHmacContext.get(), rInput.data(), nActualInputLength) + != 0; + SAL_WNODEPRECATED_DECLARATIONS_POP +#elif USE_TLS_NSS + return PK11_DigestOp(mpImpl->mContext, rInput.data(), nActualInputLength) == SECSuccess; +#else + return false; // ??? +#endif +} + +std::vector<sal_uInt8> CryptoHash::finalize() +{ + std::vector<sal_uInt8> aHash(mnHashSize, 0); +#if USE_TLS_OPENSSL + unsigned int nSizeWritten = 0; + SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'HMAC_Final' is deprecated + (void) HMAC_Final(mpImpl->mpHmacContext.get(), aHash.data(), &nSizeWritten); + SAL_WNODEPRECATED_DECLARATIONS_POP +#elif USE_TLS_NSS + unsigned int nSizeWritten = 0; + PK11_DigestFinal(mpImpl->mContext, aHash.data(), &nSizeWritten, aHash.size()); +#endif + return aHash; +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |