summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2024-11-01 12:48:10 +0100
committerTomaž Vajngerl <quikee@gmail.com>2024-11-04 21:51:32 +0100
commitc8cba8ae30baef6feca3b0613366d28df4a5e568 (patch)
tree6c70cba4f20b6c62062ad316fe0f04b745e7d59b /oox
parent6adbc3c7179fc3977a15867e505b4ea919caf765 (diff)
move CryptTools from oox to comphelper so we can reuse it
Also move the relevant tests and clean-up the names a bit to make it mroe consistent. Change-Id: I929ef9c13b954fd6a506471231d1bc41e4ef9980 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176027 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/Library_oox.mk1
-rw-r--r--oox/qa/unit/CryptoTest.cxx60
-rw-r--r--oox/source/crypto/AgileEngine.cxx50
-rw-r--r--oox/source/crypto/CryptTools.cxx533
-rw-r--r--oox/source/crypto/Standard2007Engine.cxx16
5 files changed, 34 insertions, 626 deletions
diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk
index 7330fcc8995d..df8e484f7303 100644
--- a/oox/Library_oox.mk
+++ b/oox/Library_oox.mk
@@ -139,7 +139,6 @@ $(eval $(call gb_Library_add_exception_objects,oox,\
oox/source/core/relationshandler \
oox/source/core/xmlfilterbase \
oox/source/crypto/AgileEngine \
- oox/source/crypto/CryptTools \
oox/source/crypto/DocumentEncryption \
oox/source/crypto/DocumentDecryption \
oox/source/crypto/Standard2007Engine \
diff --git a/oox/qa/unit/CryptoTest.cxx b/oox/qa/unit/CryptoTest.cxx
index 60938962fa72..88e71173a00d 100644
--- a/oox/qa/unit/CryptoTest.cxx
+++ b/oox/qa/unit/CryptoTest.cxx
@@ -31,8 +31,7 @@ class CryptoTest : public CppUnit::TestFixture
{
public:
virtual ~CryptoTest() override;
- void testCryptoHash();
- void testRoundUp();
+
void testStandard2007();
void testAgileEncryptionVerifier();
void testAgileEncryptionInfoWritingAndParsing();
@@ -40,8 +39,6 @@ public:
void testAgileEncryptingAndDecrypting();
CPPUNIT_TEST_SUITE(CryptoTest);
- CPPUNIT_TEST(testCryptoHash);
- CPPUNIT_TEST(testRoundUp);
CPPUNIT_TEST(testStandard2007);
CPPUNIT_TEST(testAgileEncryptionVerifier);
CPPUNIT_TEST(testAgileEncryptionInfoWritingAndParsing);
@@ -71,61 +68,6 @@ CryptoTest::~CryptoTest()
#endif
}
-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' };
- {
- oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA1);
- aCryptoHash.update(aContent);
- std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
- CPPUNIT_ASSERT_EQUAL(std::string("de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"),
- toString(aHash));
- }
-
- {
- oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA256);
- aCryptoHash.update(aContent);
- std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
- CPPUNIT_ASSERT_EQUAL(
- std::string("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"),
- toString(aHash));
- }
-
- {
- oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA384);
- aCryptoHash.update(aContent);
- std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
- CPPUNIT_ASSERT_EQUAL(std::string("d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1"
- "ae50700582a96cf35e1e554995fe4e03381c237"),
- toString(aHash));
- }
-
- {
- oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA512);
- aCryptoHash.update(aContent);
- std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
- CPPUNIT_ASSERT_EQUAL(
- std::string("b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549"
- "f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a"),
- toString(aHash));
- }
-}
-
-void CryptoTest::testRoundUp()
-{
- CPPUNIT_ASSERT_EQUAL(16, oox::crypto::roundUp(16, 16));
- CPPUNIT_ASSERT_EQUAL(32, oox::crypto::roundUp(32, 16));
- CPPUNIT_ASSERT_EQUAL(64, oox::crypto::roundUp(64, 16));
-
- CPPUNIT_ASSERT_EQUAL(16, oox::crypto::roundUp(01, 16));
- CPPUNIT_ASSERT_EQUAL(32, oox::crypto::roundUp(17, 16));
- CPPUNIT_ASSERT_EQUAL(32, oox::crypto::roundUp(31, 16));
-}
-
void CryptoTest::testStandard2007()
{
oox::crypto::Standard2007Engine aEngine;
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
index 1f164aa6ab42..6b552620f24d 100644
--- a/oox/source/crypto/AgileEngine.cxx
+++ b/oox/source/crypto/AgileEngine.cxx
@@ -218,14 +218,14 @@ bool hashCalc(std::vector<sal_uInt8>& output,
return false;
}
-CryptoHashType cryptoHashTypeFromString(std::u16string_view sAlgorithm)
+comphelper::CryptoHashType cryptoHashTypeFromString(std::u16string_view sAlgorithm)
{
if (sAlgorithm == u"SHA512")
- return CryptoHashType::SHA512;
+ return comphelper::CryptoHashType::SHA512;
else if (sAlgorithm == u"SHA384")
- return CryptoHashType::SHA384;
+ return comphelper::CryptoHashType::SHA384;
else
- return CryptoHashType::SHA1;
+ return comphelper::CryptoHashType::SHA1;
}
} // namespace
@@ -234,13 +234,13 @@ AgileEngine::AgileEngine()
: meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512)
{}
-Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo)
+comphelper::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo)
{
if (rInfo.keyBits == 128 && rInfo.cipherAlgorithm == "AES" && rInfo.cipherChaining == "ChainingModeCBC")
- return Crypto::AES_128_CBC;
+ return comphelper::CryptoType::AES_128_CBC;
else if (rInfo.keyBits == 256 && rInfo.cipherAlgorithm == "AES" && rInfo.cipherChaining == "ChainingModeCBC")
- return Crypto::AES_256_CBC;
- return Crypto::UNKNOWN;
+ return comphelper::CryptoType::AES_256_CBC;
+ return comphelper::CryptoType::UNKNOWN;
}
static std::vector<sal_uInt8> calculateIV(comphelper::HashType eType,
@@ -252,7 +252,7 @@ static std::vector<sal_uInt8> calculateIV(comphelper::HashType eType,
aHasher.update(rSalt.data(), rSalt.size());
aHasher.update(rBlock.data(), rBlock.size());
std::vector<sal_uInt8> aIV = aHasher.finalize();
- aIV.resize(roundUp(sal_Int32(aIV.size()), nCipherBlockSize), 0x36);
+ aIV.resize(comphelper::roundUp(sal_Int32(aIV.size()), nCipherBlockSize), 0x36);
return aIV;
}
@@ -274,7 +274,7 @@ void AgileEngine::calculateBlock(
std::copy(hash.begin(), hash.begin() + keySize, key.begin());
- Decrypt aDecryptor(key, mInfo.saltValue, cryptoType(mInfo));
+ comphelper::Decrypt aDecryptor(key, mInfo.saltValue, cryptoType(mInfo));
aDecryptor.update(rOutput, rInput);
}
@@ -296,7 +296,7 @@ void AgileEngine::encryptBlock(
std::copy(hash.begin(), hash.begin() + keySize, key.begin());
- Encrypt aEncryptor(key, mInfo.saltValue, cryptoType(mInfo));
+ comphelper::Encrypt aEncryptor(key, mInfo.saltValue, cryptoType(mInfo));
aEncryptor.update(rOutput, rInput);
}
@@ -338,7 +338,7 @@ bool AgileEngine::decryptAndCheckVerifierHash(OUString const & rPassword)
std::vector<sal_uInt8>& encryptedHashInput = mInfo.encryptedVerifierHashInput;
// SALT - needs to be a multiple of block size (?)
- sal_uInt32 nSaltSize = roundUp(mInfo.saltSize, mInfo.blockSize);
+ sal_uInt32 nSaltSize = comphelper::roundUp(mInfo.saltSize, mInfo.blockSize);
if (nSaltSize < encryptedHashInput.size())
return false;
std::vector<sal_uInt8> hashInput(nSaltSize, 0);
@@ -400,7 +400,7 @@ bool AgileEngine::decryptHmacKey()
std::vector<sal_uInt8> iv = calculateIV(eType, mInfo.keyDataSalt, constBlockHmac1, mInfo.blockSize);
// Decrypt without key, calculated iv
- Decrypt aDecrypt(mKey, iv, cryptoType(mInfo));
+ comphelper::Decrypt aDecrypt(mKey, iv, cryptoType(mInfo));
aDecrypt.update(mInfo.hmacKey, mInfo.hmacEncryptedKey);
mInfo.hmacKey.resize(mInfo.hashSize, 0);
@@ -427,7 +427,7 @@ bool AgileEngine::decryptHmacValue()
std::vector<sal_uInt8> iv = calculateIV(eType, mInfo.keyDataSalt, constBlockHmac2, mInfo.blockSize);
// Decrypt without key, calculated iv
- Decrypt aDecrypt(mKey, iv, cryptoType(mInfo));
+ comphelper::Decrypt aDecrypt(mKey, iv, cryptoType(mInfo));
aDecrypt.update(mInfo.hmacHash, mInfo.hmacEncryptedValue);
mInfo.hmacHash.resize(mInfo.hashSize, 0);
@@ -446,7 +446,7 @@ bool AgileEngine::checkDataIntegrity()
bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
{
- CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm));
+ comphelper::CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm));
sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes
// account for size in HMAC
@@ -492,7 +492,7 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
// Only if hash > keySize
std::copy(hash.begin(), hash.begin() + keySize, iv.begin());
- Decrypt aDecryptor(mKey, iv, AgileEngine::cryptoType(mInfo));
+ comphelper::Decrypt aDecryptor(mKey, iv, cryptoType(mInfo));
outputLength = aDecryptor.update(outputBuffer, inputBuffer, inputLength);
sal_uInt32 writeLength = std::min(outputLength, remaining);
@@ -593,7 +593,7 @@ bool AgileEngine::generateAndEncryptVerifierHash(OUString const & rPassword)
return false;
// HASH - needs to be modified to be multiple of block size
- sal_Int32 nVerifierHash = roundUp(mInfo.hashSize, mInfo.blockSize);
+ sal_Int32 nVerifierHash = comphelper::roundUp(mInfo.hashSize, mInfo.blockSize);
std::vector<sal_uInt8> unencryptedVerifierHashValue;
if (!hashCalc(unencryptedVerifierHashValue, unencryptedVerifierHashInput, mInfo.hashAlgorithm))
return false;
@@ -619,7 +619,7 @@ bool AgileEngine::encryptHmacKey()
return false;
// Encrypted salt must be multiple of block size
- sal_Int32 nEncryptedSaltSize = oox::crypto::roundUp(mInfo.hashSize, mInfo.blockSize);
+ sal_Int32 nEncryptedSaltSize = comphelper::roundUp(mInfo.hashSize, mInfo.blockSize);
// We need to extend hmacSalt to multiple of block size, padding with 0x36
std::vector<sal_uInt8> extendedSalt(mInfo.hmacKey);
@@ -643,7 +643,7 @@ bool AgileEngine::encryptHmacKey()
std::vector<sal_uInt8> iv = calculateIV(eType, mInfo.keyDataSalt, constBlockHmac1, mInfo.blockSize);
// Encrypt without key, calculated iv
- Encrypt aEncryptor(mKey, iv, cryptoType(mInfo));
+ comphelper::Encrypt aEncryptor(mKey, iv, cryptoType(mInfo));
aEncryptor.update(mInfo.hmacEncryptedKey, extendedSalt);
return true;
@@ -651,7 +651,7 @@ bool AgileEngine::encryptHmacKey()
bool AgileEngine::encryptHmacValue()
{
- sal_Int32 nEncryptedValueSize = roundUp(mInfo.hashSize, mInfo.blockSize);
+ sal_Int32 nEncryptedValueSize = comphelper::roundUp(mInfo.hashSize, mInfo.blockSize);
mInfo.hmacEncryptedValue.clear();
mInfo.hmacEncryptedValue.resize(nEncryptedValueSize, 0);
@@ -672,7 +672,7 @@ bool AgileEngine::encryptHmacValue()
std::vector<sal_uInt8> iv = calculateIV(eType, mInfo.keyDataSalt, constBlockHmac2, mInfo.blockSize);
// Encrypt without key, calculated iv
- Encrypt aEncryptor(mKey, iv, cryptoType(mInfo));
+ comphelper::Encrypt aEncryptor(mKey, iv, cryptoType(mInfo));
aEncryptor.update(mInfo.hmacEncryptedValue, extendedHash);
return true;
@@ -726,7 +726,7 @@ void AgileEngine::setupEncryptionParameters(AgileEncryptionParameters const & rA
mInfo.keyDataSalt.resize(mInfo.saltSize);
mInfo.saltValue.resize(mInfo.saltSize);
mInfo.encryptedVerifierHashInput.resize(mInfo.saltSize);
- mInfo.encryptedVerifierHashValue.resize(roundUp(mInfo.hashSize, mInfo.blockSize), 0);
+ mInfo.encryptedVerifierHashValue.resize(comphelper::roundUp(mInfo.hashSize, mInfo.blockSize), 0);
}
bool AgileEngine::setupEncryptionKey(OUString const & rPassword)
@@ -803,7 +803,7 @@ void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rx
css::uno::Reference<css::io::XOutputStream> & rxOutputStream,
sal_uInt32 nSize)
{
- CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm));
+ comphelper::CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm));
BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false);
BinaryXInputStream aBinaryInputStream(rxInputStream, false);
@@ -839,7 +839,7 @@ void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rx
while ((inputLength = aBinaryInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
{
sal_uInt32 correctedInputLength = inputLength % mInfo.blockSize == 0 ?
- inputLength : oox::crypto::roundUp(inputLength, sal_uInt32(mInfo.blockSize));
+ inputLength : comphelper::roundUp(inputLength, sal_uInt32(mInfo.blockSize));
// Update Key
auto p = saltWithBlockKey.begin() + saltSize;
@@ -853,7 +853,7 @@ void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rx
// Only if hash > keySize
std::copy(hash.begin(), hash.begin() + keySize, iv.begin());
- Encrypt aEncryptor(mKey, iv, AgileEngine::cryptoType(mInfo));
+ comphelper::Encrypt aEncryptor(mKey, iv, AgileEngine::cryptoType(mInfo));
outputLength = aEncryptor.update(outputBuffer, inputBuffer, correctedInputLength);
aBinaryOutputStream.writeMemory(outputBuffer.data(), outputLength);
aCryptoHash.update(outputBuffer, outputLength);
diff --git a/oox/source/crypto/CryptTools.cxx b/oox/source/crypto/CryptTools.cxx
deleted file mode 100644
index 32aefab57fac..000000000000
--- a/oox/source/crypto/CryptTools.cxx
+++ /dev/null
@@ -1,533 +0,0 @@
-/* -*- 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 <oox/crypto/CryptTools.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 oox::crypto {
-
-#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, Crypto::CryptoType type)
- {
- setupCryptoContext(key, iv, type, CKA_ENCRYPT);
- }
-
- void setupDecryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto::CryptoType type)
- {
- setupCryptoContext(key, iv, type, CKA_DECRYPT);
- }
-
- void setupCryptoContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto::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 Crypto::CryptoType::AES_128_ECB:
- mechanism = CKM_AES_ECB;
- break;
- case Crypto::CryptoType::AES_128_CBC:
- case Crypto::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, &param);
- }
-};
-#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, Crypto::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);
- unsigned int nSizeWritten;
-#if USE_TLS_OPENSSL
-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
- PK11_DigestFinal(mpImpl->mContext, aHash.data(), &nSizeWritten, aHash.size());
-#endif
- (void)nSizeWritten;
-
- return aHash;
-}
-
-} // namespace oox::crypto
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
index 792c6c27cc7a..a9fb8d3c2339 100644
--- a/oox/source/crypto/Standard2007Engine.cxx
+++ b/oox/source/crypto/Standard2007Engine.cxx
@@ -10,11 +10,11 @@
#include <oox/crypto/Standard2007Engine.hxx>
-#include <oox/crypto/CryptTools.hxx>
#include <oox/helper/binaryinputstream.hxx>
#include <oox/helper/binaryoutputstream.hxx>
#include <rtl/random.h>
+#include <comphelper/crypto/Crypto.hxx>
#include <comphelper/hash.hxx>
namespace oox::crypto {
@@ -50,7 +50,7 @@ bool Standard2007Engine::generateVerifier()
lclRandomGenerateValues(verifier.data(), verifier.size());
std::vector<sal_uInt8> iv;
- Encrypt aEncryptorVerifier(mKey, iv, Crypto::AES_128_ECB);
+ comphelper::Encrypt aEncryptorVerifier(mKey, iv, comphelper::CryptoType::AES_128_ECB);
if (aEncryptorVerifier.update(encryptedVerifier, verifier) != msfilter::ENCRYPTED_VERIFIER_LENGTH)
return false;
std::copy(encryptedVerifier.begin(), encryptedVerifier.end(), mInfo.verifier.encryptedVerifier);
@@ -61,7 +61,7 @@ bool Standard2007Engine::generateVerifier()
std::vector<sal_uInt8> encryptedHash(comphelper::SHA256_HASH_LENGTH, 0);
- Encrypt aEncryptorHash(mKey, iv, Crypto::AES_128_ECB);
+ comphelper::Encrypt aEncryptorHash(mKey, iv, comphelper::CryptoType::AES_128_ECB);
aEncryptorHash.update(encryptedHash, hash, hash.size());
std::copy(encryptedHash.begin(), encryptedHash.end(), mInfo.verifier.encryptedVerifierHash);
@@ -148,10 +148,10 @@ bool Standard2007Engine::generateEncryptionKey(const OUString& password)
encryptedHash.begin());
std::vector<sal_uInt8> verifier(encryptedVerifier.size(), 0);
- Decrypt::aes128ecb(verifier, encryptedVerifier, mKey);
+ comphelper::Decrypt::aes128ecb(verifier, encryptedVerifier, mKey);
std::vector<sal_uInt8> verifierHash(encryptedHash.size(), 0);
- Decrypt::aes128ecb(verifierHash, encryptedHash, mKey);
+ comphelper::Decrypt::aes128ecb(verifierHash, encryptedHash, mKey);
std::vector<sal_uInt8> hash = comphelper::Hash::calculateHash(verifier.data(), verifier.size(), comphelper::HashType::SHA1);
@@ -165,7 +165,7 @@ bool Standard2007Engine::decrypt(BinaryXInputStream& aInputStream,
aInputStream.skip(4); // Reserved 4 Bytes
std::vector<sal_uInt8> iv;
- Decrypt aDecryptor(mKey, iv, Crypto::AES_128_ECB);
+ comphelper::Decrypt aDecryptor(mKey, iv, comphelper::CryptoType::AES_128_ECB);
std::vector<sal_uInt8> inputBuffer (4096);
std::vector<sal_uInt8> outputBuffer(4096);
sal_uInt32 inputLength;
@@ -261,13 +261,13 @@ void Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream
sal_uInt32 outputLength;
std::vector<sal_uInt8> iv;
- Encrypt aEncryptor(mKey, iv, Crypto::AES_128_ECB);
+ comphelper::Encrypt aEncryptor(mKey, iv, comphelper::CryptoType::AES_128_ECB);
while ((inputLength = aBinaryInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
{
// increase size to multiple of 16 (size of mKey) if necessary
inputLength = inputLength % AES128Size == 0 ?
- inputLength : roundUp(inputLength, AES128Size);
+ inputLength : comphelper::roundUp(inputLength, AES128Size);
outputLength = aEncryptor.update(outputBuffer, inputBuffer, inputLength);
aBinaryOutputStream.writeMemory(outputBuffer.data(), outputLength);
}