summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2020-05-25 02:15:42 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2020-05-25 10:05:33 +0200
commitc6665a0fc8cdad31160daad65c10894cd3174584 (patch)
tree07a3978098bf13cca561229ac57ff0b56df92791 /sw/source
parentf1c1a4de8f17128191e1c6d26a737b88fcc31fc9 (diff)
sw: add XPackageEncryption save support for binary doc
This adds save support for API-based MS-CRYPTO algos. If we have custom encryption data in media descriptor and corresponding service is available it will be used during saving. Change-Id: I814e4a7f73979ff7a65831b99f77f1a9e85916de Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84438 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/filter/ww8/wrtww8.cxx105
-rw-r--r--sw/source/filter/ww8/wrtww8.hxx1
2 files changed, 106 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 91d049a42e11..c3fe9c0a36f9 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -23,7 +23,10 @@
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/streamwrap.hxx>
#include <algorithm>
#include <map>
#include <hintids.hxx>
@@ -87,6 +90,8 @@
#include "sprmids.hxx"
#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
#include "writerhelper.hxx"
#include "writerwordglue.hxx"
#include "ww8attributeoutput.hxx"
@@ -3667,6 +3672,106 @@ void WW8Export::PrepareStorage()
ErrCode SwWW8Writer::WriteStorage()
{
+ tools::SvRef<SotStorage> pOrigStg;
+ uno::Reference< packages::XPackageEncryption > xPackageEncryption;
+ std::shared_ptr<SvStream> pSotStorageStream;
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+ if (mpMedium)
+ {
+ // Check for specific encryption requests
+ const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mpMedium->GetItemSet(), SID_ENCRYPTIONDATA, false);
+ 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{
+ 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);
+
+ if (xPackageEncryption.is())
+ {
+ // We have an encryptor
+ // Create new temporary storage for content
+ pOrigStg = m_pStg;
+ pSotStorageStream = std::make_shared<SvMemoryStream>();
+ m_pStg = new SotStorage(*pSotStorageStream);
+ }
+ }
+ }
+ }
+
+ ErrCode nErrorCode = WriteStorageImpl();
+
+ if (xPackageEncryption.is())
+ {
+ m_pStg->Commit();
+ pSotStorageStream->Seek(0);
+
+ // Encrypt data written into temporary storage
+ xPackageEncryption->setupEncryption(aEncryptionData);
+
+ uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pSotStorageStream.get(), false));
+ uno::Sequence<beans::NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream);
+
+ m_pStg = pOrigStg;
+ for (const beans::NamedValue & aStreamData : std::as_const(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 = m_pStg.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);
+ if (!pStorage)
+ break;
+ }
+ }
+ } while (pStorage && idx >= 0);
+
+ if (!pStorage)
+ {
+ nErrorCode = ERRCODE_IO_GENERAL;
+ break;
+ }
+
+ SotStorageStream* pStream = pStorage->OpenSotStream(sFileName);
+ if (!pStream)
+ {
+ nErrorCode = ERRCODE_IO_GENERAL;
+ break;
+ }
+ uno::Sequence<sal_Int8> aStreamContent;
+ aStreamData.Value >>= aStreamContent;
+ size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength());
+ if (nBytesWritten != static_cast<size_t>(aStreamContent.getLength()))
+ {
+ nErrorCode = ERRCODE_IO_CANTWRITE;
+ break;
+ }
+ }
+ }
+
+ return nErrorCode;
+}
+ErrCode SwWW8Writer::WriteStorageImpl()
+{
// #i34818# - update layout (if present), for SwWriteTable
SwViewShell* pViewShell = m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
if( pViewShell != nullptr )
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 99063ef12a20..8c66df7a630a 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -983,6 +983,7 @@ public:
private:
SwWW8Writer(const SwWW8Writer&) = delete;
SwWW8Writer& operator=(const SwWW8Writer&) = delete;
+ ErrCode WriteStorageImpl();
};
/// Exporter of the binary Word file formats.