[Libreoffice-commits] core.git: Branch 'feature/cib_contract3756' - include/oox oox/source

Vasily Melenchuk (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 23 17:51:01 UTC 2019


 include/oox/crypto/AgileEngine.hxx        |    8 +++-
 include/oox/crypto/CryptoEngine.hxx       |    5 --
 include/oox/crypto/DocumentDecryption.hxx |   10 +++--
 include/oox/crypto/DocumentEncryption.hxx |    3 +
 include/oox/crypto/IRMEngine.hxx          |    8 +++-
 include/oox/crypto/Standard2007Engine.hxx |    8 +++-
 oox/source/core/filterdetect.cxx          |    2 -
 oox/source/core/xmlfilterbase.cxx         |    2 -
 oox/source/crypto/AgileEngine.cxx         |   25 ++++++++++--
 oox/source/crypto/DocumentDecryption.cxx  |   59 ++++++++++++++++++++++++++----
 oox/source/crypto/DocumentEncryption.cxx  |   10 +++--
 oox/source/crypto/IRMEngine.cxx           |   30 +++++++++++++--
 oox/source/crypto/Standard2007Engine.cxx  |   26 ++++++++++++-
 13 files changed, 159 insertions(+), 37 deletions(-)

New commits:
commit 0a1f4417c8d10459101cc5f136ebeeaed220e8fb
Author:     Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Mon Sep 23 20:48:41 2019 +0300
Commit:     Vasily Melenchuk <vasily.melenchuk at cib.de>
CommitDate: Mon Sep 23 20:48:41 2019 +0300

    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

diff --git a/include/oox/crypto/AgileEngine.hxx b/include/oox/crypto/AgileEngine.hxx
index 2fed653d924e..60d19fed11db 100644
--- a/include/oox/crypto/AgileEngine.hxx
+++ b/include/oox/crypto/AgileEngine.hxx
@@ -77,8 +77,12 @@ enum class AgileEncryptionPreset
 class OOX_DLLPUBLIC AgileEngine : public CryptoEngine
 {
 private:
+    std::vector<sal_uInt8> mKey;
     AgileEncryptionInfo mInfo;
     AgileEncryptionPreset meEncryptionPreset;
+    css::uno::Reference< css::uno::XComponentContext > mxContext;
+
+    css::uno::Reference<css::io::XInputStream> getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName);
 
     void calculateHashFinal(const OUString& rPassword, std::vector<sal_uInt8>& aHashFinal);
 
@@ -123,12 +127,12 @@ private:
     bool setupEncryptionKey(OUString const & rPassword);
 
 public:
-    AgileEngine();
+    AgileEngine(const css::uno::Reference< css::uno::XComponentContext >& rxContext);
 
     // Decryption
 
     bool generateEncryptionKey(OUString const & rPassword) override;
-    bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
+    bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override;
     bool decrypt(BinaryXInputStream& aInputStream,
                  BinaryXOutputStream& aOutputStream) override;
 
diff --git a/include/oox/crypto/CryptoEngine.hxx b/include/oox/crypto/CryptoEngine.hxx
index 7b97083a1ee4..f985f2d7fb45 100644
--- a/include/oox/crypto/CryptoEngine.hxx
+++ b/include/oox/crypto/CryptoEngine.hxx
@@ -30,9 +30,6 @@ namespace core {
 
 class CryptoEngine
 {
-protected:
-    std::vector<sal_uInt8> mKey;
-
 public:
     CryptoEngine()
     {}
@@ -41,7 +38,7 @@ public:
     {}
 
     // Decryption
-    virtual bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) = 0;
+    virtual bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) = 0;
 
     virtual bool generateEncryptionKey(const OUString& rPassword) = 0;
 
diff --git a/include/oox/crypto/DocumentDecryption.hxx b/include/oox/crypto/DocumentDecryption.hxx
index 791a119b0c6d..248f33f61734 100644
--- a/include/oox/crypto/DocumentDecryption.hxx
+++ b/include/oox/crypto/DocumentDecryption.hxx
@@ -35,14 +35,16 @@ namespace core {
 class OOX_DLLPUBLIC DocumentDecryption
 {
 private:
-    oox::ole::OleStorage&           mrOleStorage;
-    std::unique_ptr<CryptoEngine>   mEngine;
-    OUString                        msEngineName;
+    oox::ole::OleStorage&                      mrOleStorage;
+    css::uno::Sequence<css::beans::NamedValue> maStreamsSequence;
+    std::unique_ptr<CryptoEngine>              mEngine;
+    OUString                                   msEngineName;
+    css::uno::Reference< css::uno::XComponentContext > mxContext;
 
     void readStrongEncryptionInfo();
 
 public:
-    DocumentDecryption(oox::ole::OleStorage& rOleStorage);
+    DocumentDecryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext, oox::ole::OleStorage& rOleStorage);
 
     bool decrypt(const css::uno::Reference< css::io::XStream >& xDocumentStream);
     bool readEncryptionInfo();
diff --git a/include/oox/crypto/DocumentEncryption.hxx b/include/oox/crypto/DocumentEncryption.hxx
index 0d723656a81c..9e9c013456ca 100644
--- a/include/oox/crypto/DocumentEncryption.hxx
+++ b/include/oox/crypto/DocumentEncryption.hxx
@@ -34,9 +34,10 @@ private:
     oox::ole::OleStorage& mrOleStorage;
     std::unique_ptr<CryptoEngine>   mEngine;
     css::uno::Sequence< css::beans::NamedValue >& mMediaEncData;
+    css::uno::Reference< css::uno::XComponentContext > mxContext;
 
 public:
-    DocumentEncryption(
+    DocumentEncryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
         css::uno::Reference< css::io::XStream > const & xDocumentStream,
         oox::ole::OleStorage& rOleStorage,
         css::uno::Sequence< css::beans::NamedValue >& rMediaEncData);
diff --git a/include/oox/crypto/IRMEngine.hxx b/include/oox/crypto/IRMEngine.hxx
index bd2cc44b0a69..9bf610904a9d 100644
--- a/include/oox/crypto/IRMEngine.hxx
+++ b/include/oox/crypto/IRMEngine.hxx
@@ -36,11 +36,15 @@ struct OOX_DLLPUBLIC IRMEncryptionInfo
 class OOX_DLLPUBLIC IRMEngine : public CryptoEngine
 {
     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);
 
 public:
-    IRMEngine();
+    IRMEngine(const css::uno::Reference<css::uno::XComponentContext>& rxContext);
 
-    bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
+    bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override;
 
     virtual bool generateEncryptionKey(OUString const& rPassword) override;
 
diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx
index 580fe88295f5..e0ed99b79e33 100644
--- a/include/oox/crypto/Standard2007Engine.hxx
+++ b/include/oox/crypto/Standard2007Engine.hxx
@@ -28,14 +28,18 @@ namespace core {
 class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine
 {
     msfilter::StandardEncryptionInfo mInfo;
+    std::vector<sal_uInt8> mKey;
+    css::uno::Reference< css::uno::XComponentContext > mxContext;
 
     bool generateVerifier();
     bool calculateEncryptionKey(const OUString& rPassword);
 
+    css::uno::Reference<css::io::XInputStream> getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName);
+
 public:
-    Standard2007Engine() = default;
+    Standard2007Engine(const css::uno::Reference<css::uno::XComponentContext>& rxContext);
 
-    bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
+    bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override;
 
     virtual bool generateEncryptionKey(OUString const & rPassword) override;
 
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index a12e21d1503a..10f661a1d0ba 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 624048a4839a..c3bd6e16378d 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>
@@ -220,8 +221,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)
@@ -485,9 +487,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 800cc5436a13..7d9427a5bb41 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
 


More information about the Libreoffice-commits mailing list