diff --git a/ASCOfficeDocFile/DocDocxConverter/FileInformationBlock.h b/ASCOfficeDocFile/DocDocxConverter/FileInformationBlock.h index 3520a034be..bf914f5a44 100644 --- a/ASCOfficeDocFile/DocDocxConverter/FileInformationBlock.h +++ b/ASCOfficeDocFile/DocDocxConverter/FileInformationBlock.h @@ -457,37 +457,37 @@ namespace DocFileFormat unsigned char flag8 = 0; //read the FIB base - this->m_FibBase.wIdent = reader.ReadUInt16(); //0 - this->m_FibBase.nFib = (FibVersion)reader.ReadUInt16(); //2 + this->m_FibBase.wIdent = reader.ReadUInt16(); //0 + this->m_FibBase.nFib = (FibVersion)reader.ReadUInt16(); //2 reader.ReadBytes( 2, false ); //4 - this->m_FibBase.lid = reader.ReadUInt16(); //6 - this->m_FibBase.pnNext = reader.ReadInt16(); //8 + this->m_FibBase.lid = reader.ReadUInt16(); //6 + this->m_FibBase.pnNext = reader.ReadInt16(); //8 flag16 = reader.ReadUInt16(); //10 - this->m_FibBase.fDot = FormatUtils::BitmaskToBool((int)flag16, 0x0001); - this->m_FibBase.fGlsy = FormatUtils::BitmaskToBool((int)flag16, 0x0002); - this->m_FibBase.fComplex = FormatUtils::BitmaskToBool((int)flag16, 0x0002); - this->m_FibBase.fHasPic = FormatUtils::BitmaskToBool((int)flag16, 0x0008); - this->m_FibBase.cQuickSaves = (WORD)(((int)flag16 & 0x00F0) >> 4); - this->m_FibBase.fEncrypted = FormatUtils::BitmaskToBool((int)flag16, 0x0100); - this->m_FibBase.fWhichTblStm = FormatUtils::BitmaskToBool((int)flag16, 0x0200); + this->m_FibBase.fDot = FormatUtils::BitmaskToBool((int)flag16, 0x0001); + this->m_FibBase.fGlsy = FormatUtils::BitmaskToBool((int)flag16, 0x0002); + this->m_FibBase.fComplex = FormatUtils::BitmaskToBool((int)flag16, 0x0002); + this->m_FibBase.fHasPic = FormatUtils::BitmaskToBool((int)flag16, 0x0008); + this->m_FibBase.cQuickSaves = (WORD)(((int)flag16 & 0x00F0) >> 4); + this->m_FibBase.fEncrypted = FormatUtils::BitmaskToBool((int)flag16, 0x0100); + this->m_FibBase.fWhichTblStm = FormatUtils::BitmaskToBool((int)flag16, 0x0200); this->m_FibBase.fReadOnlyRecommended = FormatUtils::BitmaskToBool((int)flag16, 0x0400); this->m_FibBase.fWriteReservation = FormatUtils::BitmaskToBool((int)flag16, 0x0800); - this->m_FibBase.fExtChar = FormatUtils::BitmaskToBool((int)flag16, 0x1000); - this->m_FibBase.fLoadOverwrite = FormatUtils::BitmaskToBool((int)flag16, 0x2000); - this->m_FibBase.fFarEast = FormatUtils::BitmaskToBool((int)flag16, 0x4000); - this->m_FibBase.fCrypto = FormatUtils::BitmaskToBool((int)flag16, 0x8000); - this->m_FibBase.nFibBack = reader.ReadUInt16(); //12 - this->m_FibBase.lKey = reader.ReadInt32(); //14 - this->m_FibBase.envr = reader.ReadByte(); //18 + this->m_FibBase.fExtChar = FormatUtils::BitmaskToBool((int)flag16, 0x1000); + this->m_FibBase.fLoadOverwrite = FormatUtils::BitmaskToBool((int)flag16, 0x2000); + this->m_FibBase.fFarEast = FormatUtils::BitmaskToBool((int)flag16, 0x4000); + this->m_FibBase.fCrypto = FormatUtils::BitmaskToBool((int)flag16, 0x8000); + this->m_FibBase.nFibBack = reader.ReadUInt16(); //12 + this->m_FibBase.lKey = reader.ReadInt32(); //14 + this->m_FibBase.envr = reader.ReadByte(); //18 flag8 = reader.ReadByte(); //19 - this->m_FibBase.fMac = FormatUtils::BitmaskToBool((int)flag8, 0x01); - this->m_FibBase.fEmptySpecial = FormatUtils::BitmaskToBool((int)flag8, 0x02); + this->m_FibBase.fMac = FormatUtils::BitmaskToBool((int)flag8, 0x01); + this->m_FibBase.fEmptySpecial = FormatUtils::BitmaskToBool((int)flag8, 0x02); this->m_FibBase.fLoadOverridePage = FormatUtils::BitmaskToBool((int)flag8, 0x04); this->m_FibBase.fFutureSavedUndo = FormatUtils::BitmaskToBool((int)flag8, 0x08); - this->m_FibBase.fWord97Saved = FormatUtils::BitmaskToBool((int)flag8, 0x10); + this->m_FibBase.fWord97Saved = FormatUtils::BitmaskToBool((int)flag8, 0x10); reader.ReadBytes( 4, false ); //20 - this->m_FibBase.fcMin = reader.ReadInt32(); //24 - this->m_FibBase.fcMac = reader.ReadInt32(); //28 + this->m_FibBase.fcMin = reader.ReadInt32(); //24 + this->m_FibBase.fcMac = reader.ReadInt32(); //28 this->csw = reader.ReadUInt16(); //32 diff --git a/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp b/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp index fe201c31ea..cefa13c152 100644 --- a/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp @@ -178,6 +178,9 @@ namespace DocFileFormat } } + if (FIB->m_FibBase.fEncrypted) + return AVS_ERROR_DRM; + // Get the streams if (FIB->m_FibBase.fWhichTblStm) { diff --git a/ASCOfficeXlsFile2/ASCOfficeXlsFileTest/ASCOfficeXlsFileTest.cpp b/ASCOfficeXlsFile2/ASCOfficeXlsFileTest/ASCOfficeXlsFileTest.cpp index 8f8b0202cf..807febeec7 100644 --- a/ASCOfficeXlsFile2/ASCOfficeXlsFileTest/ASCOfficeXlsFileTest.cpp +++ b/ASCOfficeXlsFile2/ASCOfficeXlsFileTest/ASCOfficeXlsFileTest.cpp @@ -26,7 +26,7 @@ int _tmain(int argc, _TCHAR* argv[]) std::wstring dstTempPath = FileSystem::Directory::CreateDirectoryWithUniqueName(outputDir); - hr = ConvertXls2Xlsx(srcFileName, dstTempPath, L"C:\\Windows\\Fonts", NULL); + hr = ConvertXls2Xlsx(srcFileName, dstTempPath, L"password1", L"C:\\Windows\\Fonts", NULL); if (hr != S_OK) return hr; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Crypt.h b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Crypt.h index 72b33c0e5e..a7fd74ae79 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Crypt.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Crypt.h @@ -1,5 +1,6 @@ #pragma once +#include #include namespace CRYPT @@ -19,6 +20,8 @@ public: XOR } crypt_type; + virtual bool IsVerify() = 0; + }; typedef boost::shared_ptr CryptPtr; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.cpp index 3e510895ae..1ce3da1d48 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.cpp @@ -8,16 +8,31 @@ namespace CRYPT { -Decryptor::Decryptor(const CRYPTO::RC4EncryptionHeader& header) -: crypt(new RC4Crypt(header)), - type(Crypt::RC4) -{ -} + Decryptor::Decryptor(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password) : + crypt (new RC4Crypt(header, password)), + type (Crypt::RC4) + { + crypt_header = header; + } -void Decryptor::Decrypt(char* data, const size_t size, const unsigned long stream_pos) -{ - crypt->Decrypt(data, size, stream_pos); -} + void Decryptor::Decrypt(char* data, const size_t size, const unsigned long stream_pos) + { + crypt->Decrypt(data, size, stream_pos); + } + + bool Decryptor::IsVerify() + { + return crypt->IsVerify(); + } + + bool Decryptor::SetPassword(std::wstring password) + { + crypt.reset(); + crypt = CryptPtr(new RC4Crypt(crypt_header, password)); + + if (crypt) return crypt->IsVerify(); + else return false; + } }; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.h b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.h index b6eeec9ea0..3a353ac075 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/Decryptor.h @@ -4,7 +4,9 @@ namespace CRYPTO { -class RC4EncryptionHeader; + class RC4EncryptionHeader; + typedef boost::shared_ptr RC4EncryptionHeaderPtr; + } // namespace CRYPTO namespace CRYPT @@ -13,13 +15,18 @@ namespace CRYPT class Decryptor { public: - Decryptor(const CRYPTO::RC4EncryptionHeader& header); + Decryptor(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password); void Decrypt(char* data, const size_t size, const unsigned long stream_pos); + bool IsVerify(); + + bool SetPassword(std::wstring password); + private: - CryptPtr crypt; - Crypt::crypt_type type; + CryptPtr crypt; + Crypt::crypt_type type; + CRYPTO::RC4EncryptionHeaderPtr crypt_header; }; typedef boost::shared_ptr DecryptorPtr; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.cpp index 48f00dd864..942a5f09b4 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.cpp @@ -7,14 +7,19 @@ namespace CRYPT { -RC4Crypt::RC4Crypt(const CRYPTO::RC4EncryptionHeader& header) + RC4Crypt::RC4Crypt(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password) { - 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); + m_VerifyPassword = false; + + if (!header) return; + + 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); + mxDecoder.reset(new BiffDecoder_RCF(pnSalt, pnVerifier, pnVerifierHash)); - mxDecoder->verifyPassword(L"VelvetSweatshop"); + m_VerifyPassword = mxDecoder->verifyPassword(password); } void RC4Crypt::Encrypt(char* data, const size_t size) @@ -22,6 +27,11 @@ void RC4Crypt::Encrypt(char* data, const size_t size) } +bool RC4Crypt::IsVerify() +{ + return m_VerifyPassword; +} + void RC4Crypt::CopyDWORDs2Bytes(const unsigned int b1, const unsigned int b2, const unsigned int b3, const unsigned int b4, unsigned char* byte_array) { byte_array[0] = static_cast((b1 & 0x000000ff) >> 0); diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.h b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.h index dfe4b286d8..760ce32ed4 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Crypt/RC4Crypt.h @@ -10,20 +10,23 @@ namespace CRYPT class RC4Crypt : public Crypt { public: - RC4Crypt(const CRYPTO::RC4EncryptionHeader& header); + RC4Crypt(CRYPTO::RC4EncryptionHeaderPtr & header, std::wstring password); virtual void Encrypt(char* data, const size_t size); virtual void Decrypt(char* data, const size_t size, const unsigned long stream_pos); + virtual bool IsVerify(); + private: void CopyDWORDs2Bytes(const unsigned int b1, const unsigned int b2, const unsigned int b3, const unsigned int b4, unsigned char* byte_array); -private: unsigned char pnSalt[16]; unsigned char pnVerifier[16]; unsigned char pnVerifierHash[16]; BiffDecoderRef mxDecoder; + + bool m_VerifyPassword; }; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.cpp index 4bf2195127..9e44c2bcfe 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.cpp @@ -45,8 +45,13 @@ void FilePass::readFields(CFRecord& record) majorVer = *record.getCurData(); if(0x0001 == majorVer) // RC4 encryption header structure { - record >> rc4Header; - record.getGlobalWorkbookInfo()->decryptor = CRYPT::DecryptorPtr(new CRYPT::Decryptor(rc4Header)); + rc4HeaderPtr = CRYPTO::RC4EncryptionHeaderPtr(new CRYPTO::RC4EncryptionHeader()); + + rc4HeaderPtr->load (record); + + record.getGlobalWorkbookInfo()->decryptor = + CRYPT::DecryptorPtr(new CRYPT::Decryptor(rc4HeaderPtr, record.getGlobalWorkbookInfo()->password)); + Log::info("Encryption type: RC4 Standard"); } else // RC4 CryptoAPI encryption header structuren diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.h index c88cb42d11..bf55febfd3 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/FilePass.h @@ -28,10 +28,11 @@ public: //----------------------------- Boolean wEncryptionType; - XORObfuscation key; - _UINT16 majorVer; - CRYPTO::RC4EncryptionHeader rc4Header; - CRYPTO::RC4CryptoAPIEncryptionHeader rc4CryptoAPIHeader; + XORObfuscation key; + _UINT16 majorVer; + + CRYPTO::RC4EncryptionHeaderPtr rc4HeaderPtr; + CRYPTO::RC4CryptoAPIEncryptionHeader rc4CryptoAPIHeader; }; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/RC4EncryptionHeader.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/RC4EncryptionHeader.h index e8295ca9cd..fa68594154 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/RC4EncryptionHeader.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/RC4EncryptionHeader.h @@ -19,19 +19,25 @@ public: static const XLS::ElementType type = XLS::typeRC4EncryptionHeader; Version EncryptionVersionInfo; - struct SALT_TAG { + + struct SALT_TAG + { _UINT32 b1; _UINT32 b2; _UINT32 b3; _UINT32 b4; } Salt; - struct ENCRYPTED_VERIFIER_TAG { + + struct ENCRYPTED_VERIFIER_TAG + { _UINT32 b1; _UINT32 b2; _UINT32 b3; _UINT32 b4; } EncryptedVerifier; - struct ENCRYPTED_VERIFIER_HASH_TAG { + + struct ENCRYPTED_VERIFIER_HASH_TAG + { _UINT32 b1; _UINT32 b2; _UINT32 b3; @@ -39,5 +45,7 @@ public: } EncryptedVerifierHash; }; + typedef boost::shared_ptr RC4EncryptionHeaderPtr; + } // namespace CRYPTO diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/BinProcessor.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/BinProcessor.cpp index 2cf6858f60..2a0bea6e37 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/BinProcessor.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/BinProcessor.cpp @@ -106,6 +106,11 @@ const bool BinReaderProcessor::readChild(BaseObject& object, const bool is_manda ret_val = object.read(reader_, parent_, is_mandatory /* log warning if mandatory tag absent*/); if(!ret_val && is_mandatory) { + if (global_info_->decryptor) + { + if (global_info_->decryptor->IsVerify() == false) + return false; + } // We don't update ret_val here because we are reading to the copy of the object. // And the real object will remain uninitialized wanted_objects.push_back(object.clone()); // store the copy of the object that was not found (this line is here to take another chance to be read after some trash processed) diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalWorkbookInfo.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalWorkbookInfo.h index d056296bef..d4521823d9 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalWorkbookInfo.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalWorkbookInfo.h @@ -47,6 +47,7 @@ public: unsigned short CodePage; CRYPT::DecryptorPtr decryptor; + std::wstring password; std::vector sheets_state; std::vector sheets_names; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalsSubstream.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalsSubstream.cpp index 76b8774f48..63d2803af0 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalsSubstream.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/GlobalsSubstream.cpp @@ -144,7 +144,17 @@ const bool GlobalsSubstream::loadContent(BinProcessor& proc) } }break; case rt_WriteProtect: proc.optional(); break; - case rt_FilePass: proc.optional(); break; + case rt_FilePass: + { + if (proc.optional()) + { + if (( proc.getGlobalWorkbookInfo()->decryptor) && + ( proc.getGlobalWorkbookInfo()->decryptor->IsVerify() == false)) + { + return false; + } + } + }break; case rt_Template: { if (proc.optional