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 offapi/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(-)
New commits: commit 4d0e087cb05e145146b73f6691caa4c8e4c8bb7b Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Sep 27 11:56:00 2019 +0300 Commit: Vasily Melenchuk <vasily.melenc...@cib.de> CommitDate: Tue Oct 1 10:56:14 2019 +0300 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 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 <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; @@ -74,7 +74,7 @@ enum class AgileEncryptionPreset AES_256_SHA512, }; -class OOX_DLLPUBLIC AgileEngine : public CryptoEngine +class OOX_DLLPUBLIC AgileEngine : public cppu::WeakImplHelper<css::packages::XPackageEncryption> { private: std::vector<sal_uInt8> mKey; @@ -82,7 +82,7 @@ private: AgileEncryptionPreset meEncryptionPreset; css::uno::Reference< css::uno::XComponentContext > mxContext; - css::uno::Reference<css::io::XInputStream> getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName); + 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); @@ -131,24 +131,24 @@ public: // Decryption - bool generateEncryptionKey(OUString const & rPassword) override; - bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override; - bool decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) override; + sal_Bool generateEncryptionKey(const OUString & rPassword) override; + sal_Bool readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) override; + sal_Bool decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override; - bool checkDataIntegrity() override; + + sal_Bool checkDataIntegrity() override; // Encryption - void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; + css::uno::Sequence<css::beans::NamedValue> writeEncryptionInfo() override; - void encrypt(css::uno::Reference<css::io::XInputStream>& rxInputStream, - css::uno::Reference<css::io::XOutputStream>& rxOutputStream, - sal_uInt32 nSize) override; + void encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override; - bool setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; + sal_Bool setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; - virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override; + css::uno::Sequence<css::beans::NamedValue> 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 <vector> - -#include <rtl/ustring.hxx> -#include <sal/types.h> - -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/io/XOutputStream.hpp> -#include <com/sun/star/uno/Sequence.hxx> - -namespace oox { - class BinaryXInputStream; - class BinaryXOutputStream; -} - -namespace oox { -namespace core { - -class CryptoEngine -{ -public: - CryptoEngine() - {} - - virtual ~CryptoEngine() - {} - - // Decryption - virtual bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> 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<css::beans::NamedValue>& rMediaEncData) = 0; - - virtual void encrypt(css::uno::Reference<css::io::XInputStream> & rxInputStream, - css::uno::Reference<css::io::XOutputStream> & 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 <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Sequence.hxx> -#include <oox/crypto/CryptoEngine.hxx> #include <rtl/ustring.hxx> 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<css::beans::NamedValue> maStreamsSequence; - std::unique_ptr<CryptoEngine> 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 9e9c013456ca..d33450a3b791 100644 --- a/include/oox/crypto/DocumentEncryption.hxx +++ b/include/oox/crypto/DocumentEncryption.hxx @@ -15,11 +15,11 @@ #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Sequence.hxx> -#include <oox/crypto/CryptoEngine.hxx> #include <rtl/ustring.hxx> namespace com { namespace sun { namespace star { namespace io { class XStream; } + namespace packages { class XPackageEncryption; } } } } namespace oox { namespace ole { class OleStorage; } } @@ -32,7 +32,7 @@ class OOX_DLLPUBLIC DocumentEncryption private: css::uno::Reference< css::io::XStream > mxDocumentStream; oox::ole::OleStorage& mrOleStorage; - std::unique_ptr<CryptoEngine> 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,19 +12,12 @@ #define INCLUDED_OOX_CRYPTO_IRMENGINE_HXX #include <oox/dllapi.h> -#include <oox/crypto/CryptoEngine.hxx> -#include <filter/msfilter/mscodec.hxx> +#include <com/sun/star/packages/XPackageEncryption.hpp> #include <rtl/ustring.hxx> #include <sal/types.h> namespace oox { -class BinaryXInputStream; -class BinaryXOutputStream; -} - -namespace oox -{ namespace core { struct OOX_DLLPUBLIC IRMEncryptionInfo @@ -33,37 +26,40 @@ struct OOX_DLLPUBLIC IRMEncryptionInfo bool bCanRead; }; -class OOX_DLLPUBLIC IRMEngine : public CryptoEngine +class OOX_DLLPUBLIC IRMEngine : public cppu::WeakImplHelper<css::packages::XPackageEncryption> { IRMEncryptionInfo mInfo; css::uno::Reference<css::uno::XComponentContext> mxContext; css::uno::Reference<css::io::XInputStream> - getStream(css::uno::Sequence<css::beans::NamedValue>& rStreams, const OUString sStreamName); + getStream(const css::uno::Sequence<css::beans::NamedValue>& rStreams, + const OUString sStreamName); public: IRMEngine(const css::uno::Reference<css::uno::XComponentContext>& rxContext); - bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override; + // Decryption - virtual bool generateEncryptionKey(OUString const& rPassword) override; + sal_Bool generateEncryptionKey(const OUString& rPassword) override; + sal_Bool + readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) override; + sal_Bool decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override; - virtual bool decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) override; + sal_Bool checkDataIntegrity() override; - bool checkDataIntegrity() override; + // Encryption - void encrypt(css::uno::Reference<css::io::XInputStream>& rxInputStream, - css::uno::Reference<css::io::XOutputStream>& rxOutputStream, - sal_uInt32 nSize) override; + css::uno::Sequence<css::beans::NamedValue> writeEncryptionInfo() override; - virtual void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; + void encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override; - virtual void createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionData, - const OUString rPassword) override; + sal_Bool + setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; - virtual bool - setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; + css::uno::Sequence<css::beans::NamedValue> + createEncryptionData(const OUString& rPassword) override; }; } // namespace core diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx index e0ed99b79e33..d853f4e1a1af 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 <oox/crypto/CryptoEngine.hxx> +#include <com/sun/star/packages/XPackageEncryption.hpp> #include <filter/msfilter/mscodec.hxx> #include <rtl/ustring.hxx> #include <sal/types.h> @@ -25,7 +25,7 @@ namespace oox { namespace oox { namespace core { -class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine +class OOX_DLLPUBLIC Standard2007Engine : public cppu::WeakImplHelper<css::packages::XPackageEncryption> { msfilter::StandardEncryptionInfo mInfo; std::vector<sal_uInt8> mKey; @@ -34,31 +34,31 @@ class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine bool generateVerifier(); bool calculateEncryptionKey(const OUString& rPassword); - css::uno::Reference<css::io::XInputStream> getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName); + css::uno::Reference<css::io::XInputStream> getStream(const css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName); public: Standard2007Engine(const css::uno::Reference<css::uno::XComponentContext>& rxContext); - bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override; + // Decryption - virtual bool generateEncryptionKey(OUString const & rPassword) override; + sal_Bool generateEncryptionKey(const OUString & rPassword) override; + sal_Bool readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) override; + sal_Bool decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override; - virtual bool decrypt( - BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) override; - bool checkDataIntegrity() override; + sal_Bool checkDataIntegrity() override; - void encrypt(css::uno::Reference<css::io::XInputStream>& rxInputStream, - css::uno::Reference<css::io::XOutputStream>& rxOutputStream, - sal_uInt32 nSize) override; + // Encryption - virtual void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; + css::uno::Sequence<css::beans::NamedValue> writeEncryptionInfo() override; - virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override; + void encrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& rxOutputStream) override; - virtual bool setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; + sal_Bool setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; + css::uno::Sequence<css::beans::NamedValue> createEncryptionData(const OUString& rPassword) override; }; } // namespace core diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 59d7e16772c8..be0d7791d777 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 <com/sun/star/uno/XInterface.idl> + +#include <com/sun/star/io/XInputStream.idl> +#include <com/sun/star/io/XOutputStream.idl> + + +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<com::sun::star::beans::NamedValue> writeEncryptionInfo(); + + /** + TODO + */ + sequence<com::sun::star::beans::NamedValue> createEncryptionData([in] string rPassword); + + /** + TODO + */ + boolean setupEncryption([in] sequence<com::sun::star::beans::NamedValue> 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 c3bd6e16378d..35104903d918 100644 --- a/oox/source/crypto/AgileEngine.cxx +++ b/oox/source/crypto/AgileEngine.cxx @@ -30,6 +30,7 @@ #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> @@ -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<Any> const& /*arguments*/) +{ + return cppu::acquire(new AgileEngine(pCtx/*, arguments*/)); +} + + namespace { OUString stripNamespacePrefix(OUString const & rsInputName) @@ -350,7 +359,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); @@ -414,7 +423,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())); @@ -422,11 +431,14 @@ bool AgileEngine::checkDataIntegrity() return bResult; } -bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, - BinaryXOutputStream& aOutputStream) +sal_Bool AgileEngine::decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& 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<sal_uInt8> aSizeBytes(sizeof(sal_uInt32)); @@ -484,10 +496,12 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, mInfo.hmacCalculatedHash = aCryptoHash.finalize(); + rxOutputStream->flush(); + return true; } -uno::Reference<io::XInputStream> AgileEngine::getStream(Sequence<NamedValue> & rStreams, const OUString sStreamName) +uno::Reference<io::XInputStream> AgileEngine::getStream(const Sequence<NamedValue> & rStreams, const OUString sStreamName) { for (const auto & aStream : rStreams) { @@ -502,7 +516,7 @@ uno::Reference<io::XInputStream> AgileEngine::getStream(Sequence<NamedValue> & r return nullptr; } -bool AgileEngine::readEncryptionInfo(Sequence<NamedValue> aStreams) +sal_Bool AgileEngine::readEncryptionInfo(const Sequence<NamedValue>& aStreams) { uno::Reference<io::XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo"); @@ -682,7 +696,7 @@ bool AgileEngine::encryptEncryptionKey(OUString const & rPassword) return true; } -bool AgileEngine::setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) +sal_Bool AgileEngine::setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) { if (meEncryptionPreset == AgileEncryptionPreset::AES_128_SHA1) setupEncryptionParameters({ 100000, 16, 128, 20, 16, OUString("AES"), OUString("ChainingModeCBC"), OUString("SHA1") }); @@ -692,7 +706,7 @@ bool AgileEngine::setupEncryption(css::uno::Sequence<css::beans::NamedValue>& 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; @@ -702,9 +716,13 @@ bool AgileEngine::setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rM return setupEncryptionKey(sPassword); } -void AgileEngine::createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) +uno::Sequence<beans::NamedValue> AgileEngine::createEncryptionData(const OUString & rPassword) { + comphelper::SequenceAsHashMap aEncryptionData; aEncryptionData["OOXPassword"] <<= rPassword; + aEncryptionData["CryptoType"] <<= OUString("AgileEngine"); + + return aEncryptionData.getAsConstNamedValueList(); } void AgileEngine::setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters) @@ -738,10 +756,12 @@ bool AgileEngine::setupEncryptionKey(OUString const & rPassword) return true; } -void AgileEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) +css::uno::Sequence<css::beans::NamedValue> AgileEngine::writeEncryptionInfo() { - Reference<XOutputStream> xEncryptionInfo(rOleStorage.openOutputStream("EncryptionInfo"), UNO_SET_THROW); - BinaryXOutputStream rStream(xEncryptionInfo, false); + 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); @@ -798,21 +818,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<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); + aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes(); + return aStreams.getAsConstNamedValueList(); } -void AgileEngine::encrypt(css::uno::Reference<css::io::XInputStream> & rxInputStream, - css::uno::Reference<css::io::XOutputStream> & rxOutputStream, - sal_uInt32 nSize) +void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream, + css::uno::Reference<css::io::XOutputStream> & rxOutputStream) { CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm)); 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(), 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 7d9427a5bb41..ea3ed1123532 100644 --- a/oox/source/crypto/DocumentDecryption.cxx +++ b/oox/source/crypto/DocumentDecryption.cxx @@ -14,14 +14,12 @@ #include <cppuhelper/implbase.hxx> #include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/io/XSeekable.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/uno/XComponentContext.hpp> -#include <oox/crypto/AgileEngine.hxx> -#include <oox/crypto/Standard2007Engine.hxx> -#include <oox/crypto/IRMEngine.hxx> -#include <oox/helper/binaryinputstream.hxx> -#include <oox/helper/binaryoutputstream.hxx> +#include <com/sun/star/packages/XPackageEncryption.hpp> #include <oox/ole/olestorage.hxx> +#include <filter/msfilter/mscodec.hxx> 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<beans::NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword) { - comphelper::SequenceAsHashMap aEncryptionData; + if (!mxPackageEncryption.is()) + return uno::Sequence<beans::NamedValue>(); - aEncryptionData["CryptoType"] <<= msEngineName; - mEngine->createEncryptionData(aEncryptionData, rPassword); - - return aEncryptionData.getAsConstNamedValueList(); + return mxPackageEncryption->createEncryptionData(rPassword); } bool DocumentDecryption::decrypt(const uno::Reference<io::XStream>& xDocumentStream) @@ -195,21 +190,22 @@ bool DocumentDecryption::decrypt(const uno::Reference<io::XStream>& xDocumentStr if (!mrOleStorage.isStorage()) return false; + if (!mxPackageEncryption.is()) + return false; + // open the required input streams in the encrypted package uno::Reference<io::XInputStream> xEncryptedPackage = mrOleStorage.openInputStream("EncryptedPackage"); // create temporary file for unencrypted package uno::Reference<io::XOutputStream> xDecryptedPackage = xDocumentStream->getOutputStream(); - 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<io::XSeekable> 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 <oox/crypto/DocumentEncryption.hxx> -#include <oox/crypto/Standard2007Engine.hxx> -#include <oox/crypto/IRMEngine.hxx> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/packages/XPackageEncryption.hpp> -#include <oox/helper/binaryinputstream.hxx> -#include <oox/helper/binaryoutputstream.hxx> #include <oox/ole/olestorage.hxx> 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<XStream> const & xDocumentStream, oox::ole::OleStorage& rOleStorage, - Sequence<css::beans::NamedValue>& rMediaEncData) + Sequence<NamedValue>& 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<Any> 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> 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> xOutputStream(mrOleStorage.openOutputStream("EncryptedPackage"), UNO_SET_THROW); - mEngine->encrypt(xInputStream, xOutputStream, aLength); + mxPackageEncryption->encrypt(xInputStream, xOutputStream); xOutputStream->flush(); xOutputStream->closeOutput(); - mEngine->writeEncryptionInfo(mrOleStorage); + Sequence<NamedValue> aStreams = mxPackageEncryption->writeEncryptionInfo(); + + for (const NamedValue & aStream : aStreams) + { + Reference<XOutputStream> xOutputStream(mrOleStorage.openOutputStream(aStream.Name), UNO_SET_THROW); + BinaryXOutputStream aBinaryOutputStream(xOutputStream, true); + + css::uno::Sequence<sal_Int8> 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 <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> @@ -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<Any> const& /*arguments*/) +{ + return cppu::acquire(new IRMEngine(pCtx /*, arguments*/)); +} + IRMEngine::IRMEngine(const Reference<XComponentContext>& 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<XInputStream>& rxInputStream, + Reference<XOutputStream>& 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<beans::NamedValue> IRMEngine::createEncryptionData(const OUString& /*rPassword*/) { - aEncryptionData["OOXPassword"] <<= rPassword; - css::uno::Sequence<sal_uInt8> 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<io::XInputStream> IRMEngine::getStream(Sequence<NamedValue>& rStreams, +uno::Reference<io::XInputStream> IRMEngine::getStream(const Sequence<NamedValue>& rStreams, const OUString sStreamName) { for (const auto& aStream : rStreams) @@ -155,7 +176,7 @@ uno::Reference<io::XInputStream> IRMEngine::getStream(Sequence<NamedValue>& rStr return nullptr; } -bool IRMEngine::readEncryptionInfo(uno::Sequence<beans::NamedValue> aStreams) +sal_Bool IRMEngine::readEncryptionInfo(const uno::Sequence<beans::NamedValue>& aStreams) { // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4) uno::Reference<io::XInputStream> xTransformInfoStream @@ -198,11 +219,11 @@ bool IRMEngine::readEncryptionInfo(uno::Sequence<beans::NamedValue> aStreams) return true; } -bool IRMEngine::setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) +sal_Bool IRMEngine::setupEncryption(const Sequence<NamedValue>& rMediaEncData) { for (int i = 0; i < rMediaEncData.getLength(); i++) { - if (rMediaEncData[i].Name == "license") + if (rMediaEncData[i].Name == "LicenseKey") { css::uno::Sequence<sal_uInt8> seq; rMediaEncData[i].Value >>= seq; @@ -213,11 +234,13 @@ bool IRMEngine::setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMed return true; } -void IRMEngine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) +Sequence<NamedValue> IRMEngine::writeEncryptionInfo() { // Write 0x6DataSpaces/DataSpaceMap Reference<XOutputStream> 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<sal_Char>(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<sal_Char>(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<XOutputStream> xVersion(rOleStorage.openOutputStream("\006DataSpaces/Version"), - UNO_SET_THROW); + Reference<XOutputStream> 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<sal_Char>(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<XOutputStream> xDataSpaceInfo(rOleStorage.openOutputStream(sStreamName), - UNO_SET_THROW); + Reference<XOutputStream> 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<sal_Char>(0); } aDataSpaceInfoStream.close(); xDataSpaceInfo->flush(); - xDataSpaceInfo->closeOutput(); // Write 0x6DataSpaces/TransformInfo/[transformname] - sStreamName = "\006DataSpaces/TransformInfo/" + sTransformName + "/\006Primary"; - Reference<XOutputStream> xTransformInfo(rOleStorage.openOutputStream(sStreamName), - UNO_SET_THROW); + Reference<XOutputStream> 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<sal_Char>(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<sal_Char>(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<sal_Char>(mInfo.license.getStr() + 3, mInfo.license.getLength() - 3); aTransformInfoStream.writeValue<sal_Char>(0); aTransformInfoStream.close(); xTransformInfo->flush(); - xTransformInfo->closeOutput(); + + // Store all streams into sequence and return back + comphelper::SequenceAsHashMap aStreams; + + Reference<XSequenceOutputStream> xDataSpaceMapSequence(xDataSpaceMap, UNO_QUERY); + aStreams["\006DataSpaces/DataSpaceMap"] <<= xDataSpaceMapSequence->getWrittenBytes(); + + Reference<XSequenceOutputStream> xVersionSequence(xVersion, UNO_QUERY); + aStreams["\006DataSpaces/Version"] <<= xVersionSequence->getWrittenBytes(); + + OUString sStreamName = "\006DataSpaces/DataSpaceInfo/" + sDataSpaceName; + Reference<XSequenceOutputStream> xDataSpaceInfoSequence(xDataSpaceInfo, UNO_QUERY); + aStreams[sStreamName] <<= xDataSpaceInfoSequence->getWrittenBytes(); + + sStreamName = "\006DataSpaces/TransformInfo/" + sTransformName + "/\006Primary"; + Reference<XSequenceOutputStream> xTransformInfoSequence(xTransformInfo, UNO_QUERY); + aStreams[sStreamName] <<= xTransformInfoSequence->getWrittenBytes(); + + return aStreams.getAsConstNamedValueList(); } -void IRMEngine::encrypt(css::uno::Reference<css::io::XInputStream>& rxInputStream, - css::uno::Reference<css::io::XOutputStream>& rxOutputStream, - sal_uInt32 /*nSize*/) +void IRMEngine::encrypt(const Reference<XInputStream>& rxInputStream, + Reference<XOutputStream>& rxOutputStream) { HRESULT hr = IpcInitialize(); @@ -408,7 +439,7 @@ void IRMEngine::encrypt(css::uno::Reference<css::io::XInputStream>& 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 <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> @@ -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<Any> 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<css::io::XInputStream>& rxInputStream, + css::uno::Reference<css::io::XOutputStream>& 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<css::beans::NamedValue> Standard2007Engine::createEncryptionData(const OUString& rPassword) { + comphelper::SequenceAsHashMap aEncryptionData; aEncryptionData["OOXPassword"] <<= rPassword; + aEncryptionData["CryptoType"] <<= OUString("Standard2007Engine"); + + return aEncryptionData.getAsConstNamedValueList(); } -bool Standard2007Engine::setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) +sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& 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<css::beans::NamedVal return true; } -void Standard2007Engine::writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) +css::uno::Sequence<css::beans::NamedValue> Standard2007Engine::writeEncryptionInfo() { - Reference<XOutputStream> xEncryptionInfo(rOleStorage.openOutputStream("EncryptionInfo"), UNO_SET_THROW); - BinaryXOutputStream rStream(xEncryptionInfo, false); + 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); @@ -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<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); + aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes(); + return aStreams.getAsConstNamedValueList(); } -void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> & rxInputStream, - css::uno::Reference<css::io::XOutputStream> & rxOutputStream, - sal_uInt32 nSize) +void Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream, + css::uno::Reference<css::io::XOutputStream> & rxOutputStream) { if (mKey.empty()) return; BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false); BinaryXInputStream aBinaryInputStream(rxInputStream, false); + Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY); - aBinaryOutputStream.WriteUInt32(nSize); // size + aBinaryOutputStream.WriteUInt32(xSeekable->getLength()); // size aBinaryOutputStream.WriteUInt32(0U); // reserved std::vector<sal_uInt8> inputBuffer(1024); @@ -296,7 +323,7 @@ void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> & r } } -css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName) +css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(const css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName) { for (const auto & aStream : rStreams) { @@ -311,7 +338,7 @@ css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(css::un return nullptr; } -bool Standard2007Engine::readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) +sal_Bool Standard2007Engine::readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) { Reference<css::io::XInputStream> 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"> <service name="com.sun.star.xml.sax.FastShapeContextHandler"/> </implementation> + <implementation name="com.sun.star.comp.oox.crypto.DRMEncryptedDataSpace" + constructor="com_sun_star_comp_oox_crypto_DRMEncryptedDataSpace_get_implementation"> + <service name="com.sun.star.packages.XPackageEncryption"/> + </implementation> + <implementation name="com.sun.star.comp.oox.crypto.DRMDataSpace" + constructor="com_sun_star_comp_oox_crypto_DRMDataSpace_get_implementation"> + <service name="com.sun.star.packages.XPackageEncryption"/> + </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"> + <service name="com.sun.star.packages.XPackageEncryption"/> + </implementation> </component> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits