diff options
author | Vasily Melenchuk <vasily.melenchuk@cib.de> | 2019-09-23 20:48:41 +0300 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2019-12-04 13:43:21 +0100 |
commit | 78149c3847533639542ea55d97c168e0fbcd9822 (patch) | |
tree | dda90afb80aea5731329df9d764ec7b169b23eb3 /oox | |
parent | 74b6308b8e86da2bd36d241424ff03cae8a52dd2 (diff) |
irm: refactoring of decrypt methods
to allow usage of decryt methods outside of LO we should avoid
direct usage of OleStorage in CryptoEngine: it is not accessible
outside of core.
Change-Id: Id60b338445a5950aa40b84d788c94b8fa025e717
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/core/filterdetect.cxx | 2 | ||||
-rw-r--r-- | oox/source/core/xmlfilterbase.cxx | 2 | ||||
-rw-r--r-- | oox/source/crypto/AgileEngine.cxx | 25 | ||||
-rw-r--r-- | oox/source/crypto/DocumentDecryption.cxx | 59 | ||||
-rw-r--r-- | oox/source/crypto/DocumentEncryption.cxx | 10 | ||||
-rw-r--r-- | oox/source/crypto/IRMEngine.cxx | 30 | ||||
-rw-r--r-- | oox/source/crypto/Standard2007Engine.cxx | 26 |
7 files changed, 132 insertions, 22 deletions
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index 4537e61a93c8..7e72d28482df 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -300,7 +300,7 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript { try { - DocumentDecryption aDecryptor(aOleStorage); + DocumentDecryption aDecryptor(mxContext, aOleStorage); if( aDecryptor.readEncryptionInfo() ) { diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index c404e3bec6bf..c1c2972f4e9c 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -918,7 +918,7 @@ bool XmlFilterBase::implFinalizeExport( MediaDescriptor& rMediaDescriptor ) Reference< XStream> xDocumentStream (FilterBase::implGetOutputStream(rMediaDescriptor)); oox::ole::OleStorage aOleStorage( getComponentContext(), xDocumentStream, true ); - DocumentEncryption encryptor(getMainDocumentStream(), aOleStorage, aMediaEncData); + DocumentEncryption encryptor( getComponentContext(), getMainDocumentStream(), aOleStorage, aMediaEncData ); bRet = encryptor.encrypt(); if (bRet) aOleStorage.commit(); diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx index da454fbe1abe..f1f2b2eb488a 100644 --- a/oox/source/crypto/AgileEngine.cxx +++ b/oox/source/crypto/AgileEngine.cxx @@ -29,6 +29,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/uno/XComponentContext.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> @@ -219,8 +220,9 @@ CryptoHashType cryptoHashTypeFromString(OUString const & sAlgorithm) } // namespace -AgileEngine::AgileEngine() - : meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512) +AgileEngine::AgileEngine(const Reference< XComponentContext >& rxContext) : + meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512), + mxContext(rxContext) {} Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo) @@ -484,9 +486,24 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, return true; } -bool AgileEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage) +uno::Reference<io::XInputStream> AgileEngine::getStream(Sequence<NamedValue> & rStreams, const OUString sStreamName) { - uno::Reference<io::XInputStream> xEncryptionInfo = rOleStorage.openInputStream("EncryptionInfo"); + for (const auto & aStream : rStreams) + { + if (aStream.Name == sStreamName) + { + css::uno::Sequence<sal_Int8> aSeq; + aStream.Value >>= aSeq; + Reference<XInputStream> aStream(io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW); + return aStream; + } + } + return nullptr; +} + +bool AgileEngine::readEncryptionInfo(Sequence<NamedValue> aStreams) +{ + uno::Reference<io::XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo"); BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true); aBinaryInputStream.readuInt32(); // Version diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx index 5139a5380b0f..9a485688b487 100644 --- a/oox/source/crypto/DocumentDecryption.cxx +++ b/oox/source/crypto/DocumentDecryption.cxx @@ -23,14 +23,61 @@ #include <oox/helper/binaryoutputstream.hxx> #include <oox/ole/olestorage.hxx> +namespace { + +void lcl_getListOfStreams(oox::StorageBase* pStorage, std::vector<OUString>& rElementNames) +{ + std::vector< OUString > oElementNames; + pStorage->getElementNames(oElementNames); + for (const auto & sName : oElementNames) + { + oox::StorageRef rSubStorage = pStorage->openSubStorage(sName, false); + if (rSubStorage && rSubStorage->isStorage()) + { + lcl_getListOfStreams(rSubStorage.get(), rElementNames); + } + else + { + if (pStorage->isRootStorage()) + rElementNames.push_back(sName); + else + rElementNames.push_back(pStorage->getPath() + "/" + sName); + } + } +} + +} + namespace oox { namespace core { using namespace css; -DocumentDecryption::DocumentDecryption(oox::ole::OleStorage& rOleStorage) : +DocumentDecryption::DocumentDecryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext, + oox::ole::OleStorage& rOleStorage) : + mxContext(rxContext), mrOleStorage(rOleStorage) -{} +{ + // Get OLE streams into sequences for later use in CryptoEngine + std::vector< OUString > aStreamNames; + lcl_getListOfStreams(&mrOleStorage, aStreamNames); + + comphelper::SequenceAsHashMap aStreamsData; + for (const auto & sStreamName : aStreamNames) + { + uno::Reference<io::XInputStream> xStream = mrOleStorage.openInputStream(sStreamName); + assert(xStream.is()); + BinaryXInputStream aBinaryInputStream(xStream, true); + + css::uno::Sequence< sal_Int8 > oData; + sal_Int32 nStreamSize = aBinaryInputStream.size(); + sal_Int32 nReadBytes = aBinaryInputStream.readData(oData, nStreamSize); + + assert(nStreamSize == nReadBytes); + aStreamsData[sStreamName] <<= oData; + } + maStreamsSequence = aStreamsData.getAsConstNamedValueList(); +} bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword) { @@ -51,11 +98,11 @@ void DocumentDecryption::readStrongEncryptionInfo() case msfilter::VERSION_INFO_2007_FORMAT: case msfilter::VERSION_INFO_2007_FORMAT_SP2: msEngineName = "Standard"; // Set encryption info format - mEngine.reset(new Standard2007Engine); + mEngine.reset(new Standard2007Engine(mxContext)); break; case msfilter::VERSION_INFO_AGILE: msEngineName = "Agile"; // Set encryption info format - mEngine.reset(new AgileEngine); + mEngine.reset(new AgileEngine(mxContext)); break; default: break; @@ -102,7 +149,7 @@ bool DocumentDecryption::readEncryptionInfo() if (sDataSpaceName == "DRMEncryptedDataSpace") { msEngineName = "IRM"; // Set encryption info format - mEngine.reset(new IRMEngine); + mEngine.reset(new IRMEngine(mxContext)); } else if (sDataSpaceName == "\011DRMDataSpace") // 0x09DRMDataSpace { @@ -128,7 +175,7 @@ bool DocumentDecryption::readEncryptionInfo() if (!mEngine) return false; - return mEngine->readEncryptionInfo(mrOleStorage); + return mEngine->readEncryptionInfo(maStreamsSequence); } uno::Sequence<beans::NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword) diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx index 6975572193d5..8aac457c67d2 100644 --- a/oox/source/crypto/DocumentEncryption.cxx +++ b/oox/source/crypto/DocumentEncryption.cxx @@ -27,10 +27,12 @@ namespace core { using namespace css::io; using namespace css::uno; -DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStream, +DocumentEncryption::DocumentEncryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext, + Reference<XStream> const & xDocumentStream, oox::ole::OleStorage& rOleStorage, Sequence<css::beans::NamedValue>& rMediaEncData) - : mxDocumentStream(xDocumentStream) + : mxContext(rxContext) + , mxDocumentStream(xDocumentStream) , mrOleStorage(rOleStorage) , mMediaEncData(rMediaEncData) { @@ -43,11 +45,11 @@ DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStrea rMediaEncData[i].Value >>= sCryptoType; if (sCryptoType == "IRM") { - mEngine.reset(new IRMEngine); + mEngine.reset(new IRMEngine(mxContext)); } else if (sCryptoType == "Standard" || sCryptoType == "Agile") { - mEngine.reset(new Standard2007Engine); + mEngine.reset(new Standard2007Engine(mxContext)); } else { diff --git a/oox/source/crypto/IRMEngine.cxx b/oox/source/crypto/IRMEngine.cxx index 6f531b2a1c14..1301a3b51279 100644 --- a/oox/source/crypto/IRMEngine.cxx +++ b/oox/source/crypto/IRMEngine.cxx @@ -29,6 +29,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/uno/XComponentContext.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> @@ -49,7 +50,10 @@ namespace oox { namespace core { -IRMEngine::IRMEngine() {} +IRMEngine::IRMEngine(const Reference<XComponentContext>& rxContext) + : mxContext(rxContext) +{ +} bool IRMEngine::checkDataIntegrity() { return true; } @@ -133,11 +137,29 @@ void IRMEngine::createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionD aEncryptionData["license"] <<= seq; } -bool IRMEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage) +uno::Reference<io::XInputStream> IRMEngine::getStream(Sequence<NamedValue>& rStreams, + const OUString sStreamName) +{ + for (const auto& aStream : rStreams) + { + if (aStream.Name == sStreamName) + { + css::uno::Sequence<sal_Int8> aSeq; + aStream.Value >>= aSeq; + Reference<XInputStream> aStream( + io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), + UNO_QUERY_THROW); + return aStream; + } + } + return nullptr; +} + +bool IRMEngine::readEncryptionInfo(uno::Sequence<beans::NamedValue> aStreams) { // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4) - uno::Reference<io::XInputStream> xTransformInfoStream = rOleStorage.openInputStream( - "\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary"); + uno::Reference<io::XInputStream> xTransformInfoStream + = getStream(aStreams, "\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary"); SAL_WARN_IF(!xTransformInfoStream.is(), "oox", "TransormInfo stream is missing!"); BinaryXInputStream aBinaryStream(xTransformInfoStream, true); diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx index 86d9092be574..b48f6e517758 100644 --- a/oox/source/crypto/Standard2007Engine.cxx +++ b/oox/source/crypto/Standard2007Engine.cxx @@ -11,6 +11,7 @@ #include <oox/crypto/Standard2007Engine.hxx> #include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/SequenceInputStream.hpp> #include <oox/crypto/CryptTools.hxx> #include <oox/helper/binaryinputstream.hxx> #include <oox/helper/binaryoutputstream.hxx> @@ -44,6 +45,12 @@ constexpr const sal_uInt32 AES128Size = 16; } // end anonymous namespace +Standard2007Engine::Standard2007Engine(const css::uno::Reference<css::uno::XComponentContext>& rxContext) + : mxContext(rxContext) +{ + +} + bool Standard2007Engine::generateVerifier() { // only support key of size 128 bit (16 byte) @@ -289,9 +296,24 @@ void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> & r } } -bool Standard2007Engine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage) +css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName) +{ + for (const auto & aStream : rStreams) + { + if (aStream.Name == sStreamName) + { + css::uno::Sequence<sal_Int8> aSeq; + aStream.Value >>= aSeq; + Reference<XInputStream> aStream(css::io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW); + return aStream; + } + } + return nullptr; +} + +bool Standard2007Engine::readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) { - Reference<css::io::XInputStream> rxInputStream = rOleStorage.openInputStream("EncryptionInfo"); + Reference<css::io::XInputStream> rxInputStream = getStream(aStreams, "EncryptionInfo"); BinaryXInputStream aBinaryStream(rxInputStream, false); aBinaryStream.readuInt32(); // Version |