diff options
author | Rosemary <rosemaryseb8@gmail.com> | 2015-10-04 07:58:21 +0530 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2015-10-08 17:45:52 +0200 |
commit | c597581852cf1d3550359dc639f1bb7f6476f419 (patch) | |
tree | ddccc9ffa1ef3057cbb276374bea2192b43ae543 /oox | |
parent | 56a36956ed1fee1dd53817a81bcb2241373aebdc (diff) |
Implement encryption for the VBA export
Change-Id: Id994095de9f43cf0c2857272b613abe7cbd9324e
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/ole/vbaexport.cxx | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx index eaa80788d0e1..03392034fe0a 100644 --- a/oox/source/ole/vbaexport.cxx +++ b/oox/source/ole/vbaexport.cxx @@ -47,6 +47,11 @@ #define VBA_USE_ORIGINAL_PROJECT_STREAM 0 #define VBA_USE_ORIGINAL_VBA_PROJECT 0 +#define VBA_ENCRYPTION 0 +/* Enable to see VBA Encryption work. For now the input data and length values + * for encryption correspond to the case when the VBA macro is not protected. + */ + namespace { void exportString(SvStream& rStrm, const OUString& rString) @@ -336,6 +341,105 @@ void VBACompression::write() } } +// section 2.4.3 +#if VBA_ENCRYPTION + +VBAEncryption::VBAEncryption(const sal_uInt8* pData, const sal_uInt16 length, SvStream& rEncryptedData) + :mpData(pData) + ,mnLength(length) + ,mrEncryptedData(rEncryptedData) + ,mnEncryptedByte1(0) + ,mnEncryptedByte2(0) + ,mnVersion(2) + ,mnProjKey(0) + ,mnIgnoredLength(0) + ,mnSeed(0) + ,mnVersionEnc(0) +{ +} + +void VBAEncryption::writeSeed() +{ + mnSeed = 0xBE; // sample seed value TODO:Generate random seed values + mrEncryptedData.WriteUInt8(mnSeed); +} + +void VBAEncryption::writeVersionEnc() +{ + mnVersionEnc = mnSeed ^ mnVersion; + mrEncryptedData.WriteUInt8(mnVersionEnc); +} + +void VBAEncryption::writeProjKeyEnc() +{ + OUString mrProjectCLSID = "{9F10AB9C-89AC-4C0F-8AFB-8E9B96D5F170}"; //TODO:Find the real ProjectId.ProjectClSID + sal_Int32 n = mrProjectCLSID.getLength(); + const sal_Unicode* pString = mrProjectCLSID.getStr(); + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Unicode character = pString[i]; + mnProjKey += character; + } + sal_uInt8 nProjKeyEnc = mnSeed ^ mnProjKey; + mrEncryptedData.WriteUInt8(nProjKeyEnc); + mnUnencryptedByte1 = mnProjKey; + mnEncryptedByte1 = nProjKeyEnc; // ProjKeyEnc + mnEncryptedByte2 = mnVersionEnc; // VersionEnc +} + +void VBAEncryption::writeIgnoredEnc() +{ + mnIgnoredLength = (mnSeed & 6) / 2; + for(sal_Int32 i = 1; i <= mnIgnoredLength; ++i) + { + sal_uInt8 nTempValue = 0xBE; // TODO:Generate a random value + sal_uInt8 nByteEnc = nTempValue ^ (mnEncryptedByte2 + mnUnencryptedByte1); + mrEncryptedData.WriteUInt8(nByteEnc); + mnEncryptedByte2 = mnEncryptedByte1; + mnEncryptedByte1 = nByteEnc; + mnUnencryptedByte1 = nTempValue; + } +} + +void VBAEncryption::writeDataLengthEnc() +{ + sal_uInt16 temp = mnLength; + for(sal_Int8 i = 0; i < 2; ++i) + { + sal_uInt8 nByte = temp & 0xFF; + sal_uInt8 nByteEnc = nByte ^ (mnEncryptedByte2 + mnUnencryptedByte1); + mrEncryptedData.WriteUInt8(nByteEnc); + mnEncryptedByte2 = mnEncryptedByte1; + mnEncryptedByte1 = nByteEnc; + mnUnencryptedByte1 = nByte; + temp >>= 8; + } +} + +void VBAEncryption::writeDataEnc() +{ + for(sal_Int8 i = 0; i < mnLength; i++) + { + sal_uInt8 nByteEnc = mpData[i] ^ (mnEncryptedByte2 + mnUnencryptedByte1); + mrEncryptedData.WriteUInt8(nByteEnc); + mnEncryptedByte2 = mnEncryptedByte1; + mnEncryptedByte1 = nByteEnc; + mnUnencryptedByte1 = mpData[i]; + } +} + +void VBAEncryption::write() +{ + writeSeed(); + writeVersionEnc(); + writeProjKeyEnc(); + writeIgnoredEnc(); + writeDataLengthEnc(); + writeDataEnc(); +} + +#endif + VbaExport::VbaExport(css::uno::Reference<css::frame::XModel> xModel): mxModel(xModel) { @@ -768,13 +872,43 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN exportString(rStrm, "VersionCompatible32=\"393222000\"\r\n"); // section 2.3.1.15 ProjectProtectionState +#if VBA_ENCRYPTION + exportString(rStrm, "CMG=\""); + SvMemoryStream aProtectedStream(4096, 4096); + aProtectedStream.WriteUInt32(0x00000000); + const sal_uInt8* pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData()); + VBAEncryption aProtectionState(pData, 4, rStrm); + aProtectionState.write(); + exportString(rStrm, "\"\r\n"); +#else exportString(rStrm, "CMG=\"BEBC9256EEAAA8AEA8AEA8AEA8AE\"\r\n"); +#endif // section 2.3.1.16 ProjectPassword +#if VBA_ENCRYPTION + exportString(rStrm, "DPB=\""); + aProtectedStream.Seek(0); + aProtectedStream.WriteUInt8(0x00); + pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData()); + VBAEncryption aProjectPassword(pData, 1, rStrm); + aProjectPassword.write(); + exportString(rStrm, "\"\r\n"); +#else exportString(rStrm, "DPB=\"7C7E5014B0D3B1D3B1D3\"\r\n"); +#endif // section 2.3.1.17 ProjectVisibilityState +#if VBA_ENCRYPTION + exportString(rStrm, "GC=\""); + aProtectedStream.Seek(0); + aProtectedStream.WriteUInt8(0xFF); + pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData()); + VBAEncryption aVisibilityState(pData, 1, rStrm); + aVisibilityState.write(); + exportString(rStrm, "\"\r\n\r\n"); +#else exportString(rStrm, "GC=\"3A3816DAD5DBD5DB2A\"\r\n\r\n"); +#endif // section 2.3.1.18 HostExtenders exportString(rStrm, "[Host Extender Info]\r\n" |