From ab607e604d82ccdfbe584f50951de5afef17dbd2 Mon Sep 17 00:00:00 2001 From: Vasily Melenchuk Date: Fri, 27 Sep 2019 11:56:00 +0300 Subject: msdoc crypto: move crypto engines to service New interface XPackageEncryption was created. All existing crypto engines are refactored to be implmentations of this interface. Change-Id: Id063aca1474f76a926a2e47eecd4c12ebe79650f Conflicts: include/oox/crypto/AgileEngine.hxx include/oox/crypto/Standard2007Engine.hxx oox/source/crypto/DocumentDecryption.cxx --- include/oox/crypto/AgileEngine.hxx | 28 ++--- include/oox/crypto/CryptoEngine.hxx | 68 ----------- include/oox/crypto/DocumentDecryption.hxx | 5 +- include/oox/crypto/DocumentEncryption.hxx | 4 +- include/oox/crypto/IRMEngine.hxx | 42 +++---- include/oox/crypto/Standard2007Engine.hxx | 30 ++--- offapi/UnoApi_offapi.mk | 1 + .../com/sun/star/packages/XPackageEncryption.idl | 84 +++++++++++++ oox/source/crypto/AgileEngine.cxx | 63 +++++++--- oox/source/crypto/DocumentDecryption.cxx | 72 ++++++----- oox/source/crypto/DocumentEncryption.cxx | 53 ++++---- oox/source/crypto/IRMEngine.cxx | 133 +++++++++++++-------- oox/source/crypto/Standard2007Engine.cxx | 61 +++++++--- oox/util/oox.component | 16 +++ 14 files changed, 391 insertions(+), 269 deletions(-) delete mode 100644 include/oox/crypto/CryptoEngine.hxx create mode 100644 offapi/com/sun/star/packages/XPackageEncryption.idl diff --git a/include/oox/crypto/AgileEngine.hxx b/include/oox/crypto/AgileEngine.hxx index 60d19fed11db..3a8b49e21de8 100644 --- a/include/oox/crypto/AgileEngine.hxx +++ b/include/oox/crypto/AgileEngine.hxx @@ -15,9 +15,9 @@ #include #include -#include #include #include +#include namespace oox { class BinaryXInputStream; @@ -74,7 +74,7 @@ enum class AgileEncryptionPreset AES_256_SHA512, }; -class OOX_DLLPUBLIC AgileEngine : public CryptoEngine +class OOX_DLLPUBLIC AgileEngine : public cppu::WeakImplHelper { private: std::vector mKey; @@ -82,7 +82,7 @@ private: AgileEncryptionPreset meEncryptionPreset; css::uno::Reference< css::uno::XComponentContext > mxContext; - css::uno::Reference getStream(css::uno::Sequence & rStreams, const OUString sStreamName); + css::uno::Reference getStream(const css::uno::Sequence & rStreams, const OUString sStreamName); void calculateHashFinal(const OUString& rPassword, std::vector& aHashFinal); @@ -131,24 +131,24 @@ public: // Decryption - bool generateEncryptionKey(OUString const & rPassword) override; - bool readEncryptionInfo(css::uno::Sequence aStreams) override; - bool decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) override; + sal_Bool generateEncryptionKey(const OUString & rPassword) override; + sal_Bool readEncryptionInfo(const css::uno::Sequence& aStreams) override; + sal_Bool decrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) override; - bool checkDataIntegrity() override; + + sal_Bool checkDataIntegrity() override; // Encryption - void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; + css::uno::Sequence writeEncryptionInfo() override; - void encrypt(css::uno::Reference& rxInputStream, - css::uno::Reference& rxOutputStream, - sal_uInt32 nSize) override; + void encrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) override; - bool setupEncryption(css::uno::Sequence& rMediaEncData) override; + sal_Bool setupEncryption(const css::uno::Sequence& rMediaEncData) override; - virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override; + css::uno::Sequence createEncryptionData(const OUString& rPassword) override; }; } // namespace core diff --git a/include/oox/crypto/CryptoEngine.hxx b/include/oox/crypto/CryptoEngine.hxx deleted file mode 100644 index f985f2d7fb45..000000000000 --- a/include/oox/crypto/CryptoEngine.hxx +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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 - -#include -#include - -#include -#include -#include - -namespace oox { - class BinaryXInputStream; - class BinaryXOutputStream; -} - -namespace oox { -namespace core { - -class CryptoEngine -{ -public: - CryptoEngine() - {} - - virtual ~CryptoEngine() - {} - - // Decryption - virtual bool readEncryptionInfo(css::uno::Sequence aStreams) = 0; - - virtual bool generateEncryptionKey(const OUString& rPassword) = 0; - - virtual bool decrypt( - BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) = 0; - - // Encryption - virtual void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) = 0; - - virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) = 0; - - virtual bool setupEncryption(css::uno::Sequence& rMediaEncData) = 0; - - virtual void encrypt(css::uno::Reference & rxInputStream, - css::uno::Reference & rxOutputStream, - sal_uInt32 nSize) = 0; - - virtual bool checkDataIntegrity() = 0; -}; - -} // namespace core -} // 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 248f33f61734..fdea2c25f9f7 100644 --- a/include/oox/crypto/DocumentDecryption.hxx +++ b/include/oox/crypto/DocumentDecryption.hxx @@ -17,7 +17,6 @@ #include #include -#include #include namespace com { namespace sun { namespace star { @@ -25,6 +24,7 @@ namespace com { namespace sun { namespace star { namespace io { class XInputStream; } namespace io { class XStream; } namespace uno { class XComponentContext; } + namespace packages { class XPackageEncryption; } } } } namespace oox { namespace ole { class OleStorage; } } @@ -37,8 +37,7 @@ class OOX_DLLPUBLIC DocumentDecryption private: oox::ole::OleStorage& mrOleStorage; css::uno::Sequence maStreamsSequence; - std::unique_ptr mEngine; - OUString msEngineName; + css::uno::Reference< css::packages::XPackageEncryption > mxPackageEncryption; css::uno::Reference< css::uno::XComponentContext > mxContext; void readStrongEncryptionInfo(); diff --git a/include/oox/crypto/DocumentEncryption.hxx b/include/oox/crypto/DocumentEncryption.hxx index 76bdfe3a67fb..12b8db92c0d9 100644 --- a/include/oox/crypto/DocumentEncryption.hxx +++ b/include/oox/crypto/DocumentEncryption.hxx @@ -15,12 +15,12 @@ #include #include -#include #include #include namespace com { namespace sun { namespace star { namespace io { class XStream; } + namespace packages { class XPackageEncryption; } } } } namespace oox { namespace ole { class OleStorage; } } @@ -33,7 +33,7 @@ class OOX_DLLPUBLIC DocumentEncryption private: css::uno::Reference< css::io::XStream > mxDocumentStream; oox::ole::OleStorage& mrOleStorage; - std::unique_ptr mEngine; + css::uno::Reference< css::packages::XPackageEncryption > mxPackageEncryption; css::uno::Sequence< css::beans::NamedValue >& mMediaEncData; css::uno::Reference< css::uno::XComponentContext > mxContext; diff --git a/include/oox/crypto/IRMEngine.hxx b/include/oox/crypto/IRMEngine.hxx index 9bf610904a9d..c8ae7b125d86 100644 --- a/include/oox/crypto/IRMEngine.hxx +++ b/include/oox/crypto/IRMEngine.hxx @@ -12,17 +12,10 @@ #define INCLUDED_OOX_CRYPTO_IRMENGINE_HXX #include -#include -#include +#include #include #include -namespace oox -{ -class BinaryXInputStream; -class BinaryXOutputStream; -} - namespace oox { namespace core @@ -33,37 +26,40 @@ struct OOX_DLLPUBLIC IRMEncryptionInfo bool bCanRead; }; -class OOX_DLLPUBLIC IRMEngine : public CryptoEngine +class OOX_DLLPUBLIC IRMEngine : public cppu::WeakImplHelper { IRMEncryptionInfo mInfo; css::uno::Reference mxContext; css::uno::Reference - getStream(css::uno::Sequence& rStreams, const OUString sStreamName); + getStream(const css::uno::Sequence& rStreams, + const OUString sStreamName); public: IRMEngine(const css::uno::Reference& rxContext); - bool readEncryptionInfo(css::uno::Sequence aStreams) override; + // Decryption - virtual bool generateEncryptionKey(OUString const& rPassword) override; + sal_Bool generateEncryptionKey(const OUString& rPassword) override; + sal_Bool + readEncryptionInfo(const css::uno::Sequence& aStreams) override; + sal_Bool decrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) override; - virtual bool decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) override; + sal_Bool checkDataIntegrity() override; - bool checkDataIntegrity() override; + // Encryption - void encrypt(css::uno::Reference& rxInputStream, - css::uno::Reference& rxOutputStream, - sal_uInt32 nSize) override; + css::uno::Sequence writeEncryptionInfo() override; - virtual void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; + void encrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) override; - virtual void createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionData, - const OUString rPassword) override; + sal_Bool + setupEncryption(const css::uno::Sequence& rMediaEncData) override; - virtual bool - setupEncryption(css::uno::Sequence& rMediaEncData) override; + css::uno::Sequence + createEncryptionData(const OUString& rPassword) override; }; } // namespace core diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx index 0af88eada1d7..23a0742df10c 100644 --- a/include/oox/crypto/Standard2007Engine.hxx +++ b/include/oox/crypto/Standard2007Engine.hxx @@ -12,7 +12,7 @@ #define INCLUDED_OOX_CRYPTO_STANDARD2007ENGINE_HXX #include -#include +#include #include #include #include @@ -26,7 +26,7 @@ namespace oox { namespace oox { namespace core { -class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine +class OOX_DLLPUBLIC Standard2007Engine : public cppu::WeakImplHelper { msfilter::StandardEncryptionInfo mInfo; std::vector mKey; @@ -35,31 +35,31 @@ class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine bool generateVerifier(); bool calculateEncryptionKey(const OUString& rPassword); - css::uno::Reference getStream(css::uno::Sequence & rStreams, const OUString sStreamName); + css::uno::Reference getStream(const css::uno::Sequence & rStreams, const OUString sStreamName); public: Standard2007Engine(const css::uno::Reference& rxContext); - bool readEncryptionInfo(css::uno::Sequence aStreams) override; + // Decryption - virtual bool generateEncryptionKey(OUString const & rPassword) override; + sal_Bool generateEncryptionKey(const OUString & rPassword) override; + sal_Bool readEncryptionInfo(const css::uno::Sequence& aStreams) override; + sal_Bool decrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) override; - virtual bool decrypt( - BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) override; - bool checkDataIntegrity() override; + sal_Bool checkDataIntegrity() override; - void encrypt(css::uno::Reference& rxInputStream, - css::uno::Reference& rxOutputStream, - sal_uInt32 nSize) override; + // Encryption - virtual void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; + css::uno::Sequence writeEncryptionInfo() override; - virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override; + void encrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) override; - virtual bool setupEncryption(css::uno::Sequence& rMediaEncData) override; + sal_Bool setupEncryption(const css::uno::Sequence& rMediaEncData) override; + css::uno::Sequence createEncryptionData(const OUString& rPassword) override; }; } // namespace core diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 6ab05f38b4d5..35538e035330 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -2928,6 +2928,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/packages,\ NoRawFormatException \ WrongPasswordException \ XDataSinkEncrSupport \ + XPackageEncryption \ )) $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/packages/manifest,\ XManifestReader \ diff --git a/offapi/com/sun/star/packages/XPackageEncryption.idl b/offapi/com/sun/star/packages/XPackageEncryption.idl new file mode 100644 index 000000000000..298a089af6c7 --- /dev/null +++ b/offapi/com/sun/star/packages/XPackageEncryption.idl @@ -0,0 +1,84 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef __com_sun_star_packages_XPackageEncryption_idl__ +#define __com_sun_star_packages_XPackageEncryption_idl__ + +#include + +#include +#include + + +module com { module sun { module star { module packages { + + +/** + TODO + */ +interface XPackageEncryption: com::sun::star::uno::XInterface +{ + /** + TODO + */ + boolean readEncryptionInfo([in] sequence < com::sun::star::beans::NamedValue > rOleStreams); + + /** + TODO + */ + boolean generateEncryptionKey([in] string rPassword); + + /** + TODO + */ + boolean decrypt([in] com::sun::star::io::XInputStream rxInputStream, + [out] com::sun::star::io::XOutputStream rxOutputStream); + + /** + TODO + */ + sequence writeEncryptionInfo(); + + /** + TODO + */ + sequence createEncryptionData([in] string rPassword); + + /** + TODO + */ + boolean setupEncryption([in] sequence rMediaEncData); + + /** + TODO + */ + void encrypt([in] com::sun::star::io::XInputStream rxInputStream, + [out] com::sun::star::io::XOutputStream rxOutputStream); + + /** + TODO + */ + boolean checkDataIntegrity(); +}; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx index f1f2b2eb488a..d864539747cc 100644 --- a/oox/source/crypto/AgileEngine.cxx +++ b/oox/source/crypto/AgileEngine.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,14 @@ 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 const& /*arguments*/) +{ + return cppu::acquire(new AgileEngine(pCtx/*, arguments*/)); +} + + namespace { OUString stripNamespacePrefix(OUString const & rsInputName) @@ -349,7 +358,7 @@ void AgileEngine::decryptEncryptionKey(OUString const & rPassword) } // TODO: Rename -bool AgileEngine::generateEncryptionKey(OUString const & rPassword) +sal_Bool AgileEngine::generateEncryptionKey(OUString const & rPassword) { bool bResult = decryptAndCheckVerifierHash(rPassword); @@ -413,7 +422,7 @@ bool AgileEngine::decryptHmacValue() return true; } -bool AgileEngine::checkDataIntegrity() +sal_Bool AgileEngine::checkDataIntegrity() { bool bResult = (mInfo.hmacHash.size() == mInfo.hmacCalculatedHash.size() && std::equal(mInfo.hmacHash.begin(), mInfo.hmacHash.end(), mInfo.hmacCalculatedHash.begin())); @@ -421,11 +430,14 @@ bool AgileEngine::checkDataIntegrity() return bResult; } -bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) +sal_Bool AgileEngine::decrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) { 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 aSizeBytes(sizeof(sal_uInt32)); @@ -483,10 +495,12 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, mInfo.hmacCalculatedHash = aCryptoHash.finalize(); + rxOutputStream->flush(); + return true; } -uno::Reference AgileEngine::getStream(Sequence & rStreams, const OUString sStreamName) +uno::Reference AgileEngine::getStream(const Sequence & rStreams, const OUString sStreamName) { for (const auto & aStream : rStreams) { @@ -501,7 +515,7 @@ uno::Reference AgileEngine::getStream(Sequence & r return nullptr; } -bool AgileEngine::readEncryptionInfo(Sequence aStreams) +sal_Bool AgileEngine::readEncryptionInfo(const Sequence& aStreams) { uno::Reference xEncryptionInfo = getStream(aStreams, "EncryptionInfo"); @@ -681,7 +695,7 @@ bool AgileEngine::encryptEncryptionKey(OUString const & rPassword) return true; } -bool AgileEngine::setupEncryption(css::uno::Sequence& rMediaEncData) +sal_Bool AgileEngine::setupEncryption(const css::uno::Sequence& rMediaEncData) { if (meEncryptionPreset == AgileEncryptionPreset::AES_128_SHA1) setupEncryptionParameters({ 100000, 16, 128, 20, 16, OUString("AES"), OUString("ChainingModeCBC"), OUString("SHA1") }); @@ -691,7 +705,7 @@ bool AgileEngine::setupEncryption(css::uno::Sequence& rM OUString sPassword; for (int i = 0; i < rMediaEncData.getLength(); i++) { - if (rMediaEncData[i].Name == "Password") + if (rMediaEncData[i].Name == "OOXPassword") { OUString sCryptoType; rMediaEncData[i].Value >>= sPassword; @@ -701,9 +715,13 @@ bool AgileEngine::setupEncryption(css::uno::Sequence& rM return setupEncryptionKey(sPassword); } -void AgileEngine::createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) +uno::Sequence AgileEngine::createEncryptionData(const OUString & rPassword) { + comphelper::SequenceAsHashMap aEncryptionData; aEncryptionData["OOXPassword"] <<= rPassword; + aEncryptionData["CryptoType"] <<= OUString("AgileEngine"); + + return aEncryptionData.getAsConstNamedValueList(); } void AgileEngine::setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters) @@ -737,10 +755,12 @@ bool AgileEngine::setupEncryptionKey(OUString const & rPassword) return true; } -void AgileEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) +css::uno::Sequence AgileEngine::writeEncryptionInfo() { - Reference xEncryptionInfo(rOleStorage.openOutputStream("EncryptionInfo"), UNO_SET_THROW); - BinaryXOutputStream rStream(xEncryptionInfo, false); + Reference 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); @@ -797,21 +817,28 @@ void AgileEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) rStream.writeMemory(aMemStream.GetData(), aMemStream.GetSize()); rStream.close(); - xEncryptionInfo->flush(); - xEncryptionInfo->closeOutput(); + aEncryptionInfoStream->flush(); + + // Store all streams into sequence and return back + comphelper::SequenceAsHashMap aStreams; + + Reference aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); + aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes(); + return aStreams.getAsConstNamedValueList(); } -void AgileEngine::encrypt(css::uno::Reference & rxInputStream, - css::uno::Reference & rxOutputStream, - sal_uInt32 nSize) +void AgileEngine::encrypt(const css::uno::Reference & rxInputStream, + css::uno::Reference & rxOutputStream) { CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm)); BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false); BinaryXInputStream aBinaryInputStream(rxInputStream, false); + Reference xSeekable(rxInputStream, UNO_QUERY); + sal_uInt32 nLength = xSeekable->getLength(); std::vector aSizeBytes(sizeof(sal_uInt32)); - ByteOrderConverter::writeLittleEndian(aSizeBytes.data(), nSize); + ByteOrderConverter::writeLittleEndian(aSizeBytes.data(), nLength); aBinaryOutputStream.writeMemory(aSizeBytes.data(), aSizeBytes.size()); // size aCryptoHash.update(aSizeBytes, aSizeBytes.size()); diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx index 9a485688b487..8c8c52dd4a42 100644 --- a/oox/source/crypto/DocumentDecryption.cxx +++ b/oox/source/crypto/DocumentDecryption.cxx @@ -14,14 +14,12 @@ #include #include +#include #include #include -#include -#include -#include -#include -#include +#include #include +#include namespace { @@ -81,8 +79,8 @@ DocumentDecryption::DocumentDecryption(const css::uno::Reference< css::uno::XCom bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword) { - if (mEngine) - return mEngine->generateEncryptionKey(rPassword); + if (mxPackageEncryption.is()) + return mxPackageEncryption->generateEncryptionKey(rPassword); return false; } @@ -93,16 +91,20 @@ void DocumentDecryption::readStrongEncryptionInfo() 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: - msEngineName = "Standard"; // Set encryption info format - mEngine.reset(new Standard2007Engine(mxContext)); + mxPackageEncryption.set( + mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto.Standard2007Engine", aArguments, mxContext), css::uno::UNO_QUERY); break; case msfilter::VERSION_INFO_AGILE: - msEngineName = "Agile"; // Set encryption info format - mEngine.reset(new AgileEngine(mxContext)); + mxPackageEncryption.set( + mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto.AgileEngine", aArguments, mxContext), css::uno::UNO_QUERY); break; default: break; @@ -146,23 +148,15 @@ bool DocumentDecryption::readEncryptionInfo() aDataSpaceStream.skip((4 - (aDataSpaceNameLength & 3)) & 3); // Skip padding } - if (sDataSpaceName == "DRMEncryptedDataSpace") - { - msEngineName = "IRM"; // Set encryption info format - mEngine.reset(new IRMEngine(mxContext)); - } - else if (sDataSpaceName == "\011DRMDataSpace") // 0x09DRMDataSpace - { - // TODO: IRM binary file - } - else if (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() && sDataSpaceName == "StrongEncryptionDataSpace") { readStrongEncryptionInfo(); } - else - { - SAL_WARN("oox", "Unknown dataspace - document will be not decrypted!"); - } } else { @@ -172,20 +166,21 @@ bool DocumentDecryption::readEncryptionInfo() readStrongEncryptionInfo(); } - if (!mEngine) + if (!mxPackageEncryption.is()) + { + // we do not know how to decrypt this document return false; + } - return mEngine->readEncryptionInfo(maStreamsSequence); + return mxPackageEncryption->readEncryptionInfo(maStreamsSequence); } uno::Sequence DocumentDecryption::createEncryptionData(const OUString& rPassword) { - comphelper::SequenceAsHashMap aEncryptionData; + if (!mxPackageEncryption.is()) + return uno::Sequence(); - aEncryptionData["CryptoType"] <<= msEngineName; - mEngine->createEncryptionData(aEncryptionData, rPassword); - - return aEncryptionData.getAsConstNamedValueList(); + return mxPackageEncryption->createEncryptionData(rPassword); } bool DocumentDecryption::decrypt(const uno::Reference& xDocumentStream) @@ -195,21 +190,22 @@ bool DocumentDecryption::decrypt(const uno::Reference& xDocumentStr if (!mrOleStorage.isStorage()) return false; + if (!mxPackageEncryption.is()) + return false; + // open the required input streams in the encrypted package uno::Reference xEncryptedPackage(mrOleStorage.openInputStream("EncryptedPackage"), uno::UNO_QUERY); // create temporary file for unencrypted package uno::Reference xDecryptedPackage(xDocumentStream->getOutputStream(), uno::UNO_QUERY); - BinaryXOutputStream aDecryptedPackage(xDecryptedPackage, true); - BinaryXInputStream aEncryptedPackage(xEncryptedPackage, true); - bResult = mEngine->decrypt(aEncryptedPackage, aDecryptedPackage); + bResult = mxPackageEncryption->decrypt(xEncryptedPackage, xDecryptedPackage); - xDecryptedPackage->flush(); - aDecryptedPackage.seekToStart(); + css::uno::Reference xSeekable(xDecryptedPackage, css::uno::UNO_QUERY); + xSeekable->seek(0); if (bResult) - return mEngine->checkDataIntegrity(); + return mxPackageEncryption->checkDataIntegrity(); return bResult; } diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx index 8aac457c67d2..2dba0f035df5 100644 --- a/oox/source/crypto/DocumentEncryption.cxx +++ b/oox/source/crypto/DocumentEncryption.cxx @@ -9,16 +9,13 @@ */ #include -#include -#include #include #include #include #include +#include -#include -#include #include namespace oox { @@ -26,11 +23,12 @@ namespace core { using namespace css::io; using namespace css::uno; +using namespace css::beans; -DocumentEncryption::DocumentEncryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext, +DocumentEncryption::DocumentEncryption(const Reference< XComponentContext >& rxContext, Reference const & xDocumentStream, oox::ole::OleStorage& rOleStorage, - Sequence& rMediaEncData) + Sequence& rMediaEncData) : mxContext(rxContext) , mxDocumentStream(xDocumentStream) , mrOleStorage(rOleStorage) @@ -43,25 +41,28 @@ DocumentEncryption::DocumentEncryption(const css::uno::Reference< css::uno::XCom { OUString sCryptoType; rMediaEncData[i].Value >>= sCryptoType; - if (sCryptoType == "IRM") - { - mEngine.reset(new IRMEngine(mxContext)); - } - else if (sCryptoType == "Standard" || sCryptoType == "Agile") - { - mEngine.reset(new Standard2007Engine(mxContext)); - } - else + + if (sCryptoType == "Standard") + sCryptoType = "Standard2007Engine"; + + Sequence aArguments; + mxPackageEncryption.set( + mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, mxContext), css::uno::UNO_QUERY); + + if (!mxPackageEncryption.is()) { SAL_WARN("oox", "Requested encryption method \"" << sCryptoType << "\" is not supported"); } + + break; } } } bool DocumentEncryption::encrypt() { - if (!mEngine) + if (!mxPackageEncryption.is()) return false; Reference xInputStream (mxDocumentStream->getInputStream(), UNO_SET_THROW); @@ -70,20 +71,32 @@ bool DocumentEncryption::encrypt() if (!xSeekable.is()) return false; - sal_uInt32 aLength = xSeekable->getLength(); // check length of the stream xSeekable->seek(0); // seek to begin of the document stream if (!mrOleStorage.isStorage()) return false; - mEngine->setupEncryption(mMediaEncData); + mxPackageEncryption->setupEncryption(mMediaEncData); Reference xOutputStream(mrOleStorage.openOutputStream("EncryptedPackage"), UNO_SET_THROW); - mEngine->encrypt(xInputStream, xOutputStream, aLength); + mxPackageEncryption->encrypt(xInputStream, xOutputStream); xOutputStream->flush(); xOutputStream->closeOutput(); - mEngine->writeEncryptionInfo(mrOleStorage); + Sequence aStreams = mxPackageEncryption->writeEncryptionInfo(); + + for (const NamedValue & aStream : aStreams) + { + Reference xOutputStream(mrOleStorage.openOutputStream(aStream.Name), UNO_SET_THROW); + BinaryXOutputStream aBinaryOutputStream(xOutputStream, true); + + css::uno::Sequence aStreamSequence; + aStream.Value >>= aStreamSequence; + + aBinaryOutputStream.writeData(aStreamSequence); + + aBinaryOutputStream.close(); + } return true; } diff --git a/oox/source/crypto/IRMEngine.cxx b/oox/source/crypto/IRMEngine.cxx index 1301a3b51279..95135722ee08 100644 --- a/oox/source/crypto/IRMEngine.cxx +++ b/oox/source/crypto/IRMEngine.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -50,15 +51,26 @@ namespace oox { namespace core { +extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* +com_sun_star_comp_oox_crypto_DRMEncryptedDataSpace_get_implementation( + XComponentContext* pCtx, Sequence const& /*arguments*/) +{ + return cppu::acquire(new IRMEngine(pCtx /*, arguments*/)); +} + IRMEngine::IRMEngine(const Reference& rxContext) : mxContext(rxContext) { } -bool IRMEngine::checkDataIntegrity() { return true; } +sal_Bool IRMEngine::checkDataIntegrity() { return true; } -bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& aOutputStream) +sal_Bool IRMEngine::decrypt(const Reference& rxInputStream, + Reference& rxOutputStream) { + BinaryXInputStream aInputStream(rxInputStream, true); + BinaryXOutputStream aOutputStream(rxOutputStream, true); + aInputStream.readInt64(); // Skip stream size HRESULT hr = IpcInitialize(); @@ -66,6 +78,7 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a { // ERROR_ALREADY_INITIALIZED not an error // TODO: some reaction? + return false; } // Get decryption key @@ -77,6 +90,7 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a if (FAILED(hr)) { // TODO: some reaction? + return false; } // Read rights @@ -85,6 +99,7 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a if (FAILED(hr)) { // TODO: some reaction? + return false; } mInfo.bCanRead = value; @@ -94,6 +109,7 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a if (FAILED(hr)) { // TODO: some reaction? + return false; } char* pEncryptedBuffer = new char[*blockSize]; @@ -112,6 +128,7 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a if (FAILED(hr)) { // TODO: some reaction? + return false; } aOutputStream.writeArray(pDecryptedBuffer, bytes); @@ -122,22 +139,26 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a delete[] pEncryptedBuffer; delete[] pDecryptedBuffer; + rxOutputStream->flush(); + return true; } -void IRMEngine::createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionData, - const OUString rPassword) +uno::Sequence IRMEngine::createEncryptionData(const OUString& /*rPassword*/) { - aEncryptionData["OOXPassword"] <<= rPassword; - css::uno::Sequence seq; seq.realloc(mInfo.license.getLength()); memcpy(seq.getArray(), mInfo.license.getStr(), mInfo.license.getLength()); - aEncryptionData["license"] <<= seq; + comphelper::SequenceAsHashMap aEncryptionData; + aEncryptionData["LicenseKey"] <<= seq; + aEncryptionData["CryptoType"] <<= OUString("DRMEncryptedDataSpace"); + aEncryptionData["OOXPassword"] <<= OUString("1"); + + return aEncryptionData.getAsConstNamedValueList(); } -uno::Reference IRMEngine::getStream(Sequence& rStreams, +uno::Reference IRMEngine::getStream(const Sequence& rStreams, const OUString sStreamName) { for (const auto& aStream : rStreams) @@ -155,7 +176,7 @@ uno::Reference IRMEngine::getStream(Sequence& rStr return nullptr; } -bool IRMEngine::readEncryptionInfo(uno::Sequence aStreams) +sal_Bool IRMEngine::readEncryptionInfo(const uno::Sequence& aStreams) { // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4) uno::Reference xTransformInfoStream @@ -198,11 +219,11 @@ bool IRMEngine::readEncryptionInfo(uno::Sequence aStreams) return true; } -bool IRMEngine::setupEncryption(css::uno::Sequence& rMediaEncData) +sal_Bool IRMEngine::setupEncryption(const Sequence& rMediaEncData) { for (int i = 0; i < rMediaEncData.getLength(); i++) { - if (rMediaEncData[i].Name == "license") + if (rMediaEncData[i].Name == "LicenseKey") { css::uno::Sequence seq; rMediaEncData[i].Value >>= seq; @@ -213,11 +234,13 @@ bool IRMEngine::setupEncryption(css::uno::Sequence& rMed return true; } -void IRMEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) +Sequence IRMEngine::writeEncryptionInfo() { // Write 0x6DataSpaces/DataSpaceMap Reference xDataSpaceMap( - rOleStorage.openOutputStream("\006DataSpaces/DataSpaceMap"), UNO_SET_THROW); + mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); BinaryXOutputStream aDataSpaceMapStream(xDataSpaceMap, false); aDataSpaceMapStream.WriteInt32(8); // Header length @@ -227,42 +250,37 @@ void IRMEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) OUString sDataSpaceName("DRMEncryptedDataSpace"); OUString sReferenceComponent("EncryptedPackage"); - aDataSpaceMapStream.WriteInt32(0x58); // Length + aDataSpaceMapStream.WriteInt32(0x60); // Length aDataSpaceMapStream.WriteInt32(1); // References count aDataSpaceMapStream.WriteInt32(0); // References component type aDataSpaceMapStream.WriteInt32(sReferenceComponent.getLength() * 2); aDataSpaceMapStream.writeUnicodeArray(sReferenceComponent); - while (aDataSpaceMapStream.tell() % 4) // Padding + for (int i = 0; i < sReferenceComponent.getLength() * 2 % 4; i++) // Padding { aDataSpaceMapStream.writeValue(0); } aDataSpaceMapStream.WriteInt32(sDataSpaceName.getLength() * 2); aDataSpaceMapStream.writeUnicodeArray(sDataSpaceName); - while (aDataSpaceMapStream.tell() % 4) // Padding + for (int i = 0; i < sDataSpaceName.getLength() * 2 % 4; i++) // Padding { aDataSpaceMapStream.writeValue(0); } - // Write length - sal_uInt32 nLength = aDataSpaceMapStream.tell() - 8; - aDataSpaceMapStream.seek(8); - aDataSpaceMapStream.WriteInt32(nLength); - aDataSpaceMapStream.close(); xDataSpaceMap->flush(); - xDataSpaceMap->closeOutput(); // Write 0x6DataSpaces/Version - Reference xVersion(rOleStorage.openOutputStream("\006DataSpaces/Version"), - UNO_SET_THROW); + Reference xVersion(mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); BinaryXOutputStream aVersionStream(xVersion, false); OUString sFeatureIdentifier("Microsoft.Container.DataSpaces"); aVersionStream.WriteInt32(sFeatureIdentifier.getLength() * 2); aVersionStream.writeUnicodeArray(sFeatureIdentifier); - while (aVersionStream.tell() % 4) // Padding + for (int i = 0; i < sFeatureIdentifier.getLength() * 2 % 4; i++) // Padding { aVersionStream.writeValue(0); } @@ -273,59 +291,55 @@ void IRMEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) aVersionStream.close(); xVersion->flush(); - xVersion->closeOutput(); // Write 0x6DataSpaces/DataSpaceInfo/[dataspacename] - OUString sStreamName = "\006DataSpaces/DataSpaceInfo/" + sDataSpaceName; - Reference xDataSpaceInfo(rOleStorage.openOutputStream(sStreamName), - UNO_SET_THROW); + Reference xDataSpaceInfo( + mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); BinaryXOutputStream aDataSpaceInfoStream(xDataSpaceInfo, false); - aDataSpaceInfoStream.WriteInt32(8); // Header length + aDataSpaceInfoStream.WriteInt32(0x08); // Header length aDataSpaceInfoStream.WriteInt32(1); // Entries count OUString sTransformName("DRMEncryptedTransform"); aDataSpaceInfoStream.WriteInt32(sTransformName.getLength() * 2); aDataSpaceInfoStream.writeUnicodeArray(sTransformName); - while (aDataSpaceInfoStream.tell() % 4) // Padding + for (int i = 0; i < sTransformName.getLength() * 2 % 4; i++) // Padding { aDataSpaceInfoStream.writeValue(0); } aDataSpaceInfoStream.close(); xDataSpaceInfo->flush(); - xDataSpaceInfo->closeOutput(); // Write 0x6DataSpaces/TransformInfo/[transformname] - sStreamName = "\006DataSpaces/TransformInfo/" + sTransformName + "/\006Primary"; - Reference xTransformInfo(rOleStorage.openOutputStream(sStreamName), - UNO_SET_THROW); + Reference xTransformInfo( + mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); BinaryXOutputStream aTransformInfoStream(xTransformInfo, false); + OUString sTransformId("{C73DFACD-061F-43B0-8B64-0C620D2A8B50}"); // MS-OFFCRYPTO 2.1.8: TransformInfoHeader - aTransformInfoStream.WriteInt32(0); // TransformLength, will be written later + sal_uInt32 nLength + = sTransformId.getLength() * 2 + ((4 - (sTransformId.getLength() & 3)) & 3) + 10; + aTransformInfoStream.WriteInt32(nLength); // TransformLength, will be written later aTransformInfoStream.WriteInt32(1); // TransformType // TransformId - OUString sTransformId("{C73DFACD-061F-43B0-8B64-0C620D2A8B50}"); aTransformInfoStream.WriteInt32(sTransformId.getLength() * 2); aTransformInfoStream.writeUnicodeArray(sTransformId); - while (aTransformInfoStream.tell() % 4) // Padding + for (int i = 0; i < sTransformId.getLength() * 2 % 4; i++) // Padding { aTransformInfoStream.writeValue(0); } - // Calculate length and write it into beginning - nLength = aTransformInfoStream.tell(); - aTransformInfoStream.seek(0); - aTransformInfoStream.WriteInt32(nLength); - aTransformInfoStream.seek(nLength); - // TransformName OUString sTransformInfoName("Microsoft.Metadata.DRMTransform"); aTransformInfoStream.WriteInt32(sTransformInfoName.getLength() * 2); aTransformInfoStream.writeUnicodeArray(sTransformInfoName); - while (aTransformInfoStream.tell() % 4) // Padding + for (int i = 0; i < sTransformInfoName.getLength() * 2 % 4; i++) // Padding { aTransformInfoStream.writeValue(0); } @@ -336,19 +350,36 @@ void IRMEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) aTransformInfoStream.WriteInt32(4); // Extensibility Header - aTransformInfoStream.WriteInt32(mInfo.license.getLength() - 3); // LicenseLength + aTransformInfoStream.WriteInt32(mInfo.license.getLength() - 3); // LicenseLength - BOM aTransformInfoStream.writeArray(mInfo.license.getStr() + 3, mInfo.license.getLength() - 3); aTransformInfoStream.writeValue(0); aTransformInfoStream.close(); xTransformInfo->flush(); - xTransformInfo->closeOutput(); + + // Store all streams into sequence and return back + comphelper::SequenceAsHashMap aStreams; + + Reference xDataSpaceMapSequence(xDataSpaceMap, UNO_QUERY); + aStreams["\006DataSpaces/DataSpaceMap"] <<= xDataSpaceMapSequence->getWrittenBytes(); + + Reference xVersionSequence(xVersion, UNO_QUERY); + aStreams["\006DataSpaces/Version"] <<= xVersionSequence->getWrittenBytes(); + + OUString sStreamName = "\006DataSpaces/DataSpaceInfo/" + sDataSpaceName; + Reference xDataSpaceInfoSequence(xDataSpaceInfo, UNO_QUERY); + aStreams[sStreamName] <<= xDataSpaceInfoSequence->getWrittenBytes(); + + sStreamName = "\006DataSpaces/TransformInfo/" + sTransformName + "/\006Primary"; + Reference xTransformInfoSequence(xTransformInfo, UNO_QUERY); + aStreams[sStreamName] <<= xTransformInfoSequence->getWrittenBytes(); + + return aStreams.getAsConstNamedValueList(); } -void IRMEngine::encrypt(css::uno::Reference& rxInputStream, - css::uno::Reference& rxOutputStream, - sal_uInt32 /*nSize*/) +void IRMEngine::encrypt(const Reference& rxInputStream, + Reference& rxOutputStream) { HRESULT hr = IpcInitialize(); @@ -408,7 +439,7 @@ void IRMEngine::encrypt(css::uno::Reference& rxInputStrea delete[] pDecryptedBuffer; } -bool IRMEngine::generateEncryptionKey(const OUString& /*password*/) { return true; } +sal_Bool IRMEngine::generateEncryptionKey(const OUString& /*password*/) { return true; } } // namespace core } // namespace oox diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx index b48f6e517758..50f23e2cf491 100644 --- a/oox/source/crypto/Standard2007Engine.cxx +++ b/oox/source/crypto/Standard2007Engine.cxx @@ -11,7 +11,9 @@ #include #include +#include #include +#include #include #include #include @@ -27,6 +29,13 @@ 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 const& /*arguments*/) +{ + return cppu::acquire(new Standard2007Engine(pCtx/*, arguments*/)); +} + /* =========================================================================== */ /* Kudos to Caolan McNamara who provided the core decryption implementations. */ /* =========================================================================== */ @@ -129,7 +138,7 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword) return true; } -bool Standard2007Engine::generateEncryptionKey(const OUString& password) +sal_Bool Standard2007Engine::generateEncryptionKey(const OUString& password) { mKey.clear(); /* @@ -171,9 +180,12 @@ bool Standard2007Engine::generateEncryptionKey(const OUString& password) return std::equal(hash.begin(), hash.end(), verifierHash.begin()); } -bool Standard2007Engine::decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) +sal_Bool Standard2007Engine::decrypt(const css::uno::Reference& rxInputStream, + css::uno::Reference& rxOutputStream) { + BinaryXInputStream aInputStream(rxInputStream, true); + BinaryXOutputStream aOutputStream(rxOutputStream, true); + sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes aInputStream.skip(4); // Reserved 4 Bytes @@ -192,20 +204,27 @@ bool Standard2007Engine::decrypt(BinaryXInputStream& aInputStream, aOutputStream.writeMemory(outputBuffer.data(), writeLength); remaining -= outputLength; } + + rxOutputStream->flush(); + return true; } -bool Standard2007Engine::checkDataIntegrity() +sal_Bool Standard2007Engine::checkDataIntegrity() { return true; } -void Standard2007Engine::createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) +css::uno::Sequence Standard2007Engine::createEncryptionData(const OUString& rPassword) { + comphelper::SequenceAsHashMap aEncryptionData; aEncryptionData["OOXPassword"] <<= rPassword; + aEncryptionData["CryptoType"] <<= OUString("Standard2007Engine"); + + return aEncryptionData.getAsConstNamedValueList(); } -bool Standard2007Engine::setupEncryption(css::uno::Sequence& rMediaEncData) +sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence& rMediaEncData) { mInfo.header.flags = msfilter::ENCRYPTINFO_AES | msfilter::ENCRYPTINFO_CRYPTOAPI; mInfo.header.algId = msfilter::ENCRYPT_ALGO_AES128; @@ -238,10 +257,12 @@ bool Standard2007Engine::setupEncryption(css::uno::Sequence Standard2007Engine::writeEncryptionInfo() { - Reference xEncryptionInfo(rOleStorage.openOutputStream("EncryptionInfo"), UNO_SET_THROW); - BinaryXOutputStream rStream(xEncryptionInfo, false); + Reference aEncryptionInfoStream( + mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); + BinaryXOutputStream rStream(aEncryptionInfoStream, false); rStream.WriteUInt32(msfilter::VERSION_INFO_2007_FORMAT); @@ -260,21 +281,27 @@ void Standard2007Engine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) rStream.writeMemory(&mInfo.verifier, sizeof(msfilter::EncryptionVerifierAES)); rStream.close(); - xEncryptionInfo->flush(); - xEncryptionInfo->closeOutput(); + aEncryptionInfoStream->flush(); + + // Store all streams into sequence and return back + comphelper::SequenceAsHashMap aStreams; + + Reference aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); + aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes(); + return aStreams.getAsConstNamedValueList(); } -void Standard2007Engine::encrypt(css::uno::Reference & rxInputStream, - css::uno::Reference & rxOutputStream, - sal_uInt32 nSize) +void Standard2007Engine::encrypt(const css::uno::Reference & rxInputStream, + css::uno::Reference & rxOutputStream) { if (mKey.empty()) return; BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false); BinaryXInputStream aBinaryInputStream(rxInputStream, false); + Reference xSeekable(rxInputStream, UNO_QUERY); - aBinaryOutputStream.WriteUInt32(nSize); // size + aBinaryOutputStream.WriteUInt32(xSeekable->getLength()); // size aBinaryOutputStream.WriteUInt32(0U); // reserved std::vector inputBuffer(1024); @@ -296,7 +323,7 @@ void Standard2007Engine::encrypt(css::uno::Reference & r } } -css::uno::Reference Standard2007Engine::getStream(css::uno::Sequence & rStreams, const OUString sStreamName) +css::uno::Reference Standard2007Engine::getStream(const css::uno::Sequence & rStreams, const OUString sStreamName) { for (const auto & aStream : rStreams) { @@ -311,7 +338,7 @@ css::uno::Reference Standard2007Engine::getStream(css::un return nullptr; } -bool Standard2007Engine::readEncryptionInfo(css::uno::Sequence aStreams) +sal_Bool Standard2007Engine::readEncryptionInfo(const css::uno::Sequence& aStreams) { Reference rxInputStream = getStream(aStreams, "EncryptionInfo"); BinaryXInputStream aBinaryStream(rxInputStream, false); diff --git a/oox/util/oox.component b/oox/util/oox.component index 32a8100b8fb8..0643a417bfa3 100644 --- a/oox/util/oox.component +++ b/oox/util/oox.component @@ -40,4 +40,20 @@ constructor="com_sun_star_comp_oox_ShapeContextHandler_get_implementation"> + + + + + + + + + + + + -- cgit v1.2.3