Commit 3c43b372 authored by ElenaSubbotina's avatar ElenaSubbotina

OoxCryptReader

parent 2df69274
/*
* (c) Copyright Ascensio System SIA 2010-2016
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include <iostream>
#include <iomanip>
#include "CryptTransform.h"
#include "../../Common/3dParty/cryptopp/modes.h"
#include "../../Common/3dParty/cryptopp/aes.h"
#include "../../Common/3dParty/cryptopp/sha.h"
#include "../../Common/3dParty/cryptopp/pwdbased.h"
#include "../../Common/3dParty/cryptopp/filters.h"
static const unsigned char encrVerifierHashInputBlockKey[8] = { 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79 };
static const unsigned char encrVerifierHashValueBlockKey[8] = { 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e };
static const unsigned char encrKeyValueBlockKey[8] = { 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6 };
static const unsigned char encrDataIntegritySaltBlockKey[8] = { 0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, 0xf6 };
static const unsigned char encrDataIntegrityHmacValueBlockKey[8] = { 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33 };
ECMADecryptor::ECMADecryptor()
{
//default ms2010
cryptData.cipherAlgorithm = CRYPT_METHOD::AES_CBC;
cryptData.hashAlgorithm = CRYPT_METHOD::SHA1;
cryptData.spinCount = 100000;
cryptData.keySize = 0x10;
cryptData.hashSize = 0x14;
cryptData.blockSize = 0x10;
cryptData.saltSize = 0x10;
//default ms2016
//cryptData.cipherAlgorithm = AES_CBC;
//cryptData.hashAlgorithm = SHA256;
//cryptData.spinCount = 100000;
//cryptData.keySize = 0x20;
//cryptData.hashSize = 0x40;
//cryptData.blockSize = 0x10;
//cryptData.saltSize = 0x10;
}
class _buf
{
private:
bool bDelete;
public:
unsigned char *ptr;
int size;
//-----------------------------------------------------------------------------------
_buf() {ptr = NULL; size = 0; bDelete = true;}
_buf(int sz) {ptr = new unsigned char [sz]; size = sz; bDelete = true;}
_buf(unsigned char * p, int sz, bool bDelete_ = true )
{
bDelete = bDelete_;
if (bDelete)
{
ptr = new unsigned char [sz]; size = sz;
memcpy(ptr, p , sz);
}
else
{
ptr = p; size = sz;
}
}
void Clear()
{
if (bDelete && ptr) delete []ptr;
ptr = NULL; size = 0;
bDelete = true;
}
virtual ~_buf() {Clear();}
_buf& operator=(const _buf& oSrc)
{
Clear();
size = oSrc.size;
ptr = new unsigned char [oSrc.size];
memcpy(ptr, oSrc.ptr, oSrc.size);
bDelete = true;
return *this;
}
_buf& operator=(_buf& oSrc)
{
Clear();
size = oSrc.size;
ptr = new unsigned char [oSrc.size];
memcpy(ptr, oSrc.ptr, oSrc.size);
bDelete = true;
return *this;
}
};
bool operator==(const _buf& oBuf1, const _buf& oBuf2)
{
if (!oBuf1.ptr || !oBuf2.ptr) return false;
return 0 == memcmp(oBuf1.ptr, oBuf2.ptr, (std::min)(oBuf1.size, oBuf2.size));
}
void CorrectHashSize(_buf & hashBuf, int size, unsigned char padding)
{
if (hashBuf.size < size)
{
unsigned char *newPtr = new unsigned char[size];
memset(newPtr, padding, size);
memcpy(newPtr, hashBuf.ptr, hashBuf.size);
delete []hashBuf.ptr;
hashBuf.ptr = newPtr;
hashBuf.size = size;
}
else if (hashBuf.size > size)
{
hashBuf.size = size;
}
}
_buf HashAppend(_buf & hashBuf, _buf & block, CRYPT_METHOD::_hashAlgorithm algorithm)
{//todooo
if (algorithm == CRYPT_METHOD::SHA1)
{
CryptoPP::SHA1 hash;
if (hashBuf.ptr && hashBuf.size > 0) hash.Update( hashBuf.ptr, hashBuf.size);
if (block.ptr && block.size > 0) hash.Update( block.ptr , block.size);
CryptoPP::SecByteBlock buffer(hash.DigestSize());
hash.Final(buffer);
return _buf(buffer.BytePtr(), buffer.SizeInBytes());
}
else if (algorithm == CRYPT_METHOD::SHA256)
{
CryptoPP::SHA256 hash;
if (hashBuf.ptr && hashBuf.size > 0) hash.Update( hashBuf.ptr, hashBuf.size);
if (block.ptr && block.size > 0) hash.Update( block.ptr , block.size);
CryptoPP::SecByteBlock buffer(hash.DigestSize());
hash.Final(buffer);
return _buf(buffer.BytePtr(), buffer.SizeInBytes());
}
else if (algorithm == CRYPT_METHOD::SHA512)
{
CryptoPP::SHA512 hash;
if (hashBuf.ptr && hashBuf.size > 0) hash.Update( hashBuf.ptr, hashBuf.size);
if (block.ptr && block.size > 0) hash.Update( block.ptr , block.size);
CryptoPP::SecByteBlock buffer(hash.DigestSize());
hash.Final(buffer);
return _buf(buffer.BytePtr(), buffer.SizeInBytes());
}
else
return _buf();
}
_buf GenerateKey(_buf & salt, _buf & password, _buf & blockKey, int hashSize, int spin, CRYPT_METHOD::_hashAlgorithm algorithm)
{
_buf pHashBuf = HashAppend(salt, password, algorithm);
for (int i = 0; i < spin; i++)
{
pHashBuf = HashAppend(_buf((unsigned char*)&i, 4, false), pHashBuf, algorithm);
}
pHashBuf = HashAppend(pHashBuf, blockKey, algorithm);
CorrectHashSize(pHashBuf, hashSize, 0x36);
return _buf(pHashBuf.ptr, pHashBuf.size);
}
bool DecryptAES(_buf & key, _buf & iv, _buf & data_inp, _buf & data_out)
{
CryptoPP::AES::Decryption aesDecryption(key.ptr, key.size);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv.ptr );
if (!data_out.ptr)
{
data_out = _buf(data_inp.size);
}
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( data_out.ptr, data_out.size), CryptoPP::StreamTransformationFilter::NO_PADDING);
stfDecryptor.Put( data_inp.ptr, data_inp.size );
stfDecryptor.MessageEnd();
return true;
}
bool ECMADecryptor::SetPassword(std::wstring password_)
{
password = password_;
_buf pPassword ((unsigned char*)password.c_str() , password.length() * 2);
_buf pSalt ((unsigned char*)cryptData.saltValue.c_str() , cryptData.saltValue.length());
_buf pInputBlockKey ((unsigned char*)encrVerifierHashInputBlockKey , 8);
_buf pValueBlockKey ((unsigned char*)encrVerifierHashValueBlockKey , 8);
_buf pEncVerInput ((unsigned char*)cryptData.encryptedVerifierInput.c_str() , cryptData.encryptedVerifierInput.length());
_buf pEncVerValue ((unsigned char*)cryptData.encryptedVerifierValue.c_str() , cryptData.encryptedVerifierValue.length());
_buf verifierInputKey = GenerateKey( pSalt, pPassword, pInputBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm );
_buf decryptedVerifierHashInputBytes;
DecryptAES(verifierInputKey, pSalt, pEncVerInput, decryptedVerifierHashInputBytes);
//--------------------------------------------
_buf hashBuf = HashAppend(decryptedVerifierHashInputBytes, _buf(), cryptData.hashAlgorithm);
//--------------------------------------------
_buf decryptedVerifierHashBytes;
_buf verifierHashKey = GenerateKey(pSalt, pPassword, pValueBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm);
DecryptAES(verifierHashKey, pSalt, pEncVerValue, decryptedVerifierHashBytes);
return (decryptedVerifierHashBytes==hashBuf);
}
void ECMADecryptor::SetCryptData(_cryptData &data)
{
cryptData = data;
}
void ECMADecryptor::Decrypt(unsigned char* data_inp, int size, unsigned char*& data_out)
{
data_out = NULL;
_buf pBlockKey ((unsigned char*)encrKeyValueBlockKey, 8);
_buf pPassw ((unsigned char*)password.c_str(), password.length() * 2);
_buf pDataSalt ((unsigned char*)cryptData.dataSaltValue.c_str(), cryptData.dataSaltValue.length());
_buf pSalt ((unsigned char*)cryptData.saltValue.c_str(), cryptData.saltValue.length());
_buf pKeyValue ((unsigned char*)cryptData.encryptedKeyValue.c_str(), cryptData.encryptedKeyValue.length());
_buf Key = GenerateKey( pSalt, pPassw, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm);
_buf pDecryptedKey;
DecryptAES( Key, pSalt, pKeyValue, pDecryptedKey);
_buf iv(cryptData.blockSize);
memset( iv.ptr, 0x00, cryptData.blockSize );
int i = 0, sz = 4096, pos = 0;
data_out = new unsigned char[size];
while (pos < size)
{
if (pos + sz > size)
sz = size - pos;
_buf pIndex((unsigned char*)&i, 4);
iv = HashAppend(pDataSalt, pIndex, cryptData.hashAlgorithm);
CorrectHashSize(iv, cryptData.blockSize, 0x36);
_buf pInp(data_inp + pos, sz, false);
_buf pOut(data_out + pos, sz, false);
DecryptAES(pDecryptedKey, iv, pInp, pOut);
pos += sz; i++;
}
}
\ No newline at end of file
......@@ -34,36 +34,76 @@
#include <string>
#include <vector>
class Decryptor
namespace CRYPT_METHOD
{
enum _hashAlgorithm
{
SHA1,
SHA224,
SHA256,
SHA384,
SHA512
};
enum _cipherAlgorithm
{
XOR,
RC4,
AES_CBC,
AES_CFB
};
}
class ECMADecryptor
{
public:
Decryptor(int type);
virtual ~Decryptor();
void Decrypt(void* data, int size);
struct _cryptData
{
CRYPT_METHOD::_cipherAlgorithm cipherAlgorithm;
CRYPT_METHOD::_hashAlgorithm hashAlgorithm;
int spinCount;
int keySize;
int hashSize;
int blockSize;
int saltSize;
std::string dataSaltValue;
std::string saltValue;
std::string encryptedKeyValue;
std::string encryptedVerifierInput;
std::string encryptedVerifierValue;
std::string encryptedHmacKey;
std::string encryptedHmacValue;
//..........
bool IsVerify();
};
ECMADecryptor();
virtual ~ECMADecryptor(){}
void Decrypt(unsigned char* data, int size, unsigned char*& data_out);
bool IsVerify(){}
bool SetPassword(std::wstring password);
void SetCryptData(std::string salt, std::string verifier, std::string verifier_hash);
void SetCryptData(_cryptData &data);
private:
void *impl_;
_cryptData cryptData;
std::wstring password;
};
//
//class Encryptor
//class ECMAEncryptor
//{
//public:
// Encryptor(int type);
// virtual ~Encryptor();
// ECMAEncryptor(int type);
// virtual ~ECMAEncryptor();
//
// void Encrypt(char* data, int size);
//
// bool SetPassword(std::wstring password);
//
//private:
//
// void *impl_;
//};
\ No newline at end of file
......@@ -31,12 +31,13 @@
*/
#include "ECMACryptReader.h"
#include "CryptTransform.h"
#include "../../Common/3dParty/pole/pole.h"
#include "../../Common/DocxFormat/Source/Base/Types_32.h"
#include "../../Common/DocxFormat/Source/XML/xmlutils.h"
#include "../../OfficeCryptTransform/CryptTransform.h"
#include "../../DesktopEditor/common/File.h"
#define WritingElement_ReadAttributes_Start(Reader) \
if ( Reader.GetAttributesCount() <= 0 )\
......@@ -106,10 +107,25 @@ void ReadMapEntry(POLE::Stream *pStream, ECMACryptReader::_mapEntry & m)
}
m.dataSpaceName= ReadUnicodeLP(pStream);
}
std::string DecodeBase64(const std::string & value)
{
int nLength = 0;
unsigned char *pData = NULL;
std::string result;
NSFile::CBase64Converter::Decode(value.c_str(), value.length(), pData, nLength);
if (pData)
{
result = std::string((char*)pData, nLength);
delete []pData; pData = NULL;
}
return result;
}
//--------------------------------------------------------------
bool ECMACryptReader::DecryptOfficeFile(std::wstring file_name, std::wstring folder_out, std::wstring password)
bool ECMACryptReader::DecryptOfficeFile(std::wstring file_name_inp, std::wstring file_name_out, std::wstring password)
{
POLE::Storage *pStorage = new POLE::Storage(file_name.c_str());
POLE::Storage *pStorage = new POLE::Storage(file_name_inp.c_str());
if (!pStorage)return false;
......@@ -148,15 +164,44 @@ bool ECMACryptReader::DecryptOfficeFile(std::wstring file_name, std::wstring fol
}
}
//Decryptor decryptor(1);
ECMADecryptor decryptor;
//decryptor.SetCryptData(keyData.saltValue, keyData.encryptedVerifierHashInput, keyData.encryptedVerifierHashValue);
ECMADecryptor::_cryptData cryptData;
cryptData.spinCount = atoi(keyEncryptors[0].spinCount.c_str());
cryptData.blockSize = atoi(keyEncryptors[0].blockSize.c_str());
cryptData.hashSize = atoi(keyEncryptors[0].hashSize.c_str());
cryptData.saltSize = atoi(keyEncryptors[0].saltSize.c_str());
cryptData.keySize = atoi(keyEncryptors[0].keyBits.c_str() ) / 8;
cryptData.dataSaltValue = DecodeBase64(keyData.saltValue);
cryptData.saltValue = DecodeBase64(keyEncryptors[0].saltValue);
cryptData.encryptedKeyValue = DecodeBase64(keyEncryptors[0].encryptedKeyValue);
cryptData.encryptedVerifierInput = DecodeBase64(keyEncryptors[0].encryptedVerifierHashInput);
cryptData.encryptedVerifierValue = DecodeBase64(keyEncryptors[0].encryptedVerifierHashValue);
cryptData.encryptedHmacKey = DecodeBase64(dataIntegrity.encryptedHmacKey);
cryptData.encryptedHmacValue = DecodeBase64(dataIntegrity.encryptedHmacValue);
if (keyData.cipherAlgorithm == "AES")
{
if (keyData.cipherChaining == "ChainingModeCBC") cryptData.cipherAlgorithm = CRYPT_METHOD::AES_CBC;
if (keyData.cipherChaining == "ChainingModeCFB") cryptData.cipherAlgorithm = CRYPT_METHOD::AES_CFB;
}
else
{
}
//if (!decryptor.SetPassword(password))
//{
// delete pStorage;
// return false;
//}
if (keyData.hashAlgorithm == "SHA1") cryptData.hashAlgorithm = CRYPT_METHOD::SHA1;
if (keyData.hashAlgorithm == "SHA224") cryptData.hashAlgorithm = CRYPT_METHOD::SHA224;
if (keyData.hashAlgorithm == "SHA256") cryptData.hashAlgorithm = CRYPT_METHOD::SHA256;
if (keyData.hashAlgorithm == "SHA384") cryptData.hashAlgorithm = CRYPT_METHOD::SHA384;
if (keyData.hashAlgorithm == "SHA512") cryptData.hashAlgorithm = CRYPT_METHOD::SHA512;
decryptor.SetCryptData(cryptData);
if (!decryptor.SetPassword(password))
return false;
//pStream = new POLE::Stream(pStorage, "DataSpaces/DataSpaceMap"); //
//if (pStream)
......@@ -179,27 +224,36 @@ bool ECMACryptReader::DecryptOfficeFile(std::wstring file_name, std::wstring fol
bool result = false;
pStream = new POLE::Stream(pStorage, "EncryptionPackage");
if (pStream)
pStream = new POLE::Stream(pStorage, "EncryptedPackage");
if (pStream->size() > 0)
{
_UINT64 length;
pStream->read((unsigned char*)&length, 8);
_UINT64 lengthData, lengthRead = pStream->size() - 8;
pStream->read((unsigned char*)&lengthData, 8);
while (true)
{
break;
}
unsigned char* data = new unsigned char[lengthRead];
unsigned char* data_out = NULL;
pStream->read(data, lengthRead);
decryptor.Decrypt(data, lengthRead, data_out);//todoo
delete pStream;
}
//-------------------------------------------------------------------
if (data_out)
{
NSFile::CFileBinary f;
f.CreateFile(file_name_out);
f.WriteFile(data_out, lengthData);
f.CloseFile();
result = true;
}
}
//-------------------------------------------------------------------
delete pStorage;
return result;
}
bool ECMACryptReader::ReadEncryptionInfo(const std::string & xml_string)
{
XmlUtils::CXmlLiteReader xmlReader;
......@@ -217,44 +271,55 @@ bool ECMACryptReader::ReadEncryptionInfo(const std::string & xml_string)
if ( L"keyData" == sName )
{
WritingElement_ReadAttributes_Start( xmlReader)
WritingElement_ReadAttributes_Read_if ( xmlReader, "saltSize", keyData.saltSize )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "blockSize", keyData.blockSize )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "keyBits", keyData.keyBits )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "hashSize", keyData.hashSize )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "cipherAlgorithm", keyData.cipherAlgorithm )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "cipherChaining", keyData.cipherChaining )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "hashAlgorithm", keyData.hashAlgorithm )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "saltValue", keyData.saltValue )
WritingElement_ReadAttributes_Read_if ( xmlReader, "saltSize", keyData.saltSize )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "blockSize", keyData.blockSize )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "keyBits", keyData.keyBits )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "hashSize", keyData.hashSize )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "cipherAlgorithm", keyData.cipherAlgorithm )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "cipherChaining", keyData.cipherChaining )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "hashAlgorithm", keyData.hashAlgorithm )
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "saltValue", keyData.saltValue )
WritingElement_ReadAttributes_End( xmlReader )
}
else if ( L"dataIntegrity" == sName )
{
WritingElement_ReadAttributes_Start( xmlReader)
WritingElement_ReadAttributes_Read_if ( xmlReader, "encryptedHmacKey", dataIntegrity.encryptedHmacKey)
WritingElement_ReadAttributes_Read_else_if ( xmlReader, "encryptedHmacValue", dataIntegrity.encryptedHmacValue)
WritingElement_ReadAttributes_End( xmlReader )
}
else if (L"keyEncryptors" == sName)
{
while( xmlReader.ReadNextSiblingNode( nCurDepth + 1 ) )
{
if (L"keyEncryptor" == sName)
sName = xmlReader.GetName();
if (L"keyEncryptor" == sName)
{
_keyEncryptor k;
WritingElement_ReadAttributes_Start( xmlReader)
WritingElement_ReadAttributes_Read_if ( xmlReader, "spinCount", k.spinCount )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "saltSize", k.saltSize )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "blockSize", k.blockSize )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "keyBits", k.keyBits )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "hashSize", k.hashSize )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "cipherAlgorithm", k.cipherAlgorithm )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "cipherChaining", k.cipherChaining )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "hashAlgorithm", k.hashAlgorithm )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "saltValue", k.saltValue )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "encryptedVerifierHashInput", k.encryptedVerifierHashInput )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "encryptedVerifierHashValue", k.encryptedVerifierHashValue )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "encryptedKeyValue", k.encryptedKeyValue )
WritingElement_ReadAttributes_End( xmlReader )
keyEncryptors.push_back(k);
while( xmlReader.ReadNextSiblingNode( nCurDepth + 2 ) )
{
sName = xmlReader.GetName();
if (L"p:encryptedKey" == sName)
{
_keyEncryptor k={};
WritingElement_ReadAttributes_Start( xmlReader)
WritingElement_ReadAttributes_Read_if ( xmlReader, "spinCount", k.spinCount )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "saltSize", k.saltSize )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "blockSize", k.blockSize )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "keyBits", k.keyBits )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "hashSize", k.hashSize )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "cipherAlgorithm", k.cipherAlgorithm )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "cipherChaining", k.cipherChaining )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "hashAlgorithm", k.hashAlgorithm )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "saltValue", k.saltValue )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "encryptedVerifierHashInput", k.encryptedVerifierHashInput )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "encryptedVerifierHashValue", k.encryptedVerifierHashValue )
WritingElement_ReadAttributes_Read_else_if( xmlReader, "encryptedKeyValue", k.encryptedKeyValue )
WritingElement_ReadAttributes_End( xmlReader )
keyEncryptors.push_back(k);
}
}
}
}
}
......
......@@ -36,10 +36,9 @@
class ECMACryptReader
{
public:
bool DecryptOfficeFile(std::wstring file_name, std::wstring folder_out, std::wstring password);
public:
bool DecryptOfficeFile(std::wstring file_name_inp, std::wstring file_name_out, std::wstring password);
struct _keyEncryptor
{
std::string spinCount;
......@@ -57,6 +56,12 @@ public:
std::string encryptedVerifierHashValue;
std::string encryptedKeyValue;
};
struct _dataIntegrity
{
std::string encryptedHmacKey;
std::string encryptedHmacValue;
};
struct _refComponent
{
int type;
......@@ -74,8 +79,6 @@ private:
std::vector<_mapEntry> mapEntries;
//--------------------------------------------------------------
_keyEncryptor keyData;
std::string encryptedHmacKey;
std::string encryptedHmacValue;
_dataIntegrity dataIntegrity;
std::vector<_keyEncryptor> keyEncryptors;
};
......@@ -2,7 +2,7 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="ECMACryptReader"
Name="OfficeFileCrypt"
ProjectGUID="{C27E9A9F-3A17-4482-9C5F-BF15C01E747C}"
RootNamespace="ECMACryptReader"
Keyword="Win32Proj"
......@@ -142,11 +142,11 @@
</References>
<Files>
<File
RelativePath="..\..\OfficeCryptTransform\CryptTransform.cpp"
RelativePath="..\source\CryptTransform.cpp"
>
</File>
<File
RelativePath="..\..\OfficeCryptTransform\CryptTransform.h"
RelativePath="..\source\CryptTransform.h"
>
</File>
<File
......
/*
* (c) Copyright Ascensio System SIA 2010-2016
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "CryptTransform.h"
......@@ -1240,7 +1240,7 @@ namespace NExtractTools
return AVS_FILEUTILS_ERROR_CONVERT;
}
int mscrypt2oot (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, const InputParams& params)
int mscrypt2oot (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, InputParams& params)
{
std::wstring sResultOotDir = sTemp + FILE_SEPARATOR_STR + _T("oot_unpacked");
std::wstring sResultOotFileEditor = sResultOotDir + FILE_SEPARATOR_STR + _T("Editor.bin");
......@@ -1256,22 +1256,54 @@ namespace NExtractTools
return nRes;
}
int mscrypt2oox (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, InputParams& params)
{
if (!params.m_sPassword) return AVS_FILEUTILS_ERROR_CONVERT_DRM;
if ( params.m_sPassword->empty()) return AVS_FILEUTILS_ERROR_CONVERT_DRM;
//decrypt to sTo
ECMACryptReader cryptReader;
if (cryptReader.DecryptOfficeFile(sFrom, sTo, *params.m_sPassword) == false)
return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD;
int mscrypt2oot_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, const InputParams& params)
return S_OK;
}
int mscrypt2oot_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, InputParams& params)
{
if (!params.m_sPassword) return AVS_FILEUTILS_ERROR_CONVERT_DRM;
if ( params.m_sPassword->empty()) return AVS_FILEUTILS_ERROR_CONVERT_DRM;
//decrypt to temp
std::wstring sResultDecryptDir = sTemp + FILE_SEPARATOR_STR + _T("crypt_unpacked");
FileSystem::Directory::CreateDirectory(sResultDecryptDir);
//decrypt to temp file
std::wstring sResultDecryptFile = sTemp + FILE_SEPARATOR_STR + L"uncrypt_file.oox";
ECMACryptReader cryptReader;
if (cryptReader.DecryptOfficeFile(sFrom, sResultDecryptDir, *params.m_sPassword) == false)
if (cryptReader.DecryptOfficeFile(sFrom, sResultDecryptFile, *params.m_sPassword) == false)
return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD;
//convert from format (detect before) to temp binary folder
return 0;
COfficeFileFormatChecker OfficeFileFormatChecker;
if (OfficeFileFormatChecker.isOfficeFile(sResultDecryptFile))
{
switch (OfficeFileFormatChecker.nFileType)
{
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX:
{
return docx2doct_bin(sResultDecryptFile, sTo, sTemp, sFontPath);
}break;
case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX:
{
const std::wstring & sXmlOptions = params.getXmlOptions();
return xlsx2xlst_bin(sResultDecryptFile, sTo, sTemp, sFontPath, sXmlOptions);
}break;
case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX:
case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX:
{
return pptx2pptt_bin(sResultDecryptFile, sTo, sTemp, sFontPath);
}break;
}
}
return AVS_FILEUTILS_ERROR_CONVERT;
}
//html
......
......@@ -115,8 +115,9 @@ namespace NExtractTools
int xlsx2ods (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath);
int xlsx_dir2ods (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath);
int mscrypt2oot (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, const InputParams& params);
int mscrypt2oot_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, const InputParams& params);
int mscrypt2oox (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, const InputParams& params);
int mscrypt2oot (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, InputParams& params);
int mscrypt2oot_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, const std::wstring &sFontPath, InputParams& params);
//-------------------------------------------------------------------------------------------------------------------------------------------------
int dir2zip (const std::wstring &sFrom, const std::wstring &sTo);
......
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