Commit 0d261b87 authored by ElenaSubbotina's avatar ElenaSubbotina

XlsFormat - небольшой рефакторинг дешифрования

parent 4ea68435
......@@ -336,6 +336,14 @@
<File
RelativePath=".\ASCOfficeXlsFileTest.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
......
......@@ -32,8 +32,6 @@
#include "CFStream.h"
#include "CFRecordType.h"
//#include <Exception/CompoundFileFormatError.h>
//#include <Exception/EndOfStreamReached.h>
#include <boost/bind.hpp>
......@@ -47,7 +45,7 @@ CFStream::CFStream(POLE::Stream* stream)
{
if(NULL == stream)
{
return; // throw;EXCEPT::RT::CompoundFileFormatError("Wrong IStream pointer (NULL)");
return; // Wrong IStream pointer (NULL)
}
stream_ = stream;
}
......@@ -65,15 +63,14 @@ void CFStream::read(void* buf, const size_t size)
{
if(NULL == buf || stream_ == NULL)
{
return;//throw;EXCEPT::RT::CompoundFileFormatError("Wrong buffer pointer (NULL)");
return;// Wrong buffer pointer (NULL)
}
POLE::uint64 num_read = stream_->read((unsigned char*)buf, size);
if(num_read < size)
{
return;//throw; EXCEPT::RT::EndOfStreamReached(stream_->fullName(), num_read, size);
return;// EndOfStreamReached
}
// Tipa successful
}
......
......@@ -35,8 +35,9 @@ namespace CRYPT
{
BiffDecoderBase::BiffDecoderBase() : mbValid(false)
BiffDecoderBase::BiffDecoderBase(int BLOCKSIZE) : mbValid(false)
{
RCF_BLOCKSIZE = BLOCKSIZE;
}
......@@ -63,22 +64,22 @@ void BiffDecoderBase::decode(unsigned char* pnDestData, const unsigned char* pnS
}
}
/** Returns the block index of the passed stream position for RCF decryption. */
int lclGetRcfBlock(long nStreamPos)
int BiffDecoderBase::lclGetRcfBlock(long nStreamPos)
{
return static_cast<int>(nStreamPos / BIFF_RCF_BLOCKSIZE);
return static_cast<int>(nStreamPos / RCF_BLOCKSIZE);
}
/** Returns the offset of the passed stream position in a block for RCF decryption. */
int lclGetRcfOffset(long nStreamPos)
int BiffDecoderBase::lclGetRcfOffset(long nStreamPos)
{
return static_cast<int>(nStreamPos % BIFF_RCF_BLOCKSIZE);
return static_cast<int>(nStreamPos % RCF_BLOCKSIZE);
}
BiffDecoder_RCF::BiffDecoder_RCF(unsigned char pnSalt[16], unsigned char pnVerifier[16], unsigned char pnVerifierHash[16])
: maPassword(16, 0),
BiffDecoder_RCF::BiffDecoder_RCF(unsigned char pnSalt[16], unsigned char pnVerifier[16], unsigned char pnVerifierHash[16], int BlockSize)
: BiffDecoderBase(BlockSize),
maPassword(16, 0),
maSalt(pnSalt, pnSalt + 16),
maVerifier(pnVerifier, pnVerifier + 16),
maVerifierHash(pnVerifierHash, pnVerifierHash + 16)
......@@ -120,7 +121,7 @@ void BiffDecoder_RCF::implDecode(unsigned char* pnDestData, const unsigned char*
maCodec.skip(lclGetRcfOffset(nCurrPos));
// decode the block
unsigned short nBlockLeft = static_cast<unsigned short>(BIFF_RCF_BLOCKSIZE - lclGetRcfOffset(nCurrPos));
unsigned short nBlockLeft = static_cast<unsigned short>(get_BLOCKSIZE() - lclGetRcfOffset(nCurrPos));
unsigned short nDecBytes = nBytesLeft < nBlockLeft ? nBytesLeft : nBlockLeft;
maCodec.decode(pnCurrDest, pnCurrSrc, static_cast<int>(nDecBytes));
......
......@@ -40,15 +40,15 @@
namespace CRYPT
{
const long BIFF_RCF_BLOCKSIZE = 1024;
/** Base class for BIFF stream decoders. */
class BiffDecoderBase //: public ::comphelper::IDocPasswordVerifier
class BiffDecoderBase
{
public:
explicit BiffDecoderBase();
explicit BiffDecoderBase(int BLOCKSIZE);
virtual ~BiffDecoderBase();
int get_BLOCKSIZE(){return RCF_BLOCKSIZE;}
/** Implementation of the ::comphelper::IDocPasswordVerifier interface,
calls the new virtual function implVerify(). */
virtual bool verifyPassword( const std::wstring& rPassword );
......@@ -59,7 +59,13 @@ public:
/** Decodes nBytes unsigned chars and writes encrypted data into the buffer pnDestData. */
void decode(unsigned char* pnDestData, const unsigned char* pnSrcData, const long nStreamPos, const unsigned short nBytes);
int lclGetRcfBlock(long nStreamPos);
int lclGetRcfOffset(long nStreamPos);
private:
int RCF_BLOCKSIZE;
/** Derived classes implement password verification and initialization of
the decoder. */
virtual bool implVerify(const std::wstring& rPassword) = 0;
......@@ -77,7 +83,7 @@ typedef ::boost::shared_ptr<BiffDecoderBase> BiffDecoderRef;
class BiffDecoder_RCF : public BiffDecoderBase
{
public:
explicit BiffDecoder_RCF(unsigned char pnSalt[ 16 ], unsigned char pnVerifier[ 16 ], unsigned char pnVerifierHash[ 16 ]);
explicit BiffDecoder_RCF(unsigned char pnSalt[ 16 ], unsigned char pnVerifier[ 16 ], unsigned char pnVerifierHash[ 16 ], int BlockSize);
private:
......
......@@ -33,9 +33,36 @@
#include <string>
#include <boost/shared_ptr.hpp>
#include "../../../Common/DocxFormat/Source/Base/Types_32.h"
namespace CRYPT
{
struct CryptRC4Data
{
struct SALT_TAG
{
_UINT32 b1;
_UINT32 b2;
_UINT32 b3;
_UINT32 b4;
} Salt;
struct ENCRYPTED_VERIFIER_TAG
{
_UINT32 b1;
_UINT32 b2;
_UINT32 b3;
_UINT32 b4;
} EncryptedVerifier;
struct ENCRYPTED_VERIFIER_HASH_TAG
{
_UINT32 b1;
_UINT32 b2;
_UINT32 b3;
_UINT32 b4;
} EncryptedVerifierHash;
};
class Crypt
{
......@@ -57,5 +84,4 @@ public:
typedef boost::shared_ptr<Crypt> CryptPtr;
} // namespace CRYPT
......@@ -34,16 +34,15 @@
#include "Decryptor.h"
#include "RC4Crypt.h"
#include <Logic/Biff_structures/RC4EncryptionHeader.h>
//#include <Logic/Biff_structures/RC4CryptoAPIEncryptionHeader.h>
namespace CRYPT
{
Decryptor::Decryptor(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password) :
crypt (new RC4Crypt(header, password)),
Decryptor::Decryptor(CryptRC4Data & header, std::wstring password, int type) :
crypt (new RC4Crypt(header, password, type)),
type (Crypt::RC4)
{
crypt_header = header;
crypt_data = header;
}
void Decryptor::Decrypt(char* data, const size_t size, const unsigned long stream_pos)
......@@ -59,7 +58,7 @@ namespace CRYPT
bool Decryptor::SetPassword(std::wstring password)
{
crypt.reset();
crypt = CryptPtr(new RC4Crypt(crypt_header, password));
crypt = CryptPtr(new RC4Crypt(crypt_data, password, 1));
if (crypt) return crypt->IsVerify();
else return false;
......
......@@ -33,20 +33,12 @@
#include "Crypt.h"
namespace CRYPTO
{
class RC4EncryptionHeader;
typedef boost::shared_ptr<RC4EncryptionHeader> RC4EncryptionHeaderPtr;
} // namespace CRYPTO
namespace CRYPT
{
class Decryptor
{
public:
Decryptor(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password);
Decryptor(CryptRC4Data & header, std::wstring password, int type);
void Decrypt(char* data, const size_t size, const unsigned long stream_pos);
......@@ -57,7 +49,7 @@ public:
private:
CryptPtr crypt;
Crypt::crypt_type type;
CRYPTO::RC4EncryptionHeaderPtr crypt_header;
CryptRC4Data crypt_data;
};
typedef boost::shared_ptr<Decryptor> DecryptorPtr;
......
......@@ -38,17 +38,18 @@
namespace CRYPT
{
RC4Crypt::RC4Crypt(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password)
RC4Crypt::RC4Crypt(CRYPT::CryptRC4Data & data, std::wstring password, int type)
{
m_VerifyPassword = false;
if (!header) return;
CopyDWORDs2Bytes(data.Salt.b1, data.Salt.b2, data.Salt.b3, data.Salt.b4, pnSalt);
CopyDWORDs2Bytes(data.EncryptedVerifier.b1 , data.EncryptedVerifier.b2, data.EncryptedVerifier.b3, data.EncryptedVerifier.b4, pnVerifier);
CopyDWORDs2Bytes(data.EncryptedVerifierHash.b1, data.EncryptedVerifierHash.b2, data.EncryptedVerifierHash.b3, data.EncryptedVerifierHash.b4, pnVerifierHash);
CopyDWORDs2Bytes(header->Salt.b1, header->Salt.b2, header->Salt.b3, header->Salt.b4, pnSalt);
CopyDWORDs2Bytes(header->EncryptedVerifier.b1 , header->EncryptedVerifier.b2, header->EncryptedVerifier.b3, header->EncryptedVerifier.b4, pnVerifier);
CopyDWORDs2Bytes(header->EncryptedVerifierHash.b1, header->EncryptedVerifierHash.b2, header->EncryptedVerifierHash.b3, header->EncryptedVerifierHash.b4, pnVerifierHash);
int BlockSize = 1024;
//if (type == 1) BlockSize = 256;
mxDecoder.reset(new BiffDecoder_RCF(pnSalt, pnVerifier, pnVerifierHash));
mxDecoder.reset(new BiffDecoder_RCF(pnSalt, pnVerifier, pnVerifierHash, BlockSize));
m_VerifyPassword = mxDecoder->verifyPassword(password);
}
......
......@@ -41,7 +41,7 @@ namespace CRYPT
class RC4Crypt : public Crypt
{
public:
RC4Crypt(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password);
RC4Crypt(CRYPT::CryptRC4Data & data, std::wstring password, int type);
virtual void Encrypt(char* data, const size_t size);
virtual void Decrypt(char* data, const size_t size, const unsigned long stream_pos);
......
......@@ -31,7 +31,6 @@
*/
#include "FilePass.h"
//#include <Exception/FileIsEncrypted.h>
#include <Crypt/Decryptor.h>
namespace XLS
......@@ -72,7 +71,6 @@ void FilePass::readFields(CFRecord& record)
{
record >> key;
Log::info("FilePass: Encryption type: XOR");
//throw EXCEPT::STOP::FileIsEncrypted();
return;
}
else
......@@ -88,7 +86,7 @@ void FilePass::readFields(CFRecord& record)
rc4HeaderPtr->load (record);
record.getGlobalWorkbookInfo()->decryptor =
CRYPT::DecryptorPtr(new CRYPT::Decryptor(rc4HeaderPtr, record.getGlobalWorkbookInfo()->password));
CRYPT::DecryptorPtr(new CRYPT::Decryptor(rc4HeaderPtr->RC4Data, record.getGlobalWorkbookInfo()->password, 2));
Log::info("Encryption type: RC4 Standard");
}
......
......@@ -109,7 +109,7 @@ void BiffString::load(CFRecord& record, const size_t cch1, const bool is_wide1)
if (record.checkFitRead(raw_length)==false)
{
//ОЎИБ А - нехватило Continue records - нужно найти место где именно и подзагрузить
//ОШИБКА - нехватило Continue records - нужно найти место где именно и подзагрузить
return;
}
......
......@@ -36,13 +36,11 @@
#include "../XlsElementsType.h"
#include <common.h>
#include <Logging/Log.h>
#include "../../../Common/common.h"
#include "../../Logging/Log.h"
#include "../../Binary/CFRecord.h"
namespace XLS
{
......
......@@ -73,7 +73,7 @@ void ExtRst::load(CFRecord& record)
size_t data_end = record.getRdPtr();
if(data_end - data_start != cb)
{
//ОЎИБ А - нехватило Continue records - нужно найти место где именно и подзагрузить
//ОШИБКА - нехватило Continue records - нужно найти место где именно и подзагрузить
if ((data_end - data_start) < cb )
record.skipNunBytes( cb - (data_end - data_start)); // trash for unknown reason
else
......
......@@ -54,9 +54,10 @@ void RC4EncryptionHeader::store(XLS::CFRecord& record)
void RC4EncryptionHeader::load(XLS::CFRecord& record)
{
record >> EncryptionVersionInfo;
record.loadAnyData(Salt);
record.loadAnyData(EncryptedVerifier);
record.loadAnyData(EncryptedVerifierHash);
record.loadAnyData(RC4Data.Salt);
record.loadAnyData(RC4Data.EncryptedVerifier);
record.loadAnyData(RC4Data.EncryptedVerifierHash);
}
......
......@@ -33,11 +33,10 @@
#include "BiffStructure.h"
#include <Logic/Biff_structures/BitMarkedStructs.h>
#include "../../Crypt/Crypt.h"
namespace CRYPTO
{
class RC4EncryptionHeader : public XLS::BiffStructure
{
BASE_STRUCTURE_DEFINE_CLASS_NAME(RC4EncryptionHeader)
......@@ -50,30 +49,7 @@ public:
static const XLS::ElementType type = XLS::typeRC4EncryptionHeader;
Version EncryptionVersionInfo;
struct SALT_TAG
{
_UINT32 b1;
_UINT32 b2;
_UINT32 b3;
_UINT32 b4;
} Salt;
struct ENCRYPTED_VERIFIER_TAG
{
_UINT32 b1;
_UINT32 b2;
_UINT32 b3;
_UINT32 b4;
} EncryptedVerifier;
struct ENCRYPTED_VERIFIER_HASH_TAG
{
_UINT32 b1;
_UINT32 b2;
_UINT32 b3;
_UINT32 b4;
} EncryptedVerifierHash;
CRYPT::CryptRC4Data RC4Data;
};
typedef boost::shared_ptr<RC4EncryptionHeader> RC4EncryptionHeaderPtr;
......
......@@ -57,12 +57,12 @@ PropertySet::PropertySet(XLS::CFStreamPtr stream, const unsigned int property_se
PropertyIdentifierAndOffset prop_offset;
*stream >> prop_offset;
if (prop_offset.Offset - property_set_offset > Size)
if (prop_offset.Offset/* - property_set_offset*/ > Size)
break;
prop_offsets.push_back(prop_offset);
}
code_page = PropertyCodePage::DefaultCodePage;
code_page = 0;
for(unsigned int i = 0; i < prop_offsets.size(); ++i)
{
if (stream->getStreamPointer() - property_set_offset > Size)
......
......@@ -113,7 +113,7 @@ HRESULT COfficeXlsFile::LoadFromFile(BSTR sSrcFileName, BSTR sDstPath, BSTR sXML
#if defined(STANDALONE_USE) && (STANDALONE_USE == 1)
// в случае если на выходе файл Ч стираем временную директорию (мы сами ее создали)
// в случае если на выходе файл стираем временную директорию (мы сами ее создали)
try
{
FileSystem::Directory::DeleteDirectory(dstTempPath);
......
......@@ -1974,6 +1974,14 @@
<File
RelativePath="..\Source\DocxFormat\Logic\Vml.cpp"
>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
......@@ -2063,6 +2071,14 @@
<File
RelativePath="..\Source\DocxFormat\IFileContainer.cpp"
>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\Source\DocxFormat\IFileContainer.h"
......
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