[Libreoffice-commits] core.git: Branch 'feature/cib_contract3756b' - 20 commits - comphelper/source external/breakpad .gitreview include/oox odk/settings offapi/com oox/Library_oox.mk oox/qa oox/source oox/util package/source sc/source sd/source sfx2/source sw/source
Stephan Bergmann (via logerrit)
logerrit at kemper.freedesktop.org
Wed Dec 4 16:21:50 UTC 2019
Rebased ref, commits from common ancestor:
commit d24199ab2c401866c4f5e48cb99ecf0e45ac5d55
Author: Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Thu Sep 26 22:09:56 2019 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:55 2019 +0100
external/breakpad: glibc 2.30 declares tgkill
...so building against glibc-headers-2.30-4.fc31.x86_64 fails with
> src/client/linux/handler/exception_handler.cc:109:12: error: static declaration of 'tgkill' follows non-static declaration
> static int tgkill(pid_t tgid, pid_t tid, int sig) {
> ^
> /usr/include/bits/signal_ext.h:29:12: note: previous declaration is here
> extern int tgkill (__pid_t __tgid, __pid_t __tid, int __signal);
> ^
> 1 error generated.
Upstream commit <https://chromium.googlesource.com/breakpad/breakpad/+/
7e3c165000d44fa153a3270870ed500bc8bbb461%5E%21/> "Fix double declaration of
tgkill when using Android NDK Headers" looks like the perfect fit.
Change-Id: I1b4805886fb7c770cf9733f34a31296e6b859d92
Reviewed-on: https://gerrit.libreoffice.org/79661
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
(cherry picked from commit 55556a4cebbb35f15e7989bf0a6e276db99944e3)
diff --git a/external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1 b/external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1
new file mode 100644
index 000000000000..7c8a68c2451a
--- /dev/null
+++ b/external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1
@@ -0,0 +1,49 @@
+From 7e3c165000d44fa153a3270870ed500bc8bbb461 Mon Sep 17 00:00:00 2001
+From: Nicholas Baldwin <baldwinn at google.com>
+Date: Fri, 27 Oct 2017 11:44:36 -0700
+Subject: [PATCH] Fix double declaration of tgkill when using Android NDK
+ Headers.
+
+As of Android API level 16 tgkill is declared in the NDK version of
+signal.h, which conflicts with the static definition found in
+src/client/linux/handler/exception_handler.cc. This change removes
+the static tgkill definition and replaces its use with sys_tgkill
+from the linux syscall support library.
+
+Bug:
+Change-Id: Ic70addd8a064cfa36345d86b7e36409e2089e909
+Reviewed-on: https://chromium-review.googlesource.com/738912
+Reviewed-by: Mike Frysinger <vapier at chromium.org>
+---
+ src/client/linux/handler/exception_handler.cc | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
+index 95005209..cd94e3b5 100644
+--- a/src/client/linux/handler/exception_handler.cc
++++ b/src/client/linux/handler/exception_handler.cc
+@@ -105,12 +105,6 @@
+ #define PR_SET_PTRACER 0x59616d61
+ #endif
+
+-// A wrapper for the tgkill syscall: send a signal to a specific thread.
+-static int tgkill(pid_t tgid, pid_t tid, int sig) {
+- return syscall(__NR_tgkill, tgid, tid, sig);
+- return 0;
+-}
+-
+ namespace google_breakpad {
+
+ namespace {
+@@ -400,7 +394,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
+ // In order to retrigger it, we have to queue a new signal by calling
+ // kill() ourselves. The special case (si_pid == 0 && sig == SIGABRT) is
+ // due to the kernel sending a SIGABRT from a user request via SysRQ.
+- if (tgkill(getpid(), syscall(__NR_gettid), sig) < 0) {
++ if (sys_tgkill(getpid(), syscall(__NR_gettid), sig) < 0) {
+ // If we failed to kill ourselves (e.g. because a sandbox disallows us
+ // to do so), we instead resort to terminating our process. This will
+ // result in an incorrect exit code.
+--
+2.23.0
+
diff --git a/external/breakpad/UnpackedTarball_breakpad.mk b/external/breakpad/UnpackedTarball_breakpad.mk
index b70510234e38..633574cd34a7 100644
--- a/external/breakpad/UnpackedTarball_breakpad.mk
+++ b/external/breakpad/UnpackedTarball_breakpad.mk
@@ -23,6 +23,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,breakpad,\
external/breakpad/breakpad-stackwalk.patch.1 \
external/breakpad/ucontext.patch \
external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch.1 \
+ external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1 \
))
ifeq ($(COM_IS_CLANG),TRUE)
commit 296d4f852c9184150c2772998faa268511ed9942
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Wed Dec 4 06:24:26 2019 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:55 2019 +0100
Update default branch
Change-Id: I5bed5207db18747539ce8398ed85619385d51249
diff --git a/.gitreview b/.gitreview
index 042036087fed..fd925839a944 100644
--- a/.gitreview
+++ b/.gitreview
@@ -3,5 +3,5 @@ host=gerrit.libreoffice.org
port=29418
project=core
defaultremote=logerrit
-defaultbranch=libreoffice-6-3-0
+defaultbranch=feature/cib_contract3756b
commit 026ed9616710d5fcc72006f05f209f69284451f8
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Fri Nov 29 13:07:57 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
tdf#118639: store ODF encryption data for autorecovery
When saving autorecovery information, ODF is used. If the original
document is password-protected, its autorecovery is also generated
password-protected (since ef87ff6680f79362a431db6e7ef2f40cfc576219).
But when the stored encryption data for non-ODF document does not
contain "PackageSHA256UTF8EncryptionKey" value, following
ZipPackage::GetEncryptionKey fails, so the whole save fails.
So just generate and append ODF encryption keys where we still have
user password.
Change-Id: I776e28de784489521e4941d1075690f90c056014
Reviewed-on: https://gerrit.libreoffice.org/84052
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
Conflicts:
sfx2/source/dialog/filedlghelper.cxx
diff --git a/comphelper/source/misc/docpasswordhelper.cxx b/comphelper/source/misc/docpasswordhelper.cxx
index 9134e7d050a2..af3741347344 100644
--- a/comphelper/source/misc/docpasswordhelper.cxx
+++ b/comphelper/source/misc/docpasswordhelper.cxx
@@ -422,6 +422,7 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
bool* pbIsDefaultPassword )
{
css::uno::Sequence< css::beans::NamedValue > aEncData;
+ OUString aPassword;
DocPasswordVerifierResult eResult = DocPasswordVerifierResult::WrongPassword;
// first, try provided default passwords
@@ -435,8 +436,12 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
if( !rPassword.isEmpty() )
{
eResult = rVerifier.verifyPassword( rPassword, aEncData );
- if( pbIsDefaultPassword )
- *pbIsDefaultPassword = eResult == DocPasswordVerifierResult::OK;
+ if (eResult == DocPasswordVerifierResult::OK)
+ {
+ aPassword = rPassword;
+ if (pbIsDefaultPassword)
+ *pbIsDefaultPassword = true;
+ }
if( eResult != DocPasswordVerifierResult::WrongPassword )
break;
}
@@ -458,7 +463,11 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
if( eResult == DocPasswordVerifierResult::WrongPassword )
{
if( !rMediaPassword.isEmpty() )
+ {
eResult = rVerifier.verifyPassword( rMediaPassword, aEncData );
+ if (eResult == DocPasswordVerifierResult::OK)
+ aPassword = rMediaPassword;
+ }
}
// request a password (skip, if result is OK or ABORT)
@@ -474,6 +483,8 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
{
if( !pRequest->getPassword().isEmpty() )
eResult = rVerifier.verifyPassword( pRequest->getPassword(), aEncData );
+ if (eResult == DocPasswordVerifierResult::OK)
+ aPassword = pRequest->getPassword();
}
else
{
@@ -486,6 +497,21 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
{
}
+ if (eResult == DocPasswordVerifierResult::OK && !aPassword.isEmpty())
+ {
+ if (std::find_if(std::cbegin(aEncData), std::cend(aEncData),
+ [](const css::beans::NamedValue& val) {
+ return val.Name == PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
+ })
+ == std::cend(aEncData))
+ {
+ // tdf#118639: We need ODF encryption data for autorecovery, where password
+ // will already be unavailable, so generate and append it here
+ aEncData = comphelper::concatSequences(
+ aEncData, OStorageHelper::CreatePackageEncryptionData(aPassword));
+ }
+ }
+
return (eResult == DocPasswordVerifierResult::OK) ? aEncData : uno::Sequence< beans::NamedValue >();
}
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx
index 28f7d1179824..a2167c3a255b 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -2727,6 +2727,8 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter,
{
if ( pPasswordRequest->getPassword().getLength() )
{
+ css::uno::Sequence< css::beans::NamedValue > aEncryptionData;
+
// TODO/LATER: The filters should show the password dialog themself in future
if ( bMSType )
{
@@ -2736,7 +2738,7 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter,
::comphelper::SequenceAsHashMap aHashData;
aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword();
aHashData[ OUString( "CryptoType" ) ] <<= OUString( "Standard" );
- pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
+ aEncryptionData = aHashData.getAsConstNamedValueList();
}
else
{
@@ -2749,7 +2751,7 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter,
aHashData[ OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
aHashData[ OUString( "STD97UniqueID" ) ] <<= aUniqueID;
- pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
+ aEncryptionData = aHashData.getAsConstNamedValueList();
}
else
{
@@ -2757,10 +2759,14 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter,
}
}
}
- else
- {
- pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) );
- }
+
+ // tdf#118639: We need ODF encryption data for autorecovery where password will already
+ // be unavailable, even for non-ODF documents, so append it here unconditionally
+ pSet->Put(SfxUnoAnyItem(
+ SID_ENCRYPTIONDATA,
+ uno::makeAny(comphelper::concatSequences(
+ aEncryptionData, comphelper::OStorageHelper::CreatePackageEncryptionData(
+ pPasswordRequest->getPassword())))));
}
if ( pPasswordRequest->getRecommendReadOnly() )
commit 643f2e6d8176e5700eef29c64806efc6ba478671
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 29 11:57:51 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
oox: fixes for cang errors after refactoring:
Change-Id: I6c0ff55e3a6d3edbac78aa6e806da4a290af142d
diff --git a/include/oox/crypto/DocumentDecryption.hxx b/include/oox/crypto/DocumentDecryption.hxx
index d1754c791a4a..d188336a07d6 100644
--- a/include/oox/crypto/DocumentDecryption.hxx
+++ b/include/oox/crypto/DocumentDecryption.hxx
@@ -35,10 +35,10 @@ namespace crypto {
class OOX_DLLPUBLIC DocumentDecryption
{
private:
+ css::uno::Reference< css::uno::XComponentContext > mxContext;
oox::ole::OleStorage& mrOleStorage;
css::uno::Sequence<css::beans::NamedValue> maStreamsSequence;
css::uno::Reference< css::packages::XPackageEncryption > mxPackageEncryption;
- css::uno::Reference< css::uno::XComponentContext > mxContext;
public:
DocumentDecryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext, oox::ole::OleStorage& rOleStorage);
diff --git a/include/oox/crypto/DocumentEncryption.hxx b/include/oox/crypto/DocumentEncryption.hxx
index 8b9f8b89f7f0..5b45b5f53f8b 100644
--- a/include/oox/crypto/DocumentEncryption.hxx
+++ b/include/oox/crypto/DocumentEncryption.hxx
@@ -21,6 +21,7 @@
namespace com { namespace sun { namespace star {
namespace io { class XStream; }
namespace packages { class XPackageEncryption; }
+ namespace beans { struct NamedValue; }
} } }
namespace oox { namespace ole { class OleStorage; } }
@@ -31,11 +32,11 @@ namespace crypto {
class OOX_DLLPUBLIC DocumentEncryption
{
private:
+ css::uno::Reference< css::uno::XComponentContext > mxContext;
css::uno::Reference< css::io::XStream > mxDocumentStream;
oox::ole::OleStorage& mrOleStorage;
css::uno::Reference< css::packages::XPackageEncryption > mxPackageEncryption;
const css::uno::Sequence< css::beans::NamedValue >& mMediaEncData;
- css::uno::Reference< css::uno::XComponentContext > mxContext;
public:
DocumentEncryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
diff --git a/include/oox/crypto/StrongEncryptionDataSpace.hxx b/include/oox/crypto/StrongEncryptionDataSpace.hxx
index d3eb76a2c1a8..966185c94612 100644
--- a/include/oox/crypto/StrongEncryptionDataSpace.hxx
+++ b/include/oox/crypto/StrongEncryptionDataSpace.hxx
@@ -12,6 +12,7 @@
#define INCLUDED_OOX_CRYPTO_STRONGENCRYPTINDATASPACE_HXX
#include <oox/dllapi.h>
+#include <cppuhelper/implbase.hxx>
#include <com/sun/star/packages/XPackageEncryption.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <oox/crypto/CryptoEngine.hxx>
commit 30efa3c975755a7b8cc22b207944bcded4aeb9f0
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Wed Dec 4 13:29:21 2019 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
oox: more encryption engines refactoring
Make cryto tests build again.
Change-Id: Id72eb461f5f04eecc0a5bdd9c9e7f2d94df7c8ab
diff --git a/oox/qa/unit/CryptoTest.cxx b/oox/qa/unit/CryptoTest.cxx
index 47d567fab34b..dd2c7c6ad8bb 100644
--- a/oox/qa/unit/CryptoTest.cxx
+++ b/oox/qa/unit/CryptoTest.cxx
@@ -19,6 +19,7 @@
#include <oox/crypto/AgileEngine.hxx>
#include <oox/helper/binaryinputstream.hxx>
#include <oox/helper/binaryoutputstream.hxx>
+#include <oox/crypto/CryptTools.hxx>
using namespace css;
@@ -66,7 +67,7 @@ void CryptoTest::testCryptoHash()
aContentString.getStr() + aContentString.getLength());
std::vector<sal_uInt8> aKey = { 'k', 'e', 'y' };
{
- oox::core::CryptoHash aCryptoHash(aKey, oox::core::CryptoHashType::SHA1);
+ oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA1);
aCryptoHash.update(aContent);
std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
CPPUNIT_ASSERT_EQUAL(std::string("de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"),
@@ -74,7 +75,7 @@ void CryptoTest::testCryptoHash()
}
{
- oox::core::CryptoHash aCryptoHash(aKey, oox::core::CryptoHashType::SHA256);
+ oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA256);
aCryptoHash.update(aContent);
std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
CPPUNIT_ASSERT_EQUAL(
@@ -83,7 +84,7 @@ void CryptoTest::testCryptoHash()
}
{
- oox::core::CryptoHash aCryptoHash(aKey, oox::core::CryptoHashType::SHA512);
+ oox::crypto::CryptoHash aCryptoHash(aKey, oox::crypto::CryptoHashType::SHA512);
aCryptoHash.update(aContent);
std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
CPPUNIT_ASSERT_EQUAL(
commit 09102a425d9412558d31f9f4625ab6b8d7bc4b8c
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Tue Nov 26 11:08:14 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
oox: encryption engines refactoring
Restore original state of Agile and Standard 2007 engines.
Instead of standalone services for each of them
use newly introduced wrapper service.
Change-Id: Icc32a4e0ce215090c3b739f1dcaa0654b36b7f08
Conflicts:
include/oox/crypto/AgileEngine.hxx
include/oox/crypto/Standard2007Engine.hxx
diff --git a/include/oox/crypto/AgileEngine.hxx b/include/oox/crypto/AgileEngine.hxx
index de3836ffdb19..7c923c0f2cd6 100644
--- a/include/oox/crypto/AgileEngine.hxx
+++ b/include/oox/crypto/AgileEngine.hxx
@@ -15,19 +15,17 @@
#include <oox/dllapi.h>
#include <oox/crypto/CryptTools.hxx>
+#include <oox/crypto/CryptoEngine.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
-#include <com/sun/star/packages/XPackageEncryption.hpp>
namespace oox {
class BinaryXInputStream;
class BinaryXOutputStream;
}
-namespace com::sun::star::uno { class XComponentContext; }
-
namespace oox {
-namespace core {
+namespace crypto {
struct OOX_DLLPUBLIC AgileEncryptionInfo
{
@@ -76,15 +74,11 @@ enum class AgileEncryptionPreset
AES_256_SHA512,
};
-class OOX_DLLPUBLIC AgileEngine : public cppu::WeakImplHelper<css::packages::XPackageEncryption>
+class OOX_DLLPUBLIC AgileEngine : public CryptoEngine
{
private:
- std::vector<sal_uInt8> mKey;
AgileEncryptionInfo mInfo;
AgileEncryptionPreset meEncryptionPreset;
- css::uno::Reference< css::uno::XComponentContext > mxContext;
-
- css::uno::Reference<css::io::XInputStream> getStream(const css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName);
void calculateHashFinal(const OUString& rPassword, std::vector<sal_uInt8>& aHashFinal);
@@ -102,58 +96,52 @@ private:
static Crypto::CryptoType cryptoType(const AgileEncryptionInfo& rInfo);
- // Decryption
-
- bool decryptHmacKey();
- bool decryptHmacValue();
+public:
+ AgileEngine();
- AgileEncryptionInfo& getInfo() { return mInfo; }
+ AgileEncryptionInfo& getInfo() { return mInfo;}
void setPreset(AgileEncryptionPreset ePreset)
{
meEncryptionPreset = ePreset;
}
+ // Decryption
+
void decryptEncryptionKey(OUString const & rPassword);
bool decryptAndCheckVerifierHash(OUString const & rPassword);
- // Encryption
-
- bool encryptHmacKey();
- bool encryptHmacValue();
-
- bool generateAndEncryptVerifierHash(OUString const & rPassword);
-
- bool encryptEncryptionKey(OUString const & rPassword);
- void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters);
- bool setupEncryptionKey(OUString const & rPassword);
-
- css::uno::Sequence<sal_Int8> writeEncryptionInfo();
- css::uno::Sequence<sal_Int8> writeEncryptedDocument(const css::uno::Reference<css::io::XInputStream>& rxInputStream);
+ bool generateEncryptionKey(OUString const & rPassword) override;
+ bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override;
+ bool decrypt(BinaryXInputStream& aInputStream,
+ BinaryXOutputStream& aOutputStream) override;
-public:
- AgileEngine(const css::uno::Reference< css::uno::XComponentContext >& rxContext);
+ bool checkDataIntegrity() override;
- // Decryption
+ bool decryptHmacKey();
+ bool decryptHmacValue();
- virtual sal_Bool SAL_CALL generateEncryptionKey(const OUString & rPassword) override;
- virtual sal_Bool SAL_CALL readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) override;
- virtual sal_Bool SAL_CALL decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
- css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override;
+ // Encryption
+ void writeEncryptionInfo(BinaryXOutputStream& rStream) override;
- virtual sal_Bool SAL_CALL checkDataIntegrity() override;
+ void encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
+ css::uno::Reference<css::io::XOutputStream>& rxOutputStream,
+ sal_uInt32 nSize) override;
- // Encryption
+ bool setupEncryption(OUString const & rPassword) override;
- virtual css::uno::Sequence<css::beans::NamedValue> SAL_CALL encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream) override;
+ bool generateAndEncryptVerifierHash(OUString const & rPassword);
- virtual sal_Bool SAL_CALL setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override;
+ bool encryptHmacKey();
+ bool encryptHmacValue();
- virtual css::uno::Sequence<css::beans::NamedValue> SAL_CALL createEncryptionData(const OUString& rPassword) override;
+ bool encryptEncryptionKey(OUString const & rPassword);
+ void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters);
+ bool setupEncryptionKey(OUString const & rPassword);
};
-} // namespace core
+} // namespace crypto
} // namespace oox
#endif
diff --git a/include/oox/crypto/CryptTools.hxx b/include/oox/crypto/CryptTools.hxx
index 80d52cbeed74..2489cafe3c9c 100644
--- a/include/oox/crypto/CryptTools.hxx
+++ b/include/oox/crypto/CryptTools.hxx
@@ -28,7 +28,7 @@
#include <memory>
namespace oox {
-namespace core {
+namespace crypto {
/** Rounds up the input to the nearest multiple
*
@@ -115,7 +115,7 @@ public:
};
-} // namespace core
+} // namespace crypto
} // namespace oox
#endif
diff --git a/include/oox/crypto/CryptoEngine.hxx b/include/oox/crypto/CryptoEngine.hxx
new file mode 100644
index 000000000000..72bde8920dfc
--- /dev/null
+++ b/include/oox/crypto/CryptoEngine.hxx
@@ -0,0 +1,68 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_OOX_CRYPTO_CRYPTOENGINE_HXX
+#define INCLUDED_OOX_CRYPTO_CRYPTOENGINE_HXX
+
+#include <vector>
+
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+
+namespace oox {
+ class BinaryXInputStream;
+ class BinaryXOutputStream;
+}
+
+namespace oox {
+namespace crypto {
+
+class CryptoEngine
+{
+protected:
+ std::vector<sal_uInt8> mKey;
+
+public:
+ CryptoEngine()
+ {}
+
+ virtual ~CryptoEngine()
+ {}
+
+ // Decryption
+ virtual bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) = 0;
+
+ virtual bool generateEncryptionKey(const OUString& rPassword) = 0;
+
+ virtual bool decrypt(
+ BinaryXInputStream& aInputStream,
+ BinaryXOutputStream& aOutputStream) = 0;
+
+ // Encryption
+ virtual void writeEncryptionInfo(BinaryXOutputStream & rStream) = 0;
+
+ virtual bool setupEncryption(const OUString& rPassword) = 0;
+
+ virtual void encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream,
+ css::uno::Reference<css::io::XOutputStream> & rxOutputStream,
+ sal_uInt32 nSize) = 0;
+
+ virtual bool checkDataIntegrity() = 0;
+};
+
+} // namespace crypto
+} // namespace oox
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/oox/crypto/DocumentDecryption.hxx b/include/oox/crypto/DocumentDecryption.hxx
index fdea2c25f9f7..d1754c791a4a 100644
--- a/include/oox/crypto/DocumentDecryption.hxx
+++ b/include/oox/crypto/DocumentDecryption.hxx
@@ -30,7 +30,7 @@ namespace com { namespace sun { namespace star {
namespace oox { namespace ole { class OleStorage; } }
namespace oox {
-namespace core {
+namespace crypto {
class OOX_DLLPUBLIC DocumentDecryption
{
@@ -40,8 +40,6 @@ private:
css::uno::Reference< css::packages::XPackageEncryption > mxPackageEncryption;
css::uno::Reference< css::uno::XComponentContext > mxContext;
- void readStrongEncryptionInfo();
-
public:
DocumentDecryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext, oox::ole::OleStorage& rOleStorage);
@@ -53,7 +51,7 @@ public:
};
-} // namespace core
+} // namespace crypto
} // namespace oox
#endif
diff --git a/include/oox/crypto/DocumentEncryption.hxx b/include/oox/crypto/DocumentEncryption.hxx
index 106fe287b28f..8b9f8b89f7f0 100644
--- a/include/oox/crypto/DocumentEncryption.hxx
+++ b/include/oox/crypto/DocumentEncryption.hxx
@@ -26,7 +26,7 @@ namespace com { namespace sun { namespace star {
namespace oox { namespace ole { class OleStorage; } }
namespace oox {
-namespace core {
+namespace crypto {
class OOX_DLLPUBLIC DocumentEncryption
{
@@ -47,7 +47,7 @@ public:
};
-} // namespace core
+} // namespace crypto
} // namespace oox
#endif
diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx
index d1ab8039d772..fef8fc55bab0 100644
--- a/include/oox/crypto/Standard2007Engine.hxx
+++ b/include/oox/crypto/Standard2007Engine.hxx
@@ -12,7 +12,7 @@
#define INCLUDED_OOX_CRYPTO_STANDARD2007ENGINE_HXX
#include <oox/dllapi.h>
-#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <oox/crypto/CryptoEngine.hxx>
#include <filter/msfilter/mscodec.hxx>
#include <rtl/digest.h>
#include <rtl/ustring.hxx>
@@ -23,47 +23,40 @@ namespace oox {
class BinaryXOutputStream;
}
-namespace com::sun::star::uno { class XComponentContext; }
-
namespace oox {
-namespace core {
+namespace crypto {
-class OOX_DLLPUBLIC Standard2007Engine : public cppu::WeakImplHelper<css::packages::XPackageEncryption>
+class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine
{
msfilter::StandardEncryptionInfo mInfo;
- std::vector<sal_uInt8> mKey;
- css::uno::Reference< css::uno::XComponentContext > mxContext;
bool generateVerifier();
bool calculateEncryptionKey(const OUString& rPassword);
- css::uno::Reference<css::io::XInputStream> getStream(const css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName);
- css::uno::Sequence<sal_Int8> writeEncryptionInfo();
- css::uno::Sequence<sal_Int8> writeEncryptedDocument(const css::uno::Reference<css::io::XInputStream>& rxInputStream);
-
public:
- Standard2007Engine(const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+ Standard2007Engine() = default;
- // Decryption
+ bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override;
- virtual sal_Bool SAL_CALL generateEncryptionKey(const OUString & rPassword) override;
- virtual sal_Bool SAL_CALL readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) override;
- virtual sal_Bool SAL_CALL decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
- css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override;
+ virtual bool generateEncryptionKey(OUString const & rPassword) override;
+ virtual bool decrypt(
+ BinaryXInputStream& aInputStream,
+ BinaryXOutputStream& aOutputStream) override;
- virtual sal_Bool SAL_CALL checkDataIntegrity() override;
+ bool checkDataIntegrity() override;
- // Encryption
+ void encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
+ css::uno::Reference<css::io::XOutputStream>& rxOutputStream,
+ sal_uInt32 nSize) override;
- virtual css::uno::Sequence<css::beans::NamedValue> SAL_CALL encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream) override;
+ virtual void writeEncryptionInfo(BinaryXOutputStream& rStream) override;
- virtual sal_Bool SAL_CALL setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override;
+ virtual bool setupEncryption(OUString const & rPassword) override;
- virtual css::uno::Sequence<css::beans::NamedValue> SAL_CALL createEncryptionData(const OUString& rPassword) override;
};
-} // namespace core
+} // namespace crypto
} // namespace oox
#endif
diff --git a/include/oox/crypto/StrongEncryptionDataSpace.hxx b/include/oox/crypto/StrongEncryptionDataSpace.hxx
new file mode 100644
index 000000000000..d3eb76a2c1a8
--- /dev/null
+++ b/include/oox/crypto/StrongEncryptionDataSpace.hxx
@@ -0,0 +1,69 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_OOX_CRYPTO_STRONGENCRYPTINDATASPACE_HXX
+#define INCLUDED_OOX_CRYPTO_STRONGENCRYPTINDATASPACE_HXX
+
+#include <oox/dllapi.h>
+#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <oox/crypto/CryptoEngine.hxx>
+
+namespace com::sun::star::uno
+{
+class XComponentContext;
+}
+
+namespace oox
+{
+namespace crypto
+{
+class OOX_DLLPUBLIC StrongEncryptionDataSpace final
+ : public cppu::WeakImplHelper<css::packages::XPackageEncryption>
+{
+ css::uno::Reference<css::uno::XComponentContext> mxContext;
+ std::unique_ptr<CryptoEngine> mCryptoEngine;
+
+ css::uno::Reference<css::io::XInputStream>
+ getStream(const css::uno::Sequence<css::beans::NamedValue>& rStreams,
+ const rtl::OUString sStreamName);
+
+public:
+ StrongEncryptionDataSpace(const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+
+ // Decryption
+
+ virtual sal_Bool SAL_CALL generateEncryptionKey(const OUString& rPassword) override;
+ virtual sal_Bool SAL_CALL
+ readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) override;
+ virtual sal_Bool SAL_CALL
+ decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
+ css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override;
+
+ virtual sal_Bool SAL_CALL checkDataIntegrity() override;
+
+ // Encryption
+
+ virtual css::uno::Sequence<css::beans::NamedValue>
+ SAL_CALL encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream) override;
+
+ virtual sal_Bool SAL_CALL
+ setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override;
+
+ virtual css::uno::Sequence<css::beans::NamedValue>
+ SAL_CALL createEncryptionData(const OUString& rPassword) override;
+};
+
+} // namespace crypto
+} // namespace oox
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk
index 2d4718a320cb..51b61a931cd1 100644
--- a/oox/Library_oox.mk
+++ b/oox/Library_oox.mk
@@ -102,6 +102,7 @@ $(eval $(call gb_Library_add_exception_objects,oox,\
oox/source/crypto/DocumentEncryption \
oox/source/crypto/DocumentDecryption \
oox/source/crypto/Standard2007Engine \
+ oox/source/crypto/StrongEncryptionDataSpace \
oox/source/docprop/docprophandler \
oox/source/docprop/ooxmldocpropimport \
oox/source/drawingml/chart/axiscontext \
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index f59b15c56df9..565ac9c8d9a6 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -250,16 +250,16 @@ bool lclIsZipPackage( const Reference< XComponentContext >& rxContext, const Ref
class PasswordVerifier : public IDocPasswordVerifier
{
public:
- explicit PasswordVerifier( DocumentDecryption& aDecryptor );
+ explicit PasswordVerifier( crypto::DocumentDecryption& aDecryptor );
virtual DocPasswordVerifierResult verifyPassword( const OUString& rPassword, Sequence<NamedValue>& rEncryptionData ) override;
virtual DocPasswordVerifierResult verifyEncryptionData( const Sequence<NamedValue>& rEncryptionData ) override;
private:
- DocumentDecryption& mDecryptor;
+ crypto::DocumentDecryption& mDecryptor;
};
-PasswordVerifier::PasswordVerifier( DocumentDecryption& aDecryptor ) :
+PasswordVerifier::PasswordVerifier( crypto::DocumentDecryption& aDecryptor ) :
mDecryptor(aDecryptor)
{}
@@ -308,7 +308,7 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript
{
try
{
- DocumentDecryption aDecryptor(mxContext, aOleStorage);
+ crypto::DocumentDecryption aDecryptor(mxContext, aOleStorage);
if( aDecryptor.readEncryptionInfo() )
{
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index fe7e541de4b3..91be91736911 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -908,7 +908,7 @@ bool XmlFilterBase::implFinalizeExport( MediaDescriptor& rMediaDescriptor )
Reference< XStream> xDocumentStream (FilterBase::implGetOutputStream(rMediaDescriptor));
oox::ole::OleStorage aOleStorage( getComponentContext(), xDocumentStream, true );
- DocumentEncryption encryptor( getComponentContext(), getMainDocumentStream(), aOleStorage, aMediaEncData );
+ crypto::DocumentEncryption encryptor( getComponentContext(), getMainDocumentStream(), aOleStorage, aMediaEncData );
bRet = encryptor.encrypt();
if (bRet)
aOleStorage.commit();
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
index fea1498cc8b9..e232a7ef94c3 100644
--- a/oox/source/crypto/AgileEngine.cxx
+++ b/oox/source/crypto/AgileEngine.cxx
@@ -21,7 +21,6 @@
#include <comphelper/processfactory.hxx>
#include <comphelper/base64.hxx>
#include <comphelper/sequence.hxx>
-#include <comphelper/sequenceashashmap.hxx>
#include <filter/msfilter/mscodec.hxx>
#include <tools/stream.hxx>
@@ -29,8 +28,6 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XStream.hpp>
-#include <com/sun/star/io/SequenceInputStream.hpp>
-#include <com/sun/star/io/XSequenceOutputStream.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
@@ -46,15 +43,7 @@ using namespace css::xml::sax;
using namespace css::xml;
namespace oox {
-namespace core {
-
-extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
- com_sun_star_comp_oox_crypto_Agile_get_implementation(
- XComponentContext* pCtx, Sequence<Any> const& /*arguments*/)
-{
- return cppu::acquire(new AgileEngine(pCtx/*, arguments*/));
-}
-
+namespace crypto {
namespace {
@@ -159,13 +148,13 @@ public:
comphelper::Base64::decode(encryptedKeyValue, rAttribute.Value);
mInfo.encryptedKeyValue = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(encryptedKeyValue);
}
- else if (rAttrLocalName == "encryptedHmacKey")
+ if (rAttrLocalName == "encryptedHmacKey")
{
Sequence<sal_Int8> aValue;
comphelper::Base64::decode(aValue, rAttribute.Value);
mInfo.hmacEncryptedKey = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(aValue);
}
- else if (rAttrLocalName == "encryptedHmacValue")
+ if (rAttrLocalName == "encryptedHmacValue")
{
Sequence<sal_Int8> aValue;
comphelper::Base64::decode(aValue, rAttribute.Value);
@@ -229,9 +218,8 @@ CryptoHashType cryptoHashTypeFromString(OUString const & sAlgorithm)
} // namespace
-AgileEngine::AgileEngine(const Reference< XComponentContext >& rxContext) :
- meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512),
- mxContext(rxContext)
+AgileEngine::AgileEngine()
+ : meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512)
{}
Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo)
@@ -358,7 +346,7 @@ void AgileEngine::decryptEncryptionKey(OUString const & rPassword)
}
// TODO: Rename
-sal_Bool AgileEngine::generateEncryptionKey(OUString const & rPassword)
+bool AgileEngine::generateEncryptionKey(OUString const & rPassword)
{
bool bResult = decryptAndCheckVerifierHash(rPassword);
@@ -422,7 +410,7 @@ bool AgileEngine::decryptHmacValue()
return true;
}
-sal_Bool AgileEngine::checkDataIntegrity()
+bool AgileEngine::checkDataIntegrity()
{
bool bResult = (mInfo.hmacHash.size() == mInfo.hmacCalculatedHash.size() &&
std::equal(mInfo.hmacHash.begin(), mInfo.hmacHash.end(), mInfo.hmacCalculatedHash.begin()));
@@ -430,14 +418,11 @@ sal_Bool AgileEngine::checkDataIntegrity()
return bResult;
}
-sal_Bool AgileEngine::decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
- css::uno::Reference<css::io::XOutputStream>& rxOutputStream)
+bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
+ BinaryXOutputStream& aOutputStream)
{
CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm));
- BinaryXInputStream aInputStream(rxInputStream, true);
- BinaryXOutputStream aOutputStream(rxOutputStream, true);
-
sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes
// account for size in HMAC
std::vector<sal_uInt8> aSizeBytes(sizeof(sal_uInt32));
@@ -495,39 +480,17 @@ sal_Bool AgileEngine::decrypt(const css::uno::Reference<css::io::XInputStream>&
mInfo.hmacCalculatedHash = aCryptoHash.finalize();
- rxOutputStream->flush();
-
return true;
}
-uno::Reference<io::XInputStream> AgileEngine::getStream(const Sequence<NamedValue> & rStreams, const OUString sStreamName)
+bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputStream)
{
- for (const auto & aStream : rStreams)
- {
- if (aStream.Name == sStreamName)
- {
- css::uno::Sequence<sal_Int8> aSeq;
- aStream.Value >>= aSeq;
- Reference<XInputStream> aStream(io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW);
- return aStream;
- }
- }
- return nullptr;
-}
-
-sal_Bool AgileEngine::readEncryptionInfo(const Sequence<NamedValue>& aStreams)
-{
- uno::Reference<io::XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo");
-
- BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
- aBinaryInputStream.readuInt32(); // Version
-
// Check reserved value
std::vector<sal_uInt8> aExpectedReservedBytes(sizeof(sal_uInt32));
ByteOrderConverter::writeLittleEndian(aExpectedReservedBytes.data(), msfilter::AGILE_ENCRYPTION_RESERVED);
uno::Sequence<sal_Int8> aReadReservedBytes(sizeof(sal_uInt32));
- xEncryptionInfo->readBytes(aReadReservedBytes, aReadReservedBytes.getLength());
+ rxInputStream->readBytes(aReadReservedBytes, aReadReservedBytes.getLength());
if (!std::equal(aReadReservedBytes.begin(), aReadReservedBytes.end(), aExpectedReservedBytes.begin()))
return false;
@@ -547,7 +510,7 @@ sal_Bool AgileEngine::readEncryptionInfo(const Sequence<NamedValue>& aStreams)
xParser->setTokenHandler(xFastTokenHandler);
InputSource aInputSource;
- aInputSource.aInputStream = xEncryptionInfo;
+ aInputSource.aInputStream = rxInputStream;
xParser->parseStream(aInputSource);
// CHECK info data
@@ -619,7 +582,7 @@ bool AgileEngine::encryptHmacKey()
return false;
// Encrypted salt must be multiple of block size
- sal_Int32 nEncryptedSaltSize = oox::core::roundUp(mInfo.hashSize, mInfo.blockSize);
+ sal_Int32 nEncryptedSaltSize = oox::crypto::roundUp(mInfo.hashSize, mInfo.blockSize);
// We need to extend hmacSalt to multiple of block size, padding with 0x36
std::vector<sal_uInt8> extendedSalt(mInfo.hmacKey);
@@ -695,33 +658,14 @@ bool AgileEngine::encryptEncryptionKey(OUString const & rPassword)
return true;
}
-sal_Bool AgileEngine::setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData)
+bool AgileEngine::setupEncryption(OUString const & rPassword)
{
if (meEncryptionPreset == AgileEncryptionPreset::AES_128_SHA1)
setupEncryptionParameters({ 100000, 16, 128, 20, 16, OUString("AES"), OUString("ChainingModeCBC"), OUString("SHA1") });
else
setupEncryptionParameters({ 100000, 16, 256, 64, 16, OUString("AES"), OUString("ChainingModeCBC"), OUString("SHA512") });
- OUString sPassword;
- for (int i = 0; i < rMediaEncData.getLength(); i++)
- {
- if (rMediaEncData[i].Name == "OOXPassword")
- {
- OUString sCryptoType;
- rMediaEncData[i].Value >>= sPassword;
- }
- }
-
- return setupEncryptionKey(sPassword);
-}
-
-uno::Sequence<beans::NamedValue> AgileEngine::createEncryptionData(const OUString & rPassword)
-{
- comphelper::SequenceAsHashMap aEncryptionData;
- aEncryptionData["OOXPassword"] <<= rPassword;
- aEncryptionData["CryptoType"] <<= OUString("AgileEngine");
-
- return aEncryptionData.getAsConstNamedValueList();
+ return setupEncryptionKey(rPassword);
}
void AgileEngine::setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters)
@@ -755,13 +699,8 @@ bool AgileEngine::setupEncryptionKey(OUString const & rPassword)
return true;
}
-css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptionInfo()
+void AgileEngine::writeEncryptionInfo(BinaryXOutputStream & rStream)
{
- Reference<XOutputStream> aEncryptionInfoStream(
- mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext),
- UNO_QUERY);
- BinaryXOutputStream rStream(aEncryptionInfoStream, false);
-
rStream.WriteUInt32(msfilter::VERSION_INFO_AGILE);
rStream.WriteUInt32(msfilter::AGILE_ENCRYPTION_RESERVED);
@@ -815,29 +754,19 @@ css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptionInfo()
aXmlWriter.endDocument();
}
rStream.writeMemory(aMemStream.GetData(), aMemStream.GetSize());
-
- rStream.close();
- aEncryptionInfoStream->flush();
-
- Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY);
- return aEncryptionInfoSequenceStream->getWrittenBytes();
}
-css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptedDocument(const css::uno::Reference<css::io::XInputStream>& rxInputStream)
+void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream,
+ css::uno::Reference<css::io::XOutputStream> & rxOutputStream,
+ sal_uInt32 nSize)
{
CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm));
- Reference<XOutputStream> aOutputStream(
- mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext),
- UNO_QUERY);
- BinaryXOutputStream aBinaryOutputStream(aOutputStream, false);
-
+ BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false);
BinaryXInputStream aBinaryInputStream(rxInputStream, false);
- Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY);
- sal_uInt32 nLength = xSeekable->getLength();
std::vector<sal_uInt8> aSizeBytes(sizeof(sal_uInt32));
- ByteOrderConverter::writeLittleEndian(aSizeBytes.data(), nLength);
+ ByteOrderConverter::writeLittleEndian(aSizeBytes.data(), nSize);
aBinaryOutputStream.writeMemory(aSizeBytes.data(), aSizeBytes.size()); // size
aCryptoHash.update(aSizeBytes, aSizeBytes.size());
@@ -867,7 +796,7 @@ css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptedDocument(const css::uno:
while ((inputLength = aBinaryInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
{
sal_uInt32 correctedInputLength = inputLength % mInfo.blockSize == 0 ?
- inputLength : oox::core::roundUp(inputLength, sal_uInt32(mInfo.blockSize));
+ inputLength : oox::crypto::roundUp(inputLength, sal_uInt32(mInfo.blockSize));
// Update Key
sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&nSegment);
@@ -888,21 +817,9 @@ css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptedDocument(const css::uno:
}
mInfo.hmacHash = aCryptoHash.finalize();
encryptHmacValue();
-
- Reference<XSequenceOutputStream> aSequenceStream(aOutputStream, UNO_QUERY);
- return aSequenceStream->getWrittenBytes();
-}
-
-
-css::uno::Sequence<css::beans::NamedValue> AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream)
-{
- comphelper::SequenceAsHashMap aStreams;
- aStreams["EncryptedPackage"] <<= writeEncryptedDocument(rxInputStream);
- aStreams["EncryptionInfo"] <<= writeEncryptionInfo();
- return aStreams.getAsConstNamedValueList();
}
-} // namespace core
+} // namespace crypto
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/CryptTools.cxx b/oox/source/crypto/CryptTools.cxx
index 96290e0dc5fc..f1c2b6bbb2ee 100644
--- a/oox/source/crypto/CryptTools.cxx
+++ b/oox/source/crypto/CryptTools.cxx
@@ -25,7 +25,7 @@
#endif // USE_TLS_NSS
namespace oox {
-namespace core {
+namespace crypto {
#if USE_TLS_OPENSSL
struct CryptoImpl
@@ -481,7 +481,7 @@ std::vector<sal_uInt8> CryptoHash::finalize()
return aHash;
}
-} // namespace core
+} // namespace crypto
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx
index 8c8c52dd4a42..198d2f3e5c1f 100644
--- a/oox/source/crypto/DocumentDecryption.cxx
+++ b/oox/source/crypto/DocumentDecryption.cxx
@@ -9,6 +9,7 @@
*/
#include <oox/crypto/DocumentDecryption.hxx>
+#include <oox/helper/binaryinputstream.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <cppuhelper/implbase.hxx>
@@ -21,6 +22,15 @@
#include <oox/ole/olestorage.hxx>
#include <filter/msfilter/mscodec.hxx>
+#include <com/sun/star/task/PasswordRequestMode.hpp>
+#include <comphelper/docpasswordrequest.hxx>
+#include <comphelper/stillreadwriteinteraction.hxx>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+#include <sal/log.hxx>
+
namespace {
void lcl_getListOfStreams(oox::StorageBase* pStorage, std::vector<OUString>& rElementNames)
@@ -47,7 +57,7 @@ void lcl_getListOfStreams(oox::StorageBase* pStorage, std::vector<OUString>& rEl
}
namespace oox {
-namespace core {
+namespace crypto {
using namespace css;
@@ -84,33 +94,6 @@ bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword)
return false;
}
-void DocumentDecryption::readStrongEncryptionInfo()
-{
- uno::Reference<io::XInputStream> xEncryptionInfo = mrOleStorage.openInputStream("EncryptionInfo");
-
- BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
- sal_uInt32 aVersion = aBinaryInputStream.readuInt32();
-
- uno::Sequence< uno::Any > aArguments;
-
- switch (aVersion)
- {
- case msfilter::VERSION_INFO_2007_FORMAT:
- case msfilter::VERSION_INFO_2007_FORMAT_SP2:
- mxPackageEncryption.set(
- mxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
- "com.sun.star.comp.oox.crypto.Standard2007Engine", aArguments, mxContext), css::uno::UNO_QUERY);
- break;
- case msfilter::VERSION_INFO_AGILE:
- mxPackageEncryption.set(
- mxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
- "com.sun.star.comp.oox.crypto.AgileEngine", aArguments, mxContext), css::uno::UNO_QUERY);
- break;
- default:
- break;
- }
-}
-
bool DocumentDecryption::readEncryptionInfo()
{
if (!mrOleStorage.isStorage())
@@ -118,6 +101,8 @@ bool DocumentDecryption::readEncryptionInfo()
// Read 0x6DataSpaces/DataSpaceMap
uno::Reference<io::XInputStream> xDataSpaceMap = mrOleStorage.openInputStream("\006DataSpaces/DataSpaceMap");
+ OUString sDataSpaceName;
+
if (xDataSpaceMap.is())
{
BinaryXInputStream aDataSpaceStream(xDataSpaceMap, true);
@@ -126,7 +111,6 @@ bool DocumentDecryption::readEncryptionInfo()
sal_uInt32 aEntryCount = aDataSpaceStream.readuInt32();
SAL_WARN_IF(aEntryCount != 1, "oox", "DataSpaceMap contains more than one entry. Some content may be skipped");
- OUString sDataSpaceName;
// Read each DataSpaceMapEntry (MS-OFFCRYPTO 2.1.6.1)
for (sal_uInt32 i = 0; i < aEntryCount; i++)
{
@@ -147,25 +131,20 @@ bool DocumentDecryption::readEncryptionInfo()
sDataSpaceName = aDataSpaceStream.readUnicodeArray(aDataSpaceNameLength / 2);
aDataSpaceStream.skip((4 - (aDataSpaceNameLength & 3)) & 3); // Skip padding
}
-
- uno::Sequence< uno::Any > aArguments;
- mxPackageEncryption.set(
- mxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
- "com.sun.star.comp.oox.crypto." + sDataSpaceName, aArguments, mxContext), css::uno::UNO_QUERY);
-
- if (!mxPackageEncryption.is() && sDataSpaceName == "StrongEncryptionDataSpace")
- {
- readStrongEncryptionInfo();
- }
}
else
{
// Fallback for documents generated by LO: they sometimes do not have all
// required by MS-OFFCRYPTO specification streams (0x6DataSpaces/DataSpaceMap and others)
SAL_WARN("oox", "Encrypted package does not contain DataSpaceMap");
- readStrongEncryptionInfo();
+ sDataSpaceName = "StrongEncryptionDataSpace";
}
+ uno::Sequence< uno::Any > aArguments;
+ mxPackageEncryption.set(
+ mxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto." + sDataSpaceName, aArguments, mxContext), css::uno::UNO_QUERY);
+
if (!mxPackageEncryption.is())
{
// we do not know how to decrypt this document
@@ -210,7 +189,7 @@ bool DocumentDecryption::decrypt(const uno::Reference<io::XStream>& xDocumentStr
return bResult;
}
-} // namespace core
+} // namespace crypto
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx
index 70b7f2a3a4e9..026f767fafa0 100644
--- a/oox/source/crypto/DocumentEncryption.cxx
+++ b/oox/source/crypto/DocumentEncryption.cxx
@@ -16,10 +16,12 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <oox/helper/binaryoutputstream.hxx>
#include <oox/ole/olestorage.hxx>
+#include <sal/log.hxx>
namespace oox {
-namespace core {
+namespace crypto {
using namespace css::io;
using namespace css::uno;
@@ -43,7 +45,7 @@ DocumentEncryption::DocumentEncryption(const Reference< XComponentContext >& rxC
rMediaEncData[i].Value >>= sCryptoType;
if (sCryptoType == "Standard")
- sCryptoType = "Standard2007Engine";
+ sCryptoType = "StrongEncryptionDataSpace";
Sequence<Any> aArguments;
mxPackageEncryption.set(
@@ -96,7 +98,7 @@ bool DocumentEncryption::encrypt()
return true;
}
-} // namespace core
+} // namespace crypto
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
index 9ddde339b1d5..f89b29f48ccb 100644
--- a/oox/source/crypto/Standard2007Engine.cxx
+++ b/oox/source/crypto/Standard2007Engine.cxx
@@ -10,10 +10,6 @@
#include <oox/crypto/Standard2007Engine.hxx>
-#include <com/sun/star/io/XStream.hpp>
-#include <com/sun/star/io/XSeekable.hpp>
-#include <com/sun/star/io/SequenceInputStream.hpp>
-#include <com/sun/star/io/XSequenceOutputStream.hpp>
#include <oox/crypto/CryptTools.hxx>
#include <oox/helper/binaryinputstream.hxx>
#include <oox/helper/binaryoutputstream.hxx>
@@ -21,20 +17,9 @@
#include <rtl/random.h>
#include <comphelper/hash.hxx>
-#include <comphelper/sequenceashashmap.hxx>
-
-using namespace css::io;
-using namespace css::uno;
namespace oox {
-namespace core {
-
-extern "C" SAL_DLLPUBLIC_EXPORT XInterface*
- com_sun_star_comp_oox_crypto_Standard2007_get_implementation(
- XComponentContext* pCtx, Sequence<Any> const& /*arguments*/)
-{
- return cppu::acquire(new Standard2007Engine(pCtx/*, arguments*/));
-}
+namespace crypto {
/* =========================================================================== */
/* Kudos to Caolan McNamara who provided the core decryption implementations. */
@@ -54,12 +39,6 @@ constexpr const sal_uInt32 AES128Size = 16;
} // end anonymous namespace
-Standard2007Engine::Standard2007Engine(const css::uno::Reference<css::uno::XComponentContext>& rxContext)
- : mxContext(rxContext)
-{
-
-}
-
bool Standard2007Engine::generateVerifier()
{
// only support key of size 128 bit (16 byte)
@@ -138,7 +117,7 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
return true;
}
-sal_Bool Standard2007Engine::generateEncryptionKey(const OUString& password)
+bool Standard2007Engine::generateEncryptionKey(const OUString& password)
{
mKey.clear();
/*
@@ -180,12 +159,9 @@ sal_Bool Standard2007Engine::generateEncryptionKey(const OUString& password)
return std::equal(hash.begin(), hash.end(), verifierHash.begin());
}
-sal_Bool Standard2007Engine::decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
- css::uno::Reference<css::io::XOutputStream>& rxOutputStream)
+bool Standard2007Engine::decrypt(BinaryXInputStream& aInputStream,
+ BinaryXOutputStream& aOutputStream)
{
- BinaryXInputStream aInputStream(rxInputStream, true);
- BinaryXOutputStream aOutputStream(rxOutputStream, true);
-
sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes
aInputStream.skip(4); // Reserved 4 Bytes
@@ -204,27 +180,15 @@ sal_Bool Standard2007Engine::decrypt(const css::uno::Reference<css::io::XInputSt
aOutputStream.writeMemory(outputBuffer.data(), writeLength);
remaining -= outputLength;
}
-
- rxOutputStream->flush();
-
return true;
}
-sal_Bool Standard2007Engine::checkDataIntegrity()
+bool Standard2007Engine::checkDataIntegrity()
{
return true;
}
-css::uno::Sequence<css::beans::NamedValue> Standard2007Engine::createEncryptionData(const OUString& rPassword)
-{
- comphelper::SequenceAsHashMap aEncryptionData;
- aEncryptionData["OOXPassword"] <<= rPassword;
- aEncryptionData["CryptoType"] <<= OUString("Standard2007Engine");
-
- return aEncryptionData.getAsConstNamedValueList();
-}
-
-sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData)
+bool Standard2007Engine::setupEncryption(OUString const & password)
{
mInfo.header.flags = msfilter::ENCRYPTINFO_AES | msfilter::ENCRYPTINFO_CRYPTOAPI;
mInfo.header.algId = msfilter::ENCRYPT_ALGO_AES128;
@@ -238,17 +202,7 @@ sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans
mKey.clear();
mKey.resize(keyLength, 0);
- OUString sPassword;
- for (int i = 0; i < rMediaEncData.getLength(); i++)
- {
- if (rMediaEncData[i].Name == "OOXPassword")
- {
- OUString sCryptoType;
- rMediaEncData[i].Value >>= sPassword;
- }
- }
-
- if (!calculateEncryptionKey(sPassword))
+ if (!calculateEncryptionKey(password))
return false;
if (!generateVerifier())
@@ -257,13 +211,8 @@ sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans
return true;
}
-css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptionInfo()
+void Standard2007Engine::writeEncryptionInfo(BinaryXOutputStream& rStream)
{
- Reference<XOutputStream> aEncryptionInfoStream(
- mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext),
- UNO_QUERY);
- BinaryXOutputStream rStream(aEncryptionInfoStream, false);
-
rStream.WriteUInt32(msfilter::VERSION_INFO_2007_FORMAT);
sal_uInt32 cspNameSize = (lclCspName.getLength() * 2) + 2;
@@ -279,25 +228,19 @@ css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptionInfo()
rStream.WriteUInt16(0);
rStream.writeMemory(&mInfo.verifier, sizeof(msfilter::EncryptionVerifierAES));
-
- rStream.close();
- aEncryptionInfoStream->flush();
-
- Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY);
- return aEncryptionInfoSequenceStream->getWrittenBytes();
}
-css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptedDocument(const css::uno::Reference<css::io::XInputStream> & rxInputStream)
+void Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream,
+ css::uno::Reference<css::io::XOutputStream> & rxOutputStream,
+ sal_uInt32 nSize)
{
- Reference<XOutputStream> aOutputStream(
- mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext),
- UNO_QUERY);
- BinaryXOutputStream aBinaryOutputStream(aOutputStream, false);
+ if (mKey.empty())
+ return;
+ BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false);
BinaryXInputStream aBinaryInputStream(rxInputStream, false);
- Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY);
- aBinaryOutputStream.WriteUInt32(xSeekable->getLength()); // size
+ aBinaryOutputStream.WriteUInt32(nSize); // size
aBinaryOutputStream.WriteUInt32(0U); // reserved
std::vector<sal_uInt8> inputBuffer(1024);
@@ -317,43 +260,11 @@ css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptedDocument(const cs
outputLength = aEncryptor.update(outputBuffer, inputBuffer, inputLength);
aBinaryOutputStream.writeMemory(outputBuffer.data(), outputLength);
}
-
- Reference<XSequenceOutputStream> aSequenceStream(aOutputStream, UNO_QUERY);
- return aSequenceStream->getWrittenBytes();
-}
-
-css::uno::Sequence<css::beans::NamedValue> Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream)
-{
- if (mKey.empty())
- return css::uno::Sequence<css::beans::NamedValue>();
-
- comphelper::SequenceAsHashMap aStreams;
-
- aStreams["EncryptedPackage"] <<= writeEncryptedDocument(rxInputStream);
- aStreams["EncryptionInfo"] <<= writeEncryptionInfo();
- return aStreams.getAsConstNamedValueList();
-}
-
-css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(const css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName)
-{
- for (const auto & aStream : rStreams)
- {
- if (aStream.Name == sStreamName)
- {
- css::uno::Sequence<sal_Int8> aSeq;
- aStream.Value >>= aSeq;
- Reference<XInputStream> aStream(css::io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW);
- return aStream;
- }
- }
- return nullptr;
}
-sal_Bool Standard2007Engine::readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams)
+bool Standard2007Engine::readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream)
{
- Reference<css::io::XInputStream> rxInputStream = getStream(aStreams, "EncryptionInfo");
BinaryXInputStream aBinaryStream(rxInputStream, false);
- aBinaryStream.readuInt32(); // Version
mInfo.header.flags = aBinaryStream.readuInt32();
if (getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_EXTERNAL))
@@ -407,7 +318,7 @@ sal_Bool Standard2007Engine::readEncryptionInfo(const css::uno::Sequence<css::be
return !aBinaryStream.isEof();
}
-} // namespace core
+} // namespace crypto
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/StrongEncryptionDataSpace.cxx b/oox/source/crypto/StrongEncryptionDataSpace.cxx
new file mode 100644
index 000000000000..cfcab3cd4a59
--- /dev/null
+++ b/oox/source/crypto/StrongEncryptionDataSpace.cxx
@@ -0,0 +1,191 @@
+/* -*- 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 <oox/crypto/StrongEncryptionDataSpace.hxx>
+#include <oox/crypto/AgileEngine.hxx>
+#include <oox/crypto/Standard2007Engine.hxx>
+#include <oox/helper/binaryoutputstream.hxx>
+#include <oox/helper/binaryinputstream.hxx>
+#include <com/sun/star/io/SequenceInputStream.hpp>
+#include <com/sun/star/io/XSequenceOutputStream.hpp>
+
+#include <comphelper/sequenceashashmap.hxx>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::uno;
+
+namespace oox
+{
+namespace crypto
+{
+StrongEncryptionDataSpace::StrongEncryptionDataSpace(const Reference<XComponentContext>& rxContext)
+ : mxContext(rxContext)
+ , mCryptoEngine(new Standard2007Engine())
+{
+}
+
+sal_Bool StrongEncryptionDataSpace::generateEncryptionKey(const OUString& rPassword)
+{
+ if (!mCryptoEngine)
+ return false;
+
+ return mCryptoEngine->generateEncryptionKey(rPassword);
+}
+
+sal_Bool StrongEncryptionDataSpace::checkDataIntegrity()
+{
+ if (!mCryptoEngine)
+ return false;
+
+ return mCryptoEngine->checkDataIntegrity();
+}
+
+sal_Bool StrongEncryptionDataSpace::decrypt(const Reference<XInputStream>& rxInputStream,
+ Reference<XOutputStream>& rxOutputStream)
+{
+ if (!mCryptoEngine)
+ return false;
+
+ BinaryXInputStream aInputStream(rxInputStream, true);
+ BinaryXOutputStream aOutputStream(rxOutputStream, true);
+
+ mCryptoEngine->decrypt(aInputStream, aOutputStream);
+
+ rxOutputStream->flush();
+ return true;
+}
+
+Reference<XInputStream> StrongEncryptionDataSpace::getStream(const Sequence<NamedValue>& rStreams,
+ const OUString sStreamName)
+{
+ for (const auto& aStream : rStreams)
+ {
+ if (aStream.Name == sStreamName)
+ {
+ Sequence<sal_Int8> aSeq;
+ aStream.Value >>= aSeq;
+ Reference<XInputStream> aStream(
+ io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq),
+ UNO_QUERY_THROW);
+ return aStream;
+ }
+ }
+ return nullptr;
+}
+
+sal_Bool StrongEncryptionDataSpace::readEncryptionInfo(const Sequence<NamedValue>& aStreams)
+{
+ Reference<XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo");
+ if (!xEncryptionInfo.is())
+ return false;
+
+ BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
+ sal_uInt32 aVersion = aBinaryInputStream.readuInt32();
+
+ Sequence<Any> aArguments;
+
+ switch (aVersion)
+ {
+ case msfilter::VERSION_INFO_2007_FORMAT:
+ case msfilter::VERSION_INFO_2007_FORMAT_SP2:
+ mCryptoEngine.reset(new Standard2007Engine());
+ break;
+ case msfilter::VERSION_INFO_AGILE:
+ mCryptoEngine.reset(new AgileEngine());
+ break;
+ default:
+ break;
+ }
+
+ if (!mCryptoEngine)
+ return false;
+
+ return mCryptoEngine->readEncryptionInfo(xEncryptionInfo);
+}
+
+sal_Bool StrongEncryptionDataSpace::setupEncryption(const Sequence<NamedValue>& rMediaEncData)
+{
+ if (!mCryptoEngine)
+ return false;
+
+ OUString sPassword;
+ for (const auto& aParam : rMediaEncData)
+ {
+ if (aParam.Name == "OOXPassword")
+ {
+ aParam.Value >>= sPassword;
+ }
+ }
+
+ return mCryptoEngine->setupEncryption(sPassword);
+}
+
+Sequence<NamedValue> StrongEncryptionDataSpace::createEncryptionData(const OUString& rPassword)
+{
+ comphelper::SequenceAsHashMap aEncryptionData;
+ aEncryptionData["OOXPassword"] <<= rPassword;
+ aEncryptionData["CryptoType"] <<= OUString("StrongEncryptionDataSpace");
+
+ return aEncryptionData.getAsConstNamedValueList();
+}
+
+Sequence<NamedValue>
+StrongEncryptionDataSpace::encrypt(const Reference<XInputStream>& rxInputStream)
+{
+ if (!mCryptoEngine)
+ return Sequence<NamedValue>();
+
+ Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY);
+ if (!xSeekable.is())
+ return Sequence<NamedValue>();
+
+ sal_uInt32 aLength = xSeekable->getLength(); // check length of the stream
+
+ Reference<XOutputStream> xOutputStream(
+ mxContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.io.SequenceOutputStream", mxContext),
+ UNO_QUERY);
+
+ mCryptoEngine->encrypt(rxInputStream, xOutputStream, aLength);
+
+ comphelper::SequenceAsHashMap aStreams;
+
+ Reference<XSequenceOutputStream> xEncodedFileSequenceStream(xOutputStream, UNO_QUERY);
+ aStreams["EncryptedPackage"] <<= xEncodedFileSequenceStream->getWrittenBytes();
+
+ Reference<XOutputStream> aEncryptionInfoStream(
+ mxContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.io.SequenceOutputStream", mxContext),
+ UNO_QUERY);
+ BinaryXOutputStream rStream(aEncryptionInfoStream, false);
+ mCryptoEngine->writeEncryptionInfo(rStream);
+ aEncryptionInfoStream->flush();
+ Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream,
+ UNO_QUERY);
+
+ aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes();
+
+ return aStreams.getAsConstNamedValueList();
+}
+
+} // namespace crypto
+} // namespace oox
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_oox_crypto_StrongEncryptionDataSpace_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new oox::crypto::StrongEncryptionDataSpace(pCtx));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/util/oox.component b/oox/util/oox.component
index d7167545b2be..cf3a2d4b16f1 100644
--- a/oox/util/oox.component
+++ b/oox/util/oox.component
@@ -40,12 +40,8 @@
constructor="com_sun_star_comp_oox_ShapeContextHandler_get_implementation">
<service name="com.sun.star.xml.sax.FastShapeContextHandler"/>
</implementation>
- <implementation name="com.sun.star.comp.oox.crypto.Standard2007Engine"
- constructor="com_sun_star_comp_oox_crypto_Standard2007_get_implementation">
- <service name="com.sun.star.packages.XPackageEncryption"/>
- </implementation>
- <implementation name="com.sun.star.comp.oox.crypto.AgileEngine"
- constructor="com_sun_star_comp_oox_crypto_Agile_get_implementation">
+ <implementation name="com.sun.star.comp.oox.crypto.StrongEncryptionDataSpace"
+ constructor="com_sun_star_comp_oox_crypto_StrongEncryptionDataSpace_get_implementation">
<service name="com.sun.star.packages.XPackageEncryption"/>
</implementation>
</component>
commit b64ab30695c5e26d880192dbdde11a8c5ae9ef7f
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Thu Nov 21 21:11:02 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
oox: exception on password veryfy attempt is ending loop
If we receive an exception on createEncryptionData() there is
no reason to ask user for another password.
Change-Id: I7fa0949c737af20396ae7958e0e80d97af7cfe10
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index 7e72d28482df..f59b15c56df9 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -265,8 +265,16 @@ PasswordVerifier::PasswordVerifier( DocumentDecryption& aDecryptor ) :
comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword, Sequence<NamedValue>& rEncryptionData )
{
- if(mDecryptor.generateEncryptionKey(rPassword))
- rEncryptionData = mDecryptor.createEncryptionData(rPassword);
+ try
+ {
+ if (mDecryptor.generateEncryptionKey(rPassword))
+ rEncryptionData = mDecryptor.createEncryptionData(rPassword);
+ }
+ catch (...)
+ {
+ // Any exception is a reason to abort
+ return comphelper::DocPasswordVerifierResult::Abort;
+ }
return rEncryptionData.hasElements() ? comphelper::DocPasswordVerifierResult::OK : comphelper::DocPasswordVerifierResult::WrongPassword;
}
commit d505e72051d3e9a92e94c5c40a9bbb8bb3052dd5
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Mon Nov 18 11:26:23 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
package: ignore unknown encryption parameters.
Do not throw an exception if there are encryption parameters,
but they are not supported in current output format.
Change-Id: I21e4cf2f73d7c218ab5444b2016e838695163ca3
Conflicts:
package/source/zippackage/ZipPackage.cxx
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 78627441b506..a66e3a63b22f 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -1646,11 +1646,6 @@ const uno::Sequence< sal_Int8 > ZipPackage::GetEncryptionKey()
for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ )
if ( m_aStorageEncryptionKeys[nInd].Name == aNameToFind )
m_aStorageEncryptionKeys[nInd].Value >>= aResult;
-
- // empty keys are not allowed here
- // so it is not important whether there is no key, or the key is empty, it is an error
- if ( !aResult.hasElements() )
- throw uno::RuntimeException(THROW_WHERE "No expected key is provided!" );
}
else
aResult = m_aEncryptionKey;
commit 204b7d65f3cee79ec07d911d7d398bf4fc52be67
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Wed Nov 13 09:19:42 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:54 2019 +0100
ms doc: pass additional arguments to encryption service
XPackageEncryption mplementation should distingush types
of files fo possibility to encrypt them in a different way.
So additional parameter is provided to resolve this issue.
Change-Id: I3cdff6c6b85f2483138ad5ddba7799fb7bf8be95
diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx
index 2e4015e34569..463afe74b90a 100644
--- a/sc/source/filter/excel/excel.cxx
+++ b/sc/source/filter/excel/excel.cxx
@@ -261,7 +261,8 @@ static ErrCode lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
if (sCryptoType.getLength())
{
uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
- uno::Sequence<uno::Any> aArguments;
+ uno::Sequence<uno::Any> aArguments(1);
+ aArguments[0] = uno::makeAny(beans::NamedValue("Binary", uno::makeAny(true)));
xPackageEncryption.set(
xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY);
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index f2ec9038c7b1..1678a1f04451 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -268,7 +268,8 @@ bool SdPPTFilter::Export()
if (sCryptoType.getLength())
{
Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
- Sequence<Any> aArguments;
+ Sequence<Any> aArguments(1);
+ aArguments[0] = makeAny(NamedValue("Binary", makeAny(true)));
xPackageEncryption.set(
xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), UNO_QUERY);
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 04f770ea858c..c65fb7298aa3 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3561,7 +3561,8 @@ ErrCode SwWW8Writer::WriteStorage()
if (sCryptoType.getLength())
{
uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
- uno::Sequence<uno::Any> aArguments;
+ uno::Sequence<uno::Any> aArguments(1);
+ aArguments[0] = uno::makeAny(beans::NamedValue("Binary", uno::makeAny(true)));
xPackageEncryption.set(
xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY);
commit 97ac37b02a80508a0ef4b35285d768dc06d50767
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Wed Dec 4 13:34:57 2019 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:19:50 2019 +0100
Fixup Add document-level option for lock-downs
Change-Id: I52dda76fd779e7b5afce6599b1d8deb25056fb9b
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 218dc2eab259..117a9f77346d 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -1061,48 +1061,41 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs)
for (int i = 0; i < aArgs.getLength(); i++)
{
OUString sValue;
- aArgs[i].Value >>= sValue;
bool bValue;
+ aArgs[i].Value >>= sValue;
+ aArgs[i].Value >>= bValue;
if (aArgs[i].Name == "SuggestedSaveAsName")
{
- rArg.Value >>= sValue;
pMedium->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME, sValue));
}
else if (aArgs[i].Name == "SuggestedSaveAsDir")
{
- rArg.Value >>= sValue;
pMedium->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR, sValue));
}
- else if (rArg.Name == "LockContentExtraction")
+ else if (aArgs[i].Name == "LockContentExtraction")
{
- rArg.Value >>= bValue;
pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION, bValue));
}
- else if (rArg.Name == "LockExport")
+ else if (aArgs[i].Name == "LockExport")
{
- rArg.Value >>= bValue;
pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EXPORT, bValue));
}
- else if (rArg.Name == "LockPrint")
+ else if (aArgs[i].Name == "LockPrint")
{
- rArg.Value >>= bValue;
pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_PRINT, bValue));
}
- else if (rArg.Name == "LockSave")
+ else if (aArgs[i].Name == "LockSave")
{
- rArg.Value >>= bValue;
pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_SAVE, bValue));
}
- else if (rArg.Name == "LockEditDoc")
+ else if (aArgs[i].Name == "LockEditDoc")
{
- rArg.Value >>= bValue;
pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EDITDOC, bValue));
}
- else if (rArg.Name == "EncryptionData")
+ else if (aArgs[i].Name == "EncryptionData")
{
- rArg.Value >>= bValue;
- pMedium->GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, rArg.Value));
+ pMedium->GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, aArgs[i].Value));
}
else
{
commit a52f2a82ca33d31ef7491f57bfa0a306a8235ed1
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 8 21:17:10 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:13:37 2019 +0100
sd: support for DRM encryption during saving to ppt
Change-Id: Id82f8b3fa7ea045b00d7d81e2c9ce5e130c8060c
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index bb42b9d4bc11..f2ec9038c7b1 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -19,17 +19,21 @@
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
+#include <sfx2/frame.hxx>
#include <filter/msfilter/msoleexp.hxx>
#include <svx/svxerr.hxx>
#include <unotools/fltrcfg.hxx>
+#include <unotools/streamwrap.hxx>
#include <sot/storage.hxx>
#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/processfactory.hxx>
#include <com/sun/star/packages/XPackageEncryption.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <sdpptwrp.hxx>
#include <DrawDocShell.hxx>
+#include <sfx2/sfxsids.hrc>
using namespace ::com::sun::star::uno;
@@ -219,8 +223,6 @@ bool SdPPTFilter::Export()
if( mxModel.is() )
{
- tools::SvRef<SotStorage> xStorRef = new SotStorage( mrMedium.GetOutStream(), false );
-
#ifdef DISABLE_DYNLOADING
ExportPPTPointer PPTExport = ExportPPT;
#else
@@ -228,7 +230,7 @@ bool SdPPTFilter::Export()
SdFilter::GetLibrarySymbol(mrMedium.GetFilter()->GetUserData(), "ExportPPT"));
#endif
- if( PPTExport && xStorRef.is() )
+ if( PPTExport)
{
sal_uInt32 nCnvrtFlags = 0;
const SvtFilterOptions& rFilterOptions = SvtFilterOptions::Get();
@@ -252,8 +254,105 @@ bool SdPPTFilter::Export()
aProperty.Value <<= mrMedium.GetBaseURL( true );
aProperties.push_back( aProperty );
- bRet = PPTExport( aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags );
- xStorRef->Commit();
+ SvStream * pOutputStrm = mrMedium.GetOutStream();
+
+ Sequence< NamedValue > aEncryptionData;
+ Reference< css::packages::XPackageEncryption > xPackageEncryption;
+ const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mrMedium.GetItemSet(), SID_ENCRYPTIONDATA, false);
+ std::shared_ptr<SvStream> pMediaStrm;
+ if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData))
+ {
+ ::comphelper::SequenceAsHashMap aHashData(aEncryptionData);
+ OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString());
+
+ if (sCryptoType.getLength())
+ {
+ Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ Sequence<Any> aArguments;
+ xPackageEncryption.set(
+ xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), UNO_QUERY);
+
+ if (xPackageEncryption.is())
+ {
+ // We have an encryptor. Export document into memory stream and encrypt it later
+ pMediaStrm.reset(new SvMemoryStream());
+ pOutputStrm = pMediaStrm.get();
+
+ // Temp removal of EncryptionData to avoid password protection triggering
+ mrMedium.GetItemSet()->ClearItem(SID_ENCRYPTIONDATA);
+ }
+ }
+ }
+
+ tools::SvRef<SotStorage> xStorRef = new SotStorage(pOutputStrm, false);
+
+ if (xStorRef.is())
+ {
+ bRet = PPTExport(aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags);
+ xStorRef->Commit();
+
+ if (xPackageEncryption.is())
+ {
+ // Perform DRM encryption
+ pOutputStrm->Seek(0);
+
+ xPackageEncryption->setupEncryption(aEncryptionData);
+
+ Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pOutputStrm, false));
+ Sequence<NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream);
+
+ tools::SvRef<SotStorage> xEncryptedRootStrg = new SotStorage(mrMedium.GetOutStream(), false);
+ for (const NamedValue & aStreamData : aStreams)
+ {
+ // To avoid long paths split and open substorages recursively
+ // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09
+ SotStorage * pStorage = xEncryptedRootStrg.get();
+ OUString sFileName;
+ sal_Int32 idx = 0;
+ do
+ {
+ OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx);
+ if (!sPathElem.isEmpty())
+ {
+ if (idx < 0)
+ {
+ sFileName = sPathElem;
+ }
+ else
+ {
+ pStorage = pStorage->OpenSotStorage(sPathElem);
+ }
+ }
+ } while (pStorage && idx >= 0);
+
+ if (!pStorage)
+ {
+ bRet = false;
+ break;
+ }
+
+ SotStorageStream* pStream = pStorage->OpenSotStream(sFileName);
+ if (!pStream)
+ {
+ bRet = false;
+ break;
+ }
+ Sequence<sal_Int8> aStreamContent;
+ aStreamData.Value >>= aStreamContent;
+ size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength());
+ if (nBytesWritten != (size_t)aStreamContent.getLength())
+ {
+ bRet = false;
+ break;
+ }
+ }
+ xEncryptedRootStrg->Commit();
+
+ // Restore encryption data
+ mrMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData)));
+ }
+ }
}
}
commit 0a9c0a330d7bebee358ee26207c798f437a0caa3
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 8 21:00:12 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:13:37 2019 +0100
sd: support of DRM encrypted ppt files reading
Change-Id: Ib91538d53ee1f53a3cd14a44d47fd6f6136c0472
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index edc21c482d45..bb42b9d4bc11 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -23,6 +23,10 @@
#include <svx/svxerr.hxx>
#include <unotools/fltrcfg.hxx>
#include <sot/storage.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
#include <sdpptwrp.hxx>
#include <DrawDocShell.hxx>
@@ -67,9 +71,101 @@ SdPPTFilter::~SdPPTFilter()
delete pBas; // deleting the compressed basic storage
}
+static void lcl_getListOfStreams(SotStorage * pStorage, comphelper::SequenceAsHashMap& aStreamsData, const OUString& sPrefix)
+{
+ SvStorageInfoList aElements;
+ pStorage->FillInfoList(&aElements);
+ for (const auto & aElement : aElements)
+ {
+ OUString sStreamFullName = sPrefix.getLength() ? sPrefix + "/" + aElement.GetName() : aElement.GetName();
+ if (aElement.IsStorage())
+ {
+ SotStorage * pSubStorage = pStorage->OpenSotStorage(aElement.GetName(), StreamMode::STD_READ | StreamMode::SHARE_DENYALL);
+ lcl_getListOfStreams(pSubStorage, aStreamsData, sStreamFullName);
+ }
+ else
+ {
+ // Read stream
+ tools::SvRef<SotStorageStream> rStream = pStorage->OpenSotStream(aElement.GetName(), StreamMode::READ | StreamMode::SHARE_DENYALL);
+ assert(rStream.is());
+
+ sal_Int32 nStreamSize = rStream->GetSize();
+ Sequence< sal_Int8 > oData;
+ oData.realloc(nStreamSize);
+ sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize);
+ assert(nStreamSize == nReadBytes);
+ aStreamsData[sStreamFullName] <<= oData;
+ }
+ }
+}
+
+static tools::SvRef<SotStorage> lcl_DRMDecrypt(SfxMedium& rMedium, tools::SvRef<SotStorage>& rStorage, std::shared_ptr<SvStream>& rNewStorageStrm)
+{
+ tools::SvRef<SotStorage> aNewStorage;
+
+ // We have DRM encrypted storage. We should try to decrypt it first, if we can
+ Sequence< Any > aArguments;
+ Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ Reference< css::packages::XPackageEncryption > xPackageEncryption(
+ xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto.DRMDataSpace", aArguments, xComponentContext), UNO_QUERY);
+
+ if (!xPackageEncryption.is())
+ {
+ // We do not know how to decrypt this
+ return aNewStorage;
+ }
+
+ std::vector<OUString> aStreamsList;
+ comphelper::SequenceAsHashMap aStreamsData;
+ lcl_getListOfStreams(rStorage.get(), aStreamsData, OUString(""));
+
+ try {
+ Sequence<NamedValue> aStreams = aStreamsData.getAsConstNamedValueList();
+ if (!xPackageEncryption->readEncryptionInfo(aStreams))
+ {
+ // We failed with decryption
+ return aNewStorage;
+ }
+
+ tools::SvRef<SotStorageStream> rContentStream = rStorage->OpenSotStream("\011DRMContent", StreamMode::READ | StreamMode::SHARE_DENYALL);
+ if (!rContentStream.is())
+ {
+ return aNewStorage;
+ }
+
+ rNewStorageStrm.reset(new SvMemoryStream());
+
+ Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false));
+ Reference<css::io::XOutputStream > xDecryptedStream(new utl::OSeekableOutputStreamWrapper(*rNewStorageStrm.get()));
+
+ if (!xPackageEncryption->decrypt(xInputStream, xDecryptedStream))
+ {
+ // We failed with decryption
+ return aNewStorage;
+ }
+
+ rNewStorageStrm->Seek(0);
+
+ // Further reading is done from new document
+ aNewStorage = new SotStorage(*rNewStorageStrm);
+
+ // Set the media descriptor data
+ Sequence<NamedValue> aEncryptionData = xPackageEncryption->createEncryptionData("");
+ rMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData)));
+ }
+ catch (const std::exception&)
+ {
+ return aNewStorage;
+ }
+
+ return aNewStorage;
+}
+
bool SdPPTFilter::Import()
{
bool bRet = false;
+ std::shared_ptr<SvStream> aDecryptedStorageStrm;
tools::SvRef<SotStorage> pStorage = new SotStorage( mrMedium.GetInStream(), false );
if( !pStorage->GetError() )
{
@@ -82,6 +178,12 @@ bool SdPPTFilter::Import()
xDualStorage = pStorage->OpenSotStorage( sDualStorage, StreamMode::STD_READ );
pStorage = xDualStorage;
}
+ OUString sDRMContent("\011DRMContent");
+ if (pStorage->IsContained(sDRMContent))
+ {
+ // Document is DRM encrypted
+ pStorage = lcl_DRMDecrypt(mrMedium, pStorage, aDecryptedStorageStrm);
+ }
std::unique_ptr<SvStream> pDocStream(pStorage->OpenSotStream( "PowerPoint Document" , StreamMode::STD_READ ));
if( pDocStream )
{
commit 94d4c5b2bee411a9307889ad1cf1c9f58fcb51f2
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 8 18:28:41 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:13:37 2019 +0100
calc: support for writing DRM encrypted xls files
Change-Id: I5faf885cf494becca2838c6493413bcc56e91826
diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx
index 56adce29a061..2e4015e34569 100644
--- a/sc/source/filter/excel/excel.cxx
+++ b/sc/source/filter/excel/excel.cxx
@@ -24,7 +24,7 @@
#include <sot/exchange.hxx>
#include <filter/msfilter/classids.hxx>
#include <tools/globname.hxx>
-#include <com/sun/star/packages/XPAckageEncryption.hpp>
+#include <com/sun/star/packages/XPackageEncryption.hpp>
#include <com/sun/star/ucb/ContentCreationException.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <unotools/streamwrap.hxx>
@@ -248,6 +248,36 @@ ErrCode ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument*
static ErrCode lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
SvStream* pMedStrm, bool bBiff8, rtl_TextEncoding eNach )
{
+ uno::Reference< packages::XPackageEncryption > xPackageEncryption;
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+ const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(rMedium.GetItemSet(), SID_ENCRYPTIONDATA, false);
+ SvStream* pOriginalMediaStrm = pMedStrm;
+ std::shared_ptr<SvStream> pMediaStrm;
+ if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData))
+ {
+ ::comphelper::SequenceAsHashMap aHashData(aEncryptionData);
+ OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString());
+
+ if (sCryptoType.getLength())
+ {
+ uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ uno::Sequence<uno::Any> aArguments;
+ xPackageEncryption.set(
+ xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY);
+
+ if (xPackageEncryption.is())
+ {
+ // We have an encryptor. Export document into memory stream and encrypt it later
+ pMediaStrm.reset(new SvMemoryStream());
+ pMedStrm = pMediaStrm.get();
+
+ // Temp removal of EncryptionData to avoid password protection triggering
+ rMedium.GetItemSet()->ClearItem(SID_ENCRYPTIONDATA);
+ }
+ }
+ }
+
// try to open an OLE storage
tools::SvRef<SotStorage> xRootStrg = new SotStorage( pMedStrm, false );
if( xRootStrg->GetError() ) return SCERR_IMPORT_OPEN;
@@ -296,6 +326,67 @@ static ErrCode lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
xStrgStrm->Commit();
xRootStrg->Commit();
+ if (xPackageEncryption.is())
+ {
+ // Perform DRM encryption
+ pMedStrm->Seek(0);
+
+ xPackageEncryption->setupEncryption(aEncryptionData);
+
+ uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pMedStrm, false));
+ uno::Sequence<beans::NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream);
+
+ tools::SvRef<SotStorage> xEncryptedRootStrg = new SotStorage(pOriginalMediaStrm, false);
+ for (const beans::NamedValue & aStreamData : aStreams)
+ {
+ // To avoid long paths split and open substorages recursively
+ // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09
+ SotStorage * pStorage = xEncryptedRootStrg.get();
+ OUString sFileName;
+ sal_Int32 idx = 0;
+ do
+ {
+ OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx);
+ if (!sPathElem.isEmpty())
+ {
+ if (idx < 0)
+ {
+ sFileName = sPathElem;
+ }
+ else
+ {
+ pStorage = pStorage->OpenSotStorage(sPathElem);
+ }
+ }
+ } while (pStorage && idx >= 0);
+
+ if (!pStorage)
+ {
+ eRet = ERRCODE_IO_GENERAL;
+ break;
+ }
+
+ SotStorageStream* pStream = pStorage->OpenSotStream(sFileName);
+ if (!pStream)
+ {
+ eRet = ERRCODE_IO_GENERAL;
+ break;
+ }
+ uno::Sequence<sal_Int8> aStreamContent;
+ aStreamData.Value >>= aStreamContent;
+ size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength());
+ if (nBytesWritten != aStreamContent.getLength())
+ {
+ eRet = ERRCODE_IO_CANTWRITE;
+ break;
+ }
+ }
+ xEncryptedRootStrg->Commit();
+
+ // Restore encryption data
+ rMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, uno::makeAny(aEncryptionData)));
+ }
+
return eRet;
}
commit 31fdf71cb23c9c5c843ef88815a437fbaa979429
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 8 17:53:30 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 17:13:37 2019 +0100
calc: support for reading DRM encrypted xls files
DRM encryption is implemented as an optional service, so
just use it when available.
Change-Id: Ie580e5c12c48ccf99f9a932b1c66eb35866b7ef4
diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx
index ca87efc2988c..56adce29a061 100644
--- a/sc/source/filter/excel/excel.cxx
+++ b/sc/source/filter/excel/excel.cxx
@@ -24,7 +24,9 @@
#include <sot/exchange.hxx>
#include <filter/msfilter/classids.hxx>
#include <tools/globname.hxx>
+#include <com/sun/star/packages/XPAckageEncryption.hpp>
#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
#include <unotools/streamwrap.hxx>
#include <osl/diagnose.h>
#include <filter.hxx>
@@ -32,6 +34,8 @@
#include <xistream.hxx>
#include <xltools.hxx>
#include <docoptio.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/processfactory.hxx>
#include <docsh.hxx>
#include <scerrors.hxx>
@@ -42,6 +46,99 @@
#include <memory>
+using namespace css;
+
+static void lcl_getListOfStreams(SotStorage * pStorage, comphelper::SequenceAsHashMap& aStreamsData, const OUString& sPrefix)
+{
+ SvStorageInfoList aElements;
+ pStorage->FillInfoList(&aElements);
+ for (const auto & aElement : aElements)
+ {
+ OUString sStreamFullName = sPrefix.getLength() ? sPrefix + "/" + aElement.GetName() : aElement.GetName();
+ if (aElement.IsStorage())
+ {
+ SotStorage * pSubStorage = pStorage->OpenSotStorage(aElement.GetName(), StreamMode::STD_READ | StreamMode::SHARE_DENYALL);
+ lcl_getListOfStreams(pSubStorage, aStreamsData, sStreamFullName);
+ }
+ else
+ {
+ // Read stream
+ tools::SvRef<SotStorageStream> rStream = pStorage->OpenSotStream(aElement.GetName(), StreamMode::READ | StreamMode::SHARE_DENYALL);
+ assert(rStream.is());
+
+ sal_Int32 nStreamSize = rStream->GetSize();
+ uno::Sequence< sal_Int8 > oData;
+ oData.realloc(nStreamSize);
+ sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize);
+ assert(nStreamSize == nReadBytes);
+ aStreamsData[sStreamFullName] <<= oData;
+ }
+ }
+}
+
+static tools::SvRef<SotStorage> lcl_DRMDecrypt(SfxMedium& rMedium, tools::SvRef<SotStorage>& rStorage, std::shared_ptr<SvStream>& rNewStorageStrm)
+{
+ tools::SvRef<SotStorage> aNewStorage;
+
+ // We have DRM encrypted storage. We should try to decrypt it first, if we can
+ uno::Sequence< uno::Any > aArguments;
+ uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ uno::Reference< packages::XPackageEncryption > xPackageEncryption(
+ xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto.DRMDataSpace", aArguments, xComponentContext), uno::UNO_QUERY);
+
+ if (!xPackageEncryption.is())
+ {
+ // We do not know how to decrypt this
+ return aNewStorage;
+ }
+
+ std::vector<OUString> aStreamsList;
+ comphelper::SequenceAsHashMap aStreamsData;
+ lcl_getListOfStreams(rStorage.get(), aStreamsData, OUString(""));
+
+ try {
+ uno::Sequence<beans::NamedValue> aStreams = aStreamsData.getAsConstNamedValueList();
+ if (!xPackageEncryption->readEncryptionInfo(aStreams))
+ {
+ // We failed with decryption
+ return aNewStorage;
+ }
+
+ tools::SvRef<SotStorageStream> rContentStream = rStorage->OpenSotStream("\011DRMContent", StreamMode::READ | StreamMode::SHARE_DENYALL);
+ if (!rContentStream.is())
+ {
+ return aNewStorage;
+ }
+
+ rNewStorageStrm.reset(new SvMemoryStream());
+
+ uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false));
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list