[Libreoffice-commits] core.git: 5 commits - include/oox oox/CppunitTest_oox_vba_encryption.mk oox/Module_oox.mk oox/qa oox/source
Rosemary
rosemaryseb8 at gmail.com
Thu Oct 8 08:46:42 PDT 2015
include/oox/ole/vbaexport.hxx | 35 +++++++
oox/CppunitTest_oox_vba_encryption.mk | 50 ++++++++++
oox/Module_oox.mk | 1
oox/qa/unit/vba_encryption.cxx | 97 ++++++++++++++++++++
oox/source/ole/vbaexport.cxx | 158 +++++++++++++++++++++++++++++++++-
5 files changed, 340 insertions(+), 1 deletion(-)
New commits:
commit 7168f6b20ba620e20233bc9e89e1c97b6b353b97
Author: Rosemary <rosemaryseb8 at gmail.com>
Date: Thu Oct 8 10:15:03 2015 +0530
The correct size of length is 4
Change-Id: I8735e68e1094e40f989ebc0a8a3926c9e2f06fd4
diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx
index 20b9741..717f6eb 100644
--- a/oox/source/ole/vbaexport.cxx
+++ b/oox/source/ole/vbaexport.cxx
@@ -424,7 +424,7 @@ void VBAEncryption::writeIgnoredEnc()
void VBAEncryption::writeDataLengthEnc()
{
sal_uInt16 temp = mnLength;
- for(sal_Int8 i = 0; i < 2; ++i)
+ for(sal_Int8 i = 0; i < 4; ++i)
{
sal_uInt8 nByte = temp & 0xFF;
sal_uInt8 nByteEnc = nByte ^ (mnEncryptedByte2 + mnUnencryptedByte1);
commit e5f1bba213b8ca9c3b8138ba053da453852ffb87
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date: Wed Oct 7 21:01:42 2015 +0200
add test for projkey generation
Change-Id: I42957abbdcf396830713d7ca4eb7539e6c110e11
diff --git a/include/oox/ole/vbaexport.hxx b/include/oox/ole/vbaexport.hxx
index 2275c13..db63ce3 100644
--- a/include/oox/ole/vbaexport.hxx
+++ b/include/oox/ole/vbaexport.hxx
@@ -122,6 +122,8 @@ public:
void write();
+ static sal_uInt8 calculateProjKey(const OUString& rString);
+
private:
const sal_uInt8* mpData; // an array of bytes to be obfuscated
const sal_uInt16 mnLength; // the length of Data
diff --git a/oox/qa/unit/vba_encryption.cxx b/oox/qa/unit/vba_encryption.cxx
index 1c7fc02..785c480 100644
--- a/oox/qa/unit/vba_encryption.cxx
+++ b/oox/qa/unit/vba_encryption.cxx
@@ -25,6 +25,8 @@ public:
void testSimple2();
+ void testProjKey1();
+
// avoid the BootstrapFixtureBase::setUp and tearDown
virtual void setUp() SAL_OVERRIDE;
virtual void tearDown() SAL_OVERRIDE;
@@ -32,6 +34,7 @@ public:
CPPUNIT_TEST_SUITE(TestVbaEncryption);
// CPPUNIT_TEST(testSimple1);
// CPPUNIT_TEST(testSimple2);
+ CPPUNIT_TEST(testProjKey1);
CPPUNIT_TEST_SUITE_END();
private:
@@ -48,7 +51,6 @@ void TestVbaEncryption::testSimple1()
VBAEncryption aEncryption(pData, nLength, aEncryptedStream,
&nSeed, nProjKey);
aEncryption.write();
-
}
void TestVbaEncryption::testSimple2()
@@ -73,6 +75,13 @@ void TestVbaEncryption::testSimple2()
}
}
+void TestVbaEncryption::testProjKey1()
+{
+ OUString aProjectID("{917DED54-440B-4FD1-A5C1-74ACF261E600}");
+ sal_uInt8 nProjKey = VBAEncryption::calculateProjKey(aProjectID);
+ CPPUNIT_ASSERT_EQUAL((int)0xdf, (int)nProjKey);
+}
+
void TestVbaEncryption::setUp()
{
}
diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx
index e5352ca..20b9741 100644
--- a/oox/source/ole/vbaexport.cxx
+++ b/oox/source/ole/vbaexport.cxx
@@ -384,19 +384,22 @@ void VBAEncryption::writeVersionEnc()
exportHexString(mrEncryptedData, mnVersionEnc);
}
-void VBAEncryption::writeProjKeyEnc()
+sal_uInt8 VBAEncryption::calculateProjKey(const OUString& rProjectKey)
{
- if(!mnProjKey)
+ sal_uInt8 nProjKey = 0;
+ sal_Int32 n = rProjectKey.getLength();
+ const sal_Unicode* pString = rProjectKey.getStr();
+ for (sal_Int32 i = 0; i < n; ++i)
{
- OUString sProjectCLSID = "{9F10AB9C-89AC-4C0F-8AFB-8E9B96D5F170}"; //TODO:Find the real ProjectId.ProjectClSID
- sal_Int32 n = sProjectCLSID.getLength();
- const sal_Unicode* pString = sProjectCLSID.getStr();
- for (sal_Int32 i = 0; i < n; ++i)
- {
- sal_Unicode character = pString[i];
- mnProjKey += character;
- }
+ sal_Unicode character = pString[i];
+ nProjKey += character;
}
+
+ return nProjKey;
+}
+
+void VBAEncryption::writeProjKeyEnc()
+{
sal_uInt8 nProjKeyEnc = mnSeed ^ mnProjKey;
exportHexString(mrEncryptedData, nProjKeyEnc);
mnUnencryptedByte1 = mnProjKey;
@@ -861,7 +864,8 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
// section 2.3.1.2 ProjectId
exportString(rStrm, "ID=\"");
- exportString(rStrm, "{9F10AB9C-89AC-4C0F-8AFB-8E9B96D5F170}");
+ OUString aProjectID("{9F10AB9C-89AC-4C0F-8AFB-8E9B96D5F170}");
+ exportString(rStrm, aProjectID);
exportString(rStrm, "\"\r\n");
// section 2.3.1.3 ProjectModule
@@ -894,7 +898,8 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
SvMemoryStream aProtectedStream(4096, 4096);
aProtectedStream.WriteUInt32(0x00000000);
const sal_uInt8* pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
- VBAEncryption aProtectionState(pData, 4, rStrm, NULL, 0);
+ sal_uInt8 nProjKey = VBAEncryption::calculateProjKey(aProjectID);
+ VBAEncryption aProtectionState(pData, 4, rStrm, NULL, nProjKey);
aProtectionState.write();
exportString(rStrm, "\"\r\n");
#else
@@ -907,7 +912,7 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
aProtectedStream.Seek(0);
aProtectedStream.WriteUInt8(0x00);
pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
- VBAEncryption aProjectPassword(pData, 1, rStrm, NULL, 0);
+ VBAEncryption aProjectPassword(pData, 1, rStrm, NULL, nProjKey);
aProjectPassword.write();
exportString(rStrm, "\"\r\n");
#else
@@ -920,7 +925,7 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
aProtectedStream.Seek(0);
aProtectedStream.WriteUInt8(0xFF);
pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
- VBAEncryption aVisibilityState(pData, 1, rStrm, NULL, 0);
+ VBAEncryption aVisibilityState(pData, 1, rStrm, NULL, nProjKey);
aVisibilityState.write();
exportString(rStrm, "\"\r\n\r\n");
#else
commit 6970e2bac2b64c50ce04565ef1daea12d8a1df9a
Author: Rosemary <rosemaryseb8 at gmail.com>
Date: Wed Oct 7 15:47:55 2015 +0530
Correct export for strings of hexadecimal digits
Change-Id: Ie71cca63cc4ac277c57516348f4c15f5bb2395c3
diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx
index 5be8730..e5352ca 100644
--- a/oox/source/ole/vbaexport.cxx
+++ b/oox/source/ole/vbaexport.cxx
@@ -71,6 +71,19 @@ void exportUTF16String(SvStream& rStrm, const OUString& rString)
}
}
+void exportHexString(SvStream& rStrm, const sal_uInt8 nByte)
+{
+ sal_uInt8 nNibble = (nByte & 0xF0) >> 4;
+ for(sal_uInt8 i = 0; i < 2; i++)
+ {
+ if(nNibble > 9)
+ rStrm.WriteUInt8(nNibble + 55);
+ else
+ rStrm.WriteUInt8(nNibble + 48);
+ nNibble = nByte & 0xF;
+ }
+}
+
bool isWorkbook(css::uno::Reference<css::uno::XInterface> xInterface)
{
css::uno::Reference<ooo::vba::excel::XWorkbook> xWorkbook(xInterface, css::uno::UNO_QUERY);
@@ -362,29 +375,30 @@ VBAEncryption::VBAEncryption(const sal_uInt8* pData, const sal_uInt16 length, Sv
void VBAEncryption::writeSeed()
{
- mrEncryptedData.WriteUInt8(mnSeed);
+ exportHexString(mrEncryptedData, mnSeed);
}
void VBAEncryption::writeVersionEnc()
{
mnVersionEnc = mnSeed ^ mnVersion;
- mrEncryptedData.WriteUInt8(mnVersionEnc);
+ exportHexString(mrEncryptedData, 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)
+ if(!mnProjKey)
{
- sal_Unicode character = pString[i];
- mnProjKey += character;
+ OUString sProjectCLSID = "{9F10AB9C-89AC-4C0F-8AFB-8E9B96D5F170}"; //TODO:Find the real ProjectId.ProjectClSID
+ sal_Int32 n = sProjectCLSID.getLength();
+ const sal_Unicode* pString = sProjectCLSID.getStr();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode character = pString[i];
+ mnProjKey += character;
+ }
}
- */
sal_uInt8 nProjKeyEnc = mnSeed ^ mnProjKey;
- mrEncryptedData.WriteUInt8(nProjKeyEnc);
+ exportHexString(mrEncryptedData, nProjKeyEnc);
mnUnencryptedByte1 = mnProjKey;
mnEncryptedByte1 = nProjKeyEnc; // ProjKeyEnc
mnEncryptedByte2 = mnVersionEnc; // VersionEnc
@@ -397,7 +411,7 @@ void VBAEncryption::writeIgnoredEnc()
{
sal_uInt8 nTempValue = 0xBE; // TODO:Generate a random value
sal_uInt8 nByteEnc = nTempValue ^ (mnEncryptedByte2 + mnUnencryptedByte1);
- mrEncryptedData.WriteUInt8(nByteEnc);
+ exportHexString(mrEncryptedData, nByteEnc);
mnEncryptedByte2 = mnEncryptedByte1;
mnEncryptedByte1 = nByteEnc;
mnUnencryptedByte1 = nTempValue;
@@ -411,7 +425,7 @@ void VBAEncryption::writeDataLengthEnc()
{
sal_uInt8 nByte = temp & 0xFF;
sal_uInt8 nByteEnc = nByte ^ (mnEncryptedByte2 + mnUnencryptedByte1);
- mrEncryptedData.WriteUInt8(nByteEnc);
+ exportHexString(mrEncryptedData, nByteEnc);
mnEncryptedByte2 = mnEncryptedByte1;
mnEncryptedByte1 = nByteEnc;
mnUnencryptedByte1 = nByte;
@@ -424,7 +438,7 @@ void VBAEncryption::writeDataEnc()
for(sal_Int8 i = 0; i < mnLength; i++)
{
sal_uInt8 nByteEnc = mpData[i] ^ (mnEncryptedByte2 + mnUnencryptedByte1);
- mrEncryptedData.WriteUInt8(nByteEnc);
+ exportHexString(mrEncryptedData, nByteEnc);
mnEncryptedByte2 = mnEncryptedByte1;
mnEncryptedByte1 = nByteEnc;
mnUnencryptedByte1 = mpData[i];
commit 3ba169bd68d81980a112998a57ff5d2b638252fa
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date: Tue Oct 6 17:06:16 2015 +0200
add initial tests for vba encryption
Change-Id: Ic6128ecade39e8947863c9162523e0d9690f0026
diff --git a/include/oox/ole/vbaexport.hxx b/include/oox/ole/vbaexport.hxx
index 2c03cc27..2275c13 100644
--- a/include/oox/ole/vbaexport.hxx
+++ b/include/oox/ole/vbaexport.hxx
@@ -111,13 +111,14 @@ private:
SvMemoryStream& mrUncompressedStream;
};
-class VBAEncryption
+class OOX_DLLPUBLIC VBAEncryption
{
public:
VBAEncryption(const sal_uInt8* pData,
const sal_uInt16 nLength,
- SvStream& rEncryptedData
- );
+ SvStream& rEncryptedData,
+ sal_uInt8* pSeed,
+ sal_uInt8 nProjKey);
void write();
diff --git a/oox/CppunitTest_oox_vba_encryption.mk b/oox/CppunitTest_oox_vba_encryption.mk
new file mode 100644
index 0000000..1f8bb5c
--- /dev/null
+++ b/oox/CppunitTest_oox_vba_encryption.mk
@@ -0,0 +1,50 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,oox_vba_encryption))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,oox_vba_encryption,\
+ oox/qa/unit/vba_encryption \
+))
+
+$(eval $(call gb_CppunitTest_use_api,oox_vba_encryption,\
+ offapi \
+ udkapi \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,oox_vba_encryption,\
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ editeng \
+ expwrap \
+ drawinglayer \
+ msfilter \
+ sal \
+ i18nlangtag \
+ oox \
+ sax \
+ sfx \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ sot \
+ tl \
+ unotest \
+ utl \
+ vcl \
+ xo \
+ xmlscript \
+ $(gb_UWINAPI) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/oox/Module_oox.mk b/oox/Module_oox.mk
index 1c8edf0..4d7a79e 100644
--- a/oox/Module_oox.mk
+++ b/oox/Module_oox.mk
@@ -19,6 +19,7 @@ $(eval $(call gb_Module_add_targets,oox,\
$(eval $(call gb_Module_add_check_targets,oox,\
CppunitTest_oox_tokenmap \
CppunitTest_oox_vba_compression \
+ CppunitTest_oox_vba_encryption \
))
# vim: set noet sw=4 ts=4:
diff --git a/oox/qa/unit/vba_encryption.cxx b/oox/qa/unit/vba_encryption.cxx
new file mode 100644
index 0000000..1c7fc02
--- /dev/null
+++ b/oox/qa/unit/vba_encryption.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <unotest/bootstrapfixturebase.hxx>
+
+#include <cppunit/plugin/TestPlugIn.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestFixture.h>
+
+#include <oox/ole/vbaexport.hxx>
+#include <algorithm>
+
+class TestVbaEncryption : public test::BootstrapFixtureBase
+{
+public:
+
+ // an initial test for the encryption taken from the spec
+ void testSimple1();
+
+ void testSimple2();
+
+ // avoid the BootstrapFixtureBase::setUp and tearDown
+ virtual void setUp() SAL_OVERRIDE;
+ virtual void tearDown() SAL_OVERRIDE;
+
+ CPPUNIT_TEST_SUITE(TestVbaEncryption);
+ // CPPUNIT_TEST(testSimple1);
+ // CPPUNIT_TEST(testSimple2);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+};
+
+void TestVbaEncryption::testSimple1()
+{
+ sal_uInt8 nSeed = 0x07;
+ sal_uInt8 nProjKey = 0xDF;
+ sal_uInt16 nLength = 0x04;
+ sal_uInt8 pData[] = { 0x00, 0x00, 0x00, 0x00 };
+
+ SvMemoryStream aEncryptedStream(4096, 4096);
+ VBAEncryption aEncryption(pData, nLength, aEncryptedStream,
+ &nSeed, nProjKey);
+ aEncryption.write();
+
+}
+
+void TestVbaEncryption::testSimple2()
+{
+ sal_uInt8 nSeed = 0x15;
+ sal_uInt8 nProjKey = 0xDF;
+ sal_uInt16 nLength = 0x01;
+ sal_uInt8 pData[] = { 0xFF };
+
+ SvMemoryStream aEncryptedStream(4096, 4096);
+ VBAEncryption aEncryption(pData, nLength, aEncryptedStream,
+ &nSeed, nProjKey);
+ aEncryption.write();
+ sal_uInt8 pExpectedData[] = "1517CAF1D6F9D7F9D706";
+ size_t length = sizeof(pExpectedData);
+ aEncryptedStream.Seek(0);
+ for (size_t i = 0; i < length; ++i)
+ {
+ unsigned char val = 0;
+ aEncryptedStream.ReadUChar(val);
+ CPPUNIT_ASSERT_EQUAL((int)pExpectedData[i], (int)sal_uInt8(val));
+ }
+}
+
+void TestVbaEncryption::setUp()
+{
+}
+
+void TestVbaEncryption::tearDown()
+{
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TestVbaEncryption);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx
index 0339203..5be8730 100644
--- a/oox/source/ole/vbaexport.cxx
+++ b/oox/source/ole/vbaexport.cxx
@@ -47,10 +47,10 @@
#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.
*/
+#define VBA_ENCRYPTION 1
namespace {
@@ -344,23 +344,24 @@ void VBACompression::write()
// section 2.4.3
#if VBA_ENCRYPTION
-VBAEncryption::VBAEncryption(const sal_uInt8* pData, const sal_uInt16 length, SvStream& rEncryptedData)
+VBAEncryption::VBAEncryption(const sal_uInt8* pData, const sal_uInt16 length, SvStream& rEncryptedData, sal_uInt8* pSeed, sal_uInt8 nProjKey)
:mpData(pData)
,mnLength(length)
,mrEncryptedData(rEncryptedData)
,mnEncryptedByte1(0)
,mnEncryptedByte2(0)
,mnVersion(2)
- ,mnProjKey(0)
+ ,mnProjKey(nProjKey)
,mnIgnoredLength(0)
- ,mnSeed(0)
+ ,mnSeed(pSeed ? *pSeed : 0x00)
,mnVersionEnc(0)
{
+ if (!pSeed)
+ mnSeed = 0xBE; // sample seed value TODO:Generate random seed values
}
void VBAEncryption::writeSeed()
{
- mnSeed = 0xBE; // sample seed value TODO:Generate random seed values
mrEncryptedData.WriteUInt8(mnSeed);
}
@@ -372,6 +373,7 @@ void VBAEncryption::writeVersionEnc()
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();
@@ -380,6 +382,7 @@ void VBAEncryption::writeProjKeyEnc()
sal_Unicode character = pString[i];
mnProjKey += character;
}
+ */
sal_uInt8 nProjKeyEnc = mnSeed ^ mnProjKey;
mrEncryptedData.WriteUInt8(nProjKeyEnc);
mnUnencryptedByte1 = mnProjKey;
@@ -877,7 +880,7 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
SvMemoryStream aProtectedStream(4096, 4096);
aProtectedStream.WriteUInt32(0x00000000);
const sal_uInt8* pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
- VBAEncryption aProtectionState(pData, 4, rStrm);
+ VBAEncryption aProtectionState(pData, 4, rStrm, NULL, 0);
aProtectionState.write();
exportString(rStrm, "\"\r\n");
#else
@@ -890,7 +893,7 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
aProtectedStream.Seek(0);
aProtectedStream.WriteUInt8(0x00);
pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
- VBAEncryption aProjectPassword(pData, 1, rStrm);
+ VBAEncryption aProjectPassword(pData, 1, rStrm, NULL, 0);
aProjectPassword.write();
exportString(rStrm, "\"\r\n");
#else
@@ -903,7 +906,7 @@ void exportPROJECTStream(SvStream& rStrm, css::uno::Reference<css::container::XN
aProtectedStream.Seek(0);
aProtectedStream.WriteUInt8(0xFF);
pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
- VBAEncryption aVisibilityState(pData, 1, rStrm);
+ VBAEncryption aVisibilityState(pData, 1, rStrm, NULL, 0);
aVisibilityState.write();
exportString(rStrm, "\"\r\n\r\n");
#else
commit c597581852cf1d3550359dc639f1bb7f6476f419
Author: Rosemary <rosemaryseb8 at gmail.com>
Date: Sun Oct 4 07:58:21 2015 +0530
Implement encryption for the VBA export
Change-Id: Id994095de9f43cf0c2857272b613abe7cbd9324e
diff --git a/include/oox/ole/vbaexport.hxx b/include/oox/ole/vbaexport.hxx
index 7b5b916..2c03cc27 100644
--- a/include/oox/ole/vbaexport.hxx
+++ b/include/oox/ole/vbaexport.hxx
@@ -111,6 +111,38 @@ private:
SvMemoryStream& mrUncompressedStream;
};
+class VBAEncryption
+{
+public:
+ VBAEncryption(const sal_uInt8* pData,
+ const sal_uInt16 nLength,
+ SvStream& rEncryptedData
+ );
+
+ void write();
+
+private:
+ const sal_uInt8* mpData; // an array of bytes to be obfuscated
+ const sal_uInt16 mnLength; // the length of Data
+ SvStream& mrEncryptedData; // Encrypted Data Structure
+ sal_uInt8 mnUnencryptedByte1; // the last unencrypted byte read or written
+ sal_uInt8 mnEncryptedByte1; // the last encrypted byte read or written
+ sal_uInt8 mnEncryptedByte2; // the next-to-last encrypted byte read or written
+ sal_uInt8 mnVersion; // the encrypted version
+ sal_Unicode mnProjKey; // a project-specific encryption key
+ sal_uInt8 mnIgnoredLength; // the length in bytes of IgnoredEnc
+
+ sal_uInt8 mnSeed; // the seed value
+ sal_uInt8 mnVersionEnc; // the version encoding
+
+ void writeSeed();
+ void writeVersionEnc();
+ void writeProjKeyEnc();
+ void writeIgnoredEnc();
+ void writeDataLengthEnc();
+ void writeDataEnc();
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx
index eaa8078..0339203 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"
More information about the Libreoffice-commits
mailing list