Kaydet (Commit) 5b30a948 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Tomaž Vajngerl

oox: clean-up crypto classes, use c++11 features

- remove "using namespace std;"
- &vector[0] to vector.data()
- use nullptr in OPENSSL

Change-Id: Ib4067b0256801f94d448bc8d3faf5a2902d694e5
Reviewed-on: https://gerrit.libreoffice.org/33629Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
üst 93a49ee2
......@@ -26,25 +26,23 @@ namespace oox {
namespace oox {
namespace core {
const sal_uInt32 SEGMENT_LENGTH = 4096;
struct AgileEncryptionInfo
{
sal_Int32 spinCount;
sal_Int32 saltSize;
sal_Int32 keyBits;
sal_Int32 hashSize;
sal_Int32 blockSize;
sal_Int32 spinCount;
sal_Int32 saltSize;
sal_Int32 keyBits;
sal_Int32 hashSize;
sal_Int32 blockSize;
OUString cipherAlgorithm;
OUString cipherChaining;
OUString hashAlgorithm;
std::vector<sal_uInt8> keyDataSalt;
std::vector<sal_uInt8> saltValue;
std::vector<sal_uInt8> encryptedVerifierHashInput;
std::vector<sal_uInt8> encryptedVerifierHashValue;
std::vector<sal_uInt8> encryptedKeyValue;
std::vector<sal_uInt8> keyDataSalt;
std::vector<sal_uInt8> saltValue;
std::vector<sal_uInt8> encryptedVerifierHashInput;
std::vector<sal_uInt8> encryptedVerifierHashValue;
std::vector<sal_uInt8> encryptedKeyValue;
};
class AgileEngine : public CryptoEngine
......@@ -54,8 +52,7 @@ class AgileEngine : public CryptoEngine
void calculateHashFinal(const OUString& rPassword, std::vector<sal_uInt8>& aHashFinal);
void calculateBlock(
const sal_uInt8* rBlock,
sal_uInt32 aBlockSize,
std::vector<sal_uInt8> const & rBlock,
std::vector<sal_uInt8>& rHashFinal,
std::vector<sal_uInt8>& rInput,
std::vector<sal_uInt8>& rOutput);
......@@ -63,8 +60,7 @@ class AgileEngine : public CryptoEngine
static Crypto::CryptoType cryptoType(const AgileEncryptionInfo& rInfo);
public:
AgileEngine();
virtual ~AgileEngine() override;
AgileEngine() = default;
AgileEncryptionInfo& getInfo() { return mInfo;}
......
......@@ -33,8 +33,7 @@ class Standard2007Engine : public CryptoEngine
bool calculateEncryptionKey(const OUString& rPassword);
public:
Standard2007Engine();
virtual ~Standard2007Engine() override;
Standard2007Engine() = default;
msfilter::StandardEncryptionInfo& getInfo() { return mInfo;}
......
......@@ -16,34 +16,23 @@
namespace oox {
namespace core {
using namespace std;
namespace {
const sal_uInt8 constBlock1[] = { 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79 };
const sal_uInt8 constBlock2[] = { 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e };
const sal_uInt8 constBlock3[] = { 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6 };
const sal_uInt32 constSegmentLength = 4096;
bool hashCalc( std::vector<sal_uInt8>& output,
std::vector<sal_uInt8>& input,
const OUString& algorithm )
bool hashCalc(std::vector<sal_uInt8>& output,
std::vector<sal_uInt8>& input,
const OUString& sAlgorithm )
{
if (algorithm == "SHA1")
if (sAlgorithm == "SHA1")
return Digest::sha1(output, input);
else if (algorithm == "SHA512")
else if (sAlgorithm == "SHA512")
return Digest::sha512(output, input);
return false;
}
} // namespace
AgileEngine::AgileEngine() :
CryptoEngine()
{}
AgileEngine::~AgileEngine()
{}
Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo)
{
if (rInfo.keyBits == 128 && rInfo.cipherAlgorithm == "AES" && rInfo.cipherChaining == "ChainingModeCBC")
......@@ -54,39 +43,35 @@ Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo)
}
void AgileEngine::calculateBlock(
const sal_uInt8* rBlock,
sal_uInt32 aBlockSize,
vector<sal_uInt8>& rHashFinal,
vector<sal_uInt8>& rInput,
vector<sal_uInt8>& rOutput)
std::vector<sal_uInt8> const & rBlock,
std::vector<sal_uInt8>& rHashFinal,
std::vector<sal_uInt8>& rInput,
std::vector<sal_uInt8>& rOutput)
{
vector<sal_uInt8> hash(mInfo.hashSize, 0);
vector<sal_uInt8> salt = mInfo.saltValue;
vector<sal_uInt8> dataFinal(mInfo.hashSize + aBlockSize, 0);
std::vector<sal_uInt8> hash(mInfo.hashSize, 0);
std::vector<sal_uInt8> dataFinal(mInfo.hashSize + rBlock.size(), 0);
std::copy(rHashFinal.begin(), rHashFinal.end(), dataFinal.begin());
std::copy(
rBlock,
rBlock + aBlockSize,
dataFinal.begin() + mInfo.hashSize);
std::copy(rBlock.begin(), rBlock.end(), dataFinal.begin() + mInfo.hashSize);
hashCalc(hash, dataFinal, mInfo.hashAlgorithm);
sal_Int32 keySize = mInfo.keyBits / 8;
vector<sal_uInt8> key(keySize, 0);
std::vector<sal_uInt8> key(keySize, 0);
std::copy(hash.begin(), hash.begin() + keySize, key.begin());
Decrypt aDecryptor(key, salt, cryptoType(mInfo));
Decrypt aDecryptor(key, mInfo.saltValue, cryptoType(mInfo));
aDecryptor.update(rOutput, rInput);
}
void AgileEngine::calculateHashFinal(const OUString& rPassword, vector<sal_uInt8>& aHashFinal)
void AgileEngine::calculateHashFinal(const OUString& rPassword, std::vector<sal_uInt8>& aHashFinal)
{
sal_Int32 saltSize = mInfo.saltSize;
vector<sal_uInt8> salt = mInfo.saltValue;
std::vector<sal_uInt8>& salt = mInfo.saltValue;
sal_uInt32 passwordByteLength = rPassword.getLength() * 2;
vector<sal_uInt8> initialData(saltSize + passwordByteLength);
std::vector<sal_uInt8> initialData(saltSize + passwordByteLength);
std::copy(salt.begin(), salt.end(), initialData.begin());
const sal_uInt8* passwordByteArray = reinterpret_cast<const sal_uInt8*>(rPassword.getStr());
......@@ -96,15 +81,15 @@ void AgileEngine::calculateHashFinal(const OUString& rPassword, vector<sal_uInt8
passwordByteArray + passwordByteLength,
initialData.begin() + saltSize);
vector<sal_uInt8> hash(mInfo.hashSize, 0);
std::vector<sal_uInt8> hash(mInfo.hashSize, 0);
hashCalc(hash, initialData, mInfo.hashAlgorithm);
vector<sal_uInt8> data(mInfo.hashSize + 4, 0);
std::vector<sal_uInt8> data(mInfo.hashSize + 4, 0);
for (sal_Int32 i = 0; i < mInfo.spinCount; i++)
{
ByteOrderConverter::writeLittleEndian( &data[0], i );
ByteOrderConverter::writeLittleEndian(data.data(), i);
std::copy(hash.begin(), hash.end(), data.begin() + 4);
hashCalc(hash, data, mInfo.hashAlgorithm);
}
......@@ -114,60 +99,63 @@ void AgileEngine::calculateHashFinal(const OUString& rPassword, vector<sal_uInt8
bool AgileEngine::generateEncryptionKey(const OUString& rPassword)
{
static const std::vector<sal_uInt8> constBlock1{ 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79 };
static const std::vector<sal_uInt8> constBlock2{ 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e };
static const std::vector<sal_uInt8> constBlock3{ 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6 };
mKey.clear();
mKey.resize(mInfo.keyBits / 8, 0);
vector<sal_uInt8> hashFinal(mInfo.hashSize, 0);
std::vector<sal_uInt8> hashFinal(mInfo.hashSize, 0);
calculateHashFinal(rPassword, hashFinal);
vector<sal_uInt8> encryptedHashInput = mInfo.encryptedVerifierHashInput;
vector<sal_uInt8> hashInput(mInfo.saltSize, 0);
calculateBlock(constBlock1, sizeof(constBlock1), hashFinal, encryptedHashInput, hashInput);
std::vector<sal_uInt8>& encryptedHashInput = mInfo.encryptedVerifierHashInput;
std::vector<sal_uInt8> hashInput(mInfo.saltSize, 0);
calculateBlock(constBlock1, hashFinal, encryptedHashInput, hashInput);
vector<sal_uInt8> encryptedHashValue = mInfo.encryptedVerifierHashValue;
vector<sal_uInt8> hashValue(encryptedHashValue.size(), 0);
calculateBlock(constBlock2, sizeof(constBlock2), hashFinal, encryptedHashValue, hashValue);
std::vector<sal_uInt8>& encryptedHashValue = mInfo.encryptedVerifierHashValue;
std::vector<sal_uInt8> hashValue(encryptedHashValue.size(), 0);
calculateBlock(constBlock2, hashFinal, encryptedHashValue, hashValue);
vector<sal_uInt8> hash(mInfo.hashSize, 0);
std::vector<sal_uInt8> hash(mInfo.hashSize, 0);
hashCalc(hash, hashInput, mInfo.hashAlgorithm);
if (std::equal (hash.begin(), hash.end(), hashValue.begin()) )
{
vector<sal_uInt8> encryptedKeyValue = mInfo.encryptedKeyValue;
calculateBlock(constBlock3, sizeof(constBlock3), hashFinal, encryptedKeyValue, mKey);
std::vector<sal_uInt8>& encryptedKeyValue = mInfo.encryptedKeyValue;
calculateBlock(constBlock3, hashFinal, encryptedKeyValue, mKey);
return true;
}
return false;
}
bool AgileEngine::decrypt(
BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
{
sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes
aInputStream.skip( 4 ); // Reserved 4 Bytes
aInputStream.skip(4); // Reserved 4 Bytes
vector<sal_uInt8> keyDataSalt = mInfo.keyDataSalt;
std::vector<sal_uInt8>& keyDataSalt = mInfo.keyDataSalt;
sal_uInt32 saltSize = mInfo.saltSize;
sal_uInt32 keySize = mInfo.keyBits / 8;
sal_uInt32 segment = 0;
vector<sal_uInt8> saltWithBlockKey(saltSize + sizeof(segment), 0);
std::vector<sal_uInt8> saltWithBlockKey(saltSize + sizeof(segment), 0);
std::copy(keyDataSalt.begin(), keyDataSalt.end(), saltWithBlockKey.begin());
vector<sal_uInt8> hash(mInfo.hashSize, 0);
vector<sal_uInt8> iv(keySize, 0);
std::vector<sal_uInt8> hash(mInfo.hashSize, 0);
std::vector<sal_uInt8> iv(keySize, 0);
vector<sal_uInt8> inputBuffer (SEGMENT_LENGTH);
vector<sal_uInt8> outputBuffer(SEGMENT_LENGTH);
std::vector<sal_uInt8> inputBuffer(constSegmentLength);
std::vector<sal_uInt8> outputBuffer(constSegmentLength);
sal_uInt32 inputLength;
sal_uInt32 outputLength;
sal_uInt32 remaining = totalSize;
while( (inputLength = aInputStream.readMemory( &inputBuffer[0], SEGMENT_LENGTH )) > 0 )
while ((inputLength = aInputStream.readMemory(inputBuffer.data(), constSegmentLength)) > 0)
{
sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&segment);
sal_uInt8* segmentEnd = segmentBegin + sizeof(segment);
......@@ -182,7 +170,7 @@ bool AgileEngine::decrypt(
outputLength = aDecryptor.update(outputBuffer, inputBuffer, inputLength);
sal_uInt32 writeLength = outputLength > remaining ? remaining : outputLength;
aOutputStream.writeMemory( &outputBuffer[0], writeLength );
aOutputStream.writeMemory(outputBuffer.data(), writeLength);
remaining -= outputLength;
segment++;
......
......@@ -15,8 +15,6 @@
namespace oox {
namespace core {
using namespace std;
Crypto::Crypto()
#if USE_TLS_NSS
: mContext(nullptr)
......@@ -61,7 +59,7 @@ const EVP_CIPHER* Crypto::getCipher(CryptoType type)
#endif
#if USE_TLS_NSS
void Crypto::setupContext(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoType type, CK_ATTRIBUTE_TYPE operation)
void Crypto::setupContext(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);
......@@ -70,7 +68,7 @@ void Crypto::setupContext(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoT
if(iv.empty())
ivItem.data = nullptr;
else
ivItem.data = &iv[0];
ivItem.data = iv.data();
ivItem.len = iv.size();
SECItem* pIvItem = nullptr;
......@@ -92,37 +90,37 @@ void Crypto::setupContext(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoT
break;
}
PK11SlotInfo* pSlot( PK11_GetBestSlot( mechanism, nullptr ) );
PK11SlotInfo* pSlot(PK11_GetBestSlot(mechanism, nullptr));
if (!pSlot)
throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference<css::uno::XInterface>());
SECItem keyItem;
keyItem.type = siBuffer;
keyItem.data = &key[0];
keyItem.data = key.data();
keyItem.len = key.size();
mSymKey = PK11_ImportSymKey( pSlot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr );
mSecParam = PK11_ParamFromIV( mechanism, pIvItem );
mContext = PK11_CreateContextBySymKey( mechanism, operation, mSymKey, mSecParam );
mSymKey = PK11_ImportSymKey(pSlot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr);
mSecParam = PK11_ParamFromIV(mechanism, pIvItem);
mContext = PK11_CreateContextBySymKey(mechanism, operation, mSymKey, mSecParam);
}
#endif // USE_TLS_NSS
// DECRYPT
Decrypt::Decrypt(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoType type) :
Crypto()
Decrypt::Decrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type)
: Crypto()
{
#if USE_TLS_OPENSSL
EVP_CIPHER_CTX_init( &mContext );
EVP_CIPHER_CTX_init(&mContext);
const EVP_CIPHER* cipher = getCipher(type);
if (iv.empty())
EVP_DecryptInit_ex( &mContext, cipher, NULL, &key[0], 0 );
EVP_DecryptInit_ex(&mContext, cipher, nullptr, key.data(), 0);
else
EVP_DecryptInit_ex( &mContext, cipher, NULL, &key[0], &iv[0] );
EVP_CIPHER_CTX_set_padding( &mContext, 0 );
EVP_DecryptInit_ex(&mContext, cipher, nullptr, key.data(), iv.data());
EVP_CIPHER_CTX_set_padding(&mContext, 0);
#endif
#if USE_TLS_NSS
......@@ -130,27 +128,27 @@ Decrypt::Decrypt(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoType type)
#endif // USE_TLS_NSS
}
sal_uInt32 Decrypt::update(vector<sal_uInt8>& output, vector<sal_uInt8>& input, sal_uInt32 inputLength)
sal_uInt32 Decrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, sal_uInt32 inputLength)
{
int outputLength = 0;
sal_uInt32 actualInputLength = inputLength == 0 || inputLength > input.size() ? input.size() : inputLength;
#if USE_TLS_OPENSSL
(void)EVP_DecryptUpdate( &mContext, &output[0], &outputLength, &input[0], actualInputLength );
(void)EVP_DecryptUpdate(&mContext, output.data(), &outputLength, input.data(), actualInputLength);
#endif // USE_TLS_OPENSSL
#if USE_TLS_NSS
(void)PK11_CipherOp( mContext, &output[0], &outputLength, actualInputLength, &input[0], actualInputLength );
(void)PK11_CipherOp( mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength );
#endif // USE_TLS_NSS
return static_cast<sal_uInt32>(outputLength);
}
sal_uInt32 Decrypt::aes128ecb(vector<sal_uInt8>& output, vector<sal_uInt8>& input, vector<sal_uInt8>& key)
sal_uInt32 Decrypt::aes128ecb(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, std::vector<sal_uInt8>& key)
{
sal_uInt32 outputLength = 0;
vector<sal_uInt8> iv;
std::vector<sal_uInt8> iv;
Decrypt crypto(key, iv, Crypto::AES_128_ECB);
outputLength = crypto.update(output, input);
return outputLength;
......@@ -158,19 +156,19 @@ sal_uInt32 Decrypt::aes128ecb(vector<sal_uInt8>& output, vector<sal_uInt8>& inpu
// ENCRYPT
Encrypt::Encrypt(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoType type) :
Crypto()
Encrypt::Encrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type)
: Crypto()
{
#if USE_TLS_OPENSSL
EVP_CIPHER_CTX_init( &mContext );
EVP_CIPHER_CTX_init(&mContext);
const EVP_CIPHER* cipher = getCipher(type);
if (iv.empty())
EVP_EncryptInit_ex( &mContext, cipher, NULL, &key[0], 0 );
EVP_EncryptInit_ex(&mContext, cipher, nullptr, key.data(), 0);
else
EVP_EncryptInit_ex( &mContext, cipher, NULL, &key[0], &iv[0] );
EVP_CIPHER_CTX_set_padding( &mContext, 0 );
EVP_EncryptInit_ex(&mContext, cipher, nullptr, key.data(), iv.data());
EVP_CIPHER_CTX_set_padding(&mContext, 0);
#endif
#if USE_TLS_NSS
......@@ -178,18 +176,18 @@ Encrypt::Encrypt(vector<sal_uInt8>& key, vector<sal_uInt8>& iv, CryptoType type)
#endif // USE_TLS_NSS
}
sal_uInt32 Encrypt::update(vector<sal_uInt8>& output, vector<sal_uInt8>& input, sal_uInt32 inputLength)
sal_uInt32 Encrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, sal_uInt32 inputLength)
{
int outputLength = 0;
sal_uInt32 actualInputLength = inputLength == 0 || inputLength > input.size() ? input.size() : inputLength;
#if USE_TLS_OPENSSL
(void)EVP_EncryptUpdate( &mContext, &output[0], &outputLength, &input[0], actualInputLength );
(void)EVP_EncryptUpdate(&mContext, output.data(), &outputLength, input.data(), actualInputLength);
#endif // USE_TLS_OPENSSL
#if USE_TLS_NSS
(void)PK11_CipherOp( mContext, &output[0], &outputLength, actualInputLength, &input[0], actualInputLength );
(void)PK11_CipherOp(mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength);
#endif // USE_TLS_NSS
return static_cast<sal_uInt32>(outputLength);
......@@ -237,29 +235,29 @@ HASH_HashType lclNSSgetHashType(Digest::DigestType eType)
Digest::Digest(DigestType eType) :
meType(eType)
{
#if USE_TLS_OPENSSL
#if USE_TLS_OPENSSL
mpContext = EVP_MD_CTX_create();
EVP_DigestInit_ex(mpContext, lclOpenSSLgetEngine(eType), NULL);
#endif
#endif
#if USE_TLS_NSS
#if USE_TLS_NSS
NSS_NoDB_Init(nullptr);
mpContext = HASH_Create(lclNSSgetHashType(eType));
HASH_Begin(mpContext);
#endif
#endif
}
Digest::~Digest()
{
#if USE_TLS_OPENSSL
#if USE_TLS_OPENSSL
if(mpContext)
EVP_MD_CTX_destroy(mpContext);
#endif
#endif
#if USE_TLS_NSS
#if USE_TLS_NSS
if(mpContext)
HASH_Destroy(mpContext);
#endif
#endif
}
sal_uInt32 Digest::getLength()
......@@ -278,33 +276,33 @@ sal_uInt32 Digest::getLength()
void Digest::update(std::vector<sal_uInt8>& input)
{
#if USE_TLS_OPENSSL
EVP_DigestUpdate(mpContext, &input[0], input.size());
#endif
#if USE_TLS_NSS
HASH_Update(mpContext, &input[0], input.size());
#endif
#if USE_TLS_OPENSSL
EVP_DigestUpdate(mpContext, input.data(), input.size());
#endif
#if USE_TLS_NSS
HASH_Update(mpContext, input.data(), input.size());
#endif
}
void Digest::finalize(std::vector<sal_uInt8>& digest)
{
digest.clear();
#if USE_TLS_OPENSSL
#if USE_TLS_OPENSSL
unsigned int digestWrittenLength;
digest.resize(getLength(), 0);
EVP_DigestFinal_ex(mpContext, &digest[0], &digestWrittenLength);
#endif
EVP_DigestFinal_ex(mpContext, digest.data(), &digestWrittenLength);
#endif
#if USE_TLS_NSS
#if USE_TLS_NSS
unsigned int digestWrittenLength;
unsigned int digestLength = static_cast<unsigned int>(getLength());
digest.resize(digestLength, 0);
HASH_End(mpContext, &digest[0], &digestWrittenLength, digestLength);
#endif
HASH_End(mpContext, digest.data(), &digestWrittenLength, digestLength);
#endif
}
bool Digest::sha1(vector<sal_uInt8>& output, vector<sal_uInt8>& input)
bool Digest::sha1(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input)
{
bool aResult = false;
......@@ -315,7 +313,7 @@ bool Digest::sha1(vector<sal_uInt8>& output, vector<sal_uInt8>& input)
return aResult;
}
bool Digest::sha512(vector<sal_uInt8>& output, vector<sal_uInt8>& input)
bool Digest::sha512(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input)
{
bool aResult = false;
......
......@@ -26,18 +26,18 @@ using namespace css::io;
using namespace css::lang;
using namespace css::uno;
using namespace std;
DocumentEncryption::DocumentEncryption(Reference< XStream > const & xDocumentStream, oox::ole::OleStorage& rOleStorage, const OUString& aPassword) :
mxDocumentStream(xDocumentStream),
mrOleStorage(rOleStorage),
maPassword(aPassword)
DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStream,
oox::ole::OleStorage& rOleStorage,
const OUString& rPassword)
: mxDocumentStream(xDocumentStream)
, mrOleStorage(rOleStorage)
, maPassword(rPassword)
{}
bool DocumentEncryption::encrypt()
{
Reference< XInputStream > xInputStream ( mxDocumentStream->getInputStream(), UNO_SET_THROW );
Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY );
Reference<XInputStream> xInputStream (mxDocumentStream->getInputStream(), UNO_SET_THROW);
Reference<XSeekable> xSeekable(xInputStream, UNO_QUERY);
if (!xSeekable.is())
return false;
......@@ -47,8 +47,8 @@ bool DocumentEncryption::encrypt()
if (!mrOleStorage.isStorage())
return false;
Reference< XOutputStream > xEncryptionInfo( mrOleStorage.openOutputStream( "EncryptionInfo" ), UNO_SET_THROW );
BinaryXOutputStream aEncryptionInfoBinaryOutputStream( xEncryptionInfo, false );
Reference<XOutputStream> xEncryptionInfo(mrOleStorage.openOutputStream("EncryptionInfo"), UNO_SET_THROW);
BinaryXOutputStream aEncryptionInfoBinaryOutputStream(xEncryptionInfo, false);
mEngine.writeEncryptionInfo(maPassword, aEncryptionInfoBinaryOutputStream);
......@@ -56,14 +56,14 @@ bool DocumentEncryption::encrypt()
xEncryptionInfo->flush();
xEncryptionInfo->closeOutput();
Reference< XOutputStream > xEncryptedPackage( mrOleStorage.openOutputStream( "EncryptedPackage" ), UNO_SET_THROW );
BinaryXOutputStream aEncryptedPackageStream( xEncryptedPackage, false );
Reference<XOutputStream> xEncryptedPackage(mrOleStorage.openOutputStream("EncryptedPackage"), UNO_SET_THROW);
BinaryXOutputStream aEncryptedPackageStream(xEncryptedPackage, false);
BinaryXInputStream aDocumentInputStream( xInputStream, false );
BinaryXInputStream aDocumentInputStream(xInputStream, false);
aDocumentInputStream.seekToStart();
aEncryptedPackageStream.WriteUInt32( aLength ); // size
aEncryptedPackageStream.WriteUInt32( 0U ); // reserved
aEncryptedPackageStream.WriteUInt32(aLength); // size
aEncryptedPackageStream.WriteUInt32(0U); // reserved
mEngine.encrypt(aDocumentInputStream, aEncryptedPackageStream);
......
......@@ -20,8 +20,6 @@
namespace oox {
namespace core {
using namespace std;
/* =========================================================================== */
/* Kudos to Caolan McNamara who provided the core decryption implementations. */
/* =========================================================================== */
......@@ -31,23 +29,16 @@ namespace
void lclRandomGenerateValues(sal_uInt8* aArray, sal_uInt32 aSize)
{
TimeValue aTime;
osl_getSystemTime( &aTime );
rtlRandomPool aRandomPool = rtl_random_createPool ();
rtl_random_addBytes ( aRandomPool, &aTime, 8 );
rtl_random_getBytes ( aRandomPool, aArray, aSize );
rtl_random_destroyPool ( aRandomPool );
osl_getSystemTime(&aTime);
rtlRandomPool aRandomPool = rtl_random_createPool();
rtl_random_addBytes(aRandomPool, &aTime, 8);
rtl_random_getBytes(aRandomPool, aArray, aSize);
rtl_random_destroyPool(aRandomPool);
}
static const OUString lclCspName = "Microsoft Enhanced RSA and AES Cryptographic Provider";
} // namespace
Standard2007Engine::Standard2007Engine() :
CryptoEngine()
{}
Standard2007Engine::~Standard2007Engine()
{}
} // end anonymous namespace
bool Standard2007Engine::generateVerifier()
{
......@@ -55,23 +46,23 @@ bool Standard2007Engine::generateVerifier()
if (mKey.size() != 16)
return false;
vector<sal_uInt8> verifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
vector<sal_uInt8> encryptedVerifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
std::vector<sal_uInt8> verifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
std::vector<sal_uInt8> encryptedVerifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
lclRandomGenerateValues(&verifier[0], verifier.size());
lclRandomGenerateValues(verifier.data(), verifier.size());
vector<sal_uInt8> iv;
std::vector<sal_uInt8> iv;
Encrypt aEncryptorVerifier(mKey, iv, Crypto::AES_128_ECB);
if (aEncryptorVerifier.update(encryptedVerifier, verifier) != msfilter::ENCRYPTED_VERIFIER_LENGTH)
return false;
std::copy(encryptedVerifier.begin(), encryptedVerifier.end(), mInfo.verifier.encryptedVerifier);
vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
std::vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
mInfo.verifier.encryptedVerifierHashSize = msfilter::SHA1_HASH_LENGTH;
Digest::sha1(hash, verifier);
hash.resize(msfilter::SHA256_HASH_LENGTH, 0);
vector<sal_uInt8> encryptedHash(msfilter::SHA256_HASH_LENGTH, 0);
std::vector<sal_uInt8> encryptedHash(msfilter::SHA256_HASH_LENGTH, 0);
Encrypt aEncryptorHash(mKey, iv, Crypto::AES_128_ECB);
aEncryptorHash.update(encryptedHash, hash, hash.size());
......@@ -87,7 +78,7 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
const sal_uInt8* saltArray = mInfo.verifier.salt;
// Prepare initial data -> salt + password (in 16-bit chars)
vector<sal_uInt8> initialData(saltSize + passwordByteLength);
std::vector<sal_uInt8> initialData(saltSize + passwordByteLength);
std::copy(saltArray, saltArray + saltSize, initialData.begin());
const sal_uInt8* passwordByteArray = reinterpret_cast<const sal_uInt8*>(rPassword.getStr());
......@@ -98,17 +89,17 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
initialData.begin() + saltSize);
// use "hash" vector for result of sha1 hashing
vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
std::vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
// calculate SHA1 hash of initialData
Digest::sha1(hash, initialData);
// data = iterator (4bytes) + hash
vector<sal_uInt8> data(msfilter::SHA1_HASH_LENGTH + 4, 0);
std::vector<sal_uInt8> data(msfilter::SHA1_HASH_LENGTH + 4, 0);
for (sal_Int32 i = 0; i < 50000; ++i)
{
ByteOrderConverter::writeLittleEndian( &data[0], i );
ByteOrderConverter::writeLittleEndian(data.data(), i);
std::copy(hash.begin(), hash.end(), data.begin() + 4);
Digest::sha1(hash, data);
}
......@@ -118,8 +109,8 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
Digest::sha1(hash, data);
// derive key
vector<sal_uInt8> buffer(64, 0x36);
for( size_t i = 0; i < hash.size(); ++i )
std::vector<sal_uInt8> buffer(64, 0x36);
for (size_t i = 0; i < hash.size(); ++i)
buffer[i] ^= hash[i];
Digest::sha1(hash, buffer);
......@@ -135,48 +126,47 @@ bool Standard2007Engine::generateEncryptionKey(const OUString& password)
calculateEncryptionKey(password);
vector<sal_uInt8> encryptedVerifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
std::vector<sal_uInt8> encryptedVerifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
std::copy(
mInfo.verifier.encryptedVerifier,
mInfo.verifier.encryptedVerifier + msfilter::ENCRYPTED_VERIFIER_LENGTH,
encryptedVerifier.begin());
vector<sal_uInt8> encryptedHash(msfilter::SHA256_HASH_LENGTH);
std::vector<sal_uInt8> encryptedHash(msfilter::SHA256_HASH_LENGTH);
std::copy(
mInfo.verifier.encryptedVerifierHash,
mInfo.verifier.encryptedVerifierHash + msfilter::SHA256_HASH_LENGTH,
encryptedHash.begin());
vector<sal_uInt8> verifier(encryptedVerifier.size(), 0);
std::vector<sal_uInt8> verifier(encryptedVerifier.size(), 0);
Decrypt::aes128ecb(verifier, encryptedVerifier, mKey);
vector<sal_uInt8> verifierHash(encryptedHash.size(), 0);
std::vector<sal_uInt8> verifierHash(encryptedHash.size(), 0);
Decrypt::aes128ecb(verifierHash, encryptedHash, mKey);
vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
std::vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
Digest::sha1(hash, verifier);
return std::equal( hash.begin(), hash.end(), verifierHash.begin() );
return std::equal(hash.begin(), hash.end(), verifierHash.begin());
}
bool Standard2007Engine::decrypt(
BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
bool Standard2007Engine::decrypt(BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
{
aInputStream.skip(4); // Document unencrypted size - 4 bytes
aInputStream.skip(4); // Reserved 4 Bytes
aInputStream.skip(4); // Document unencrypted size - 4 bytes
aInputStream.skip(4); // Reserved 4 Bytes
vector<sal_uInt8> iv;
std::vector<sal_uInt8> iv;
Decrypt aDecryptor(mKey, iv, Crypto::AES_128_ECB);
vector<sal_uInt8> inputBuffer (4096);
vector<sal_uInt8> outputBuffer(4096);
std::vector<sal_uInt8> inputBuffer (4096);
std::vector<sal_uInt8> outputBuffer(4096);
sal_uInt32 inputLength;
sal_uInt32 outputLength;
while( (inputLength = aInputStream.readMemory( &inputBuffer[0], inputBuffer.size() )) > 0 )
while ((inputLength = aInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
{
outputLength = aDecryptor.update(outputBuffer, inputBuffer, inputLength);
aOutputStream.writeMemory( &outputBuffer[0], outputLength );
aOutputStream.writeMemory(outputBuffer.data(), outputLength);
}
return true;
}
......@@ -207,9 +197,9 @@ void Standard2007Engine::writeEncryptionInfo(const OUString& password, BinaryXOu
sal_uInt32 encryptionHeaderSize = static_cast<sal_uInt32>(sizeof(msfilter::EncryptionStandardHeader));
rStream.WriteUInt32( mInfo.header.flags );
rStream.WriteUInt32(mInfo.header.flags);
sal_uInt32 headerSize = encryptionHeaderSize + cspNameSize;
rStream.WriteUInt32( headerSize );
rStream.WriteUInt32(headerSize);
rStream.writeMemory(&mInfo.header, encryptionHeaderSize);
rStream.writeUnicodeArray(lclCspName);
......@@ -219,24 +209,23 @@ void Standard2007Engine::writeEncryptionInfo(const OUString& password, BinaryXOu
rStream.writeMemory(&mInfo.verifier, encryptionVerifierSize);
}
void Standard2007Engine::encrypt(
BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
void Standard2007Engine::encrypt(BinaryXInputStream& aInputStream,
BinaryXOutputStream& aOutputStream)
{
vector<sal_uInt8> inputBuffer(1024);
vector<sal_uInt8> outputBuffer(1024);
std::vector<sal_uInt8> inputBuffer(1024);
std::vector<sal_uInt8> outputBuffer(1024);
sal_uInt32 inputLength;
sal_uInt32 outputLength;
vector<sal_uInt8> iv;
std::vector<sal_uInt8> iv;
Encrypt aEncryptor(mKey, iv, Crypto::AES_128_ECB);
while( (inputLength = aInputStream.readMemory( &inputBuffer[0], inputBuffer.size() )) > 0 )
while ((inputLength = aInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
{
inputLength = inputLength % 16 == 0 ? inputLength : ((inputLength / 16) * 16) + 16;
outputLength = aEncryptor.update(outputBuffer, inputBuffer, inputLength);
aOutputStream.writeMemory( &outputBuffer[0], outputLength );
aOutputStream.writeMemory(outputBuffer.data(), outputLength);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment