[Libreoffice-commits] core.git: Branch 'feature/cib_contract3756b' - 50 commits - basctl/source comphelper/source external/breakpad framework/inc framework/Library_fwk.mk framework/source .gitreview include/oox include/sfx2 include/vcl offapi/com offapi/UnoApi_offapi.mk officecfg/registry oox/Library_oox.mk oox/qa oox/source oox/util package/source scripting/java scripting/Library_protocolhandler.mk scripting/source sc/source sd/source sfx2/sdi sfx2/source sw/qa sw/source unotools/source vcl/inc vcl/source

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Wed Dec 4 13:13:46 UTC 2019


Rebased ref, commits from common ancestor:
commit f39319f3ad7edff51a47fd7051261d07f12e531d
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 13:46:19 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 b0b5f44b40dda469240b31cb701deccad021983d
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 13:46:19 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 9e3663754726c4e187295690830bd5922ad3b9d4
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 13:46:19 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 90825b13b152b6582f97c01254b4290d3a03780c
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 13:46:19 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 431c0aeea513fff51aaf8229722b9f7898dad895
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 13:46:11 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 3d067b50b795a0dd7cb732bc09bb3a902a4eba1c
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 13:46:10 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 2f31eae4ddb34b078cb865d46cd07f84ba5ddfe4
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 13:46:10 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 bf2afc96a7e8f3dfde634138b5f5828a1f303e75
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 13:46:10 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 0b9e6b3be162f0fe3791dbc85f088de063d43c9b
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 13:46:10 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 53b4541641751bb3655398ed1ee7faaf3cbde474
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 13:46:10 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 df214e8b7309..fb6e10534255 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -1061,53 +1061,45 @@ 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 == "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 34e5d88775c75b2abe5a773d6e281e09da49d63c
Author:     Serge Krot <Serge.Krot at cib.de>
AuthorDate: Tue Nov 12 21:52:05 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Dec 4 13:44:37 2019 +0100

    Add document level option to lock down edit doc command
    
    Change-Id: I431fa4cd0daa52c885030dbadcc4052b5a890d34
    Reviewed-on: https://gerrit.libreoffice.org/82553
    Reviewed-by: Serge Krot (CIB) <Serge.Krot at cib.de>
    Tested-by: Serge Krot (CIB) <Serge.Krot at cib.de>

diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 218dc2eab259..df214e8b7309 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -1099,6 +1099,11 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs)
             rArg.Value >>= bValue;
             pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EDITDOC, bValue));
         }
+        else if (rArg.Name == "LockEditDoc")
+        {
+            rArg.Value >>= bValue;
+            pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EDITDOC, bValue));
+        }
         else if (rArg.Name == "EncryptionData")
         {
             rArg.Value >>= bValue;
commit 71f202f7804f7f9fdf0b3078d69eccc811a7d934
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 13:44: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 affbd9dfc756fc7db87a2491675a450b21d33515
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 13:44: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 79ce65b09a9065deca3a15e7837f98a28fa19cef
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 13:44: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 e1f1c3a05fa0cb335e6ccf2cc4043cd883d120c0
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 13:44: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;
+

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list