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

Vasily Melenchuk (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 23 08:22:04 UTC 2019


 include/oox/crypto/AgileEngine.hxx        |   40 +++++++++++++-----------
 include/oox/crypto/CryptoEngine.hxx       |    2 -
 include/oox/crypto/DocumentDecryption.hxx |    3 -
 include/oox/crypto/IRMEngine.hxx          |    3 +
 include/oox/crypto/Standard2007Engine.hxx |    2 -
 oox/source/crypto/AgileEngine.cxx         |   11 ++++--
 oox/source/crypto/DocumentDecryption.cxx  |   50 ++++++------------------------
 oox/source/crypto/DocumentEncryption.cxx  |    9 ++++-
 oox/source/crypto/IRMEngine.cxx           |   40 ++++++++++++++++++++++--
 oox/source/crypto/Standard2007Engine.cxx  |    6 ++-
 sfx2/source/dialog/filedlghelper.cxx      |    3 +
 sw/qa/extras/inc/swmodeltestbase.hxx      |    1 
 12 files changed, 97 insertions(+), 73 deletions(-)

New commits:
commit 5a5a6d973c9bbd88d1bd6efdeefdc6bbf3043cc8
Author:     Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Mon Sep 23 10:32:18 2019 +0300
Commit:     Vasily Melenchuk <vasily.melenchuk at cib.de>
CommitDate: Mon Sep 23 10:21:25 2019 +0200

    irm: encryption/decrypttion methods organization
    
    fixing encryption problems introduced in previous commit
    
    Change-Id: Ie03360f51b76db3fc9a4f7d343d622c6dc9fcee6
    Reviewed-on: https://gerrit.libreoffice.org/79376
    Reviewed-by: Vasily Melenchuk <vasily.melenchuk at cib.de>
    Tested-by: Vasily Melenchuk <vasily.melenchuk at cib.de>

diff --git a/include/oox/crypto/AgileEngine.hxx b/include/oox/crypto/AgileEngine.hxx
index 7a3f4788d1af..2fed653d924e 100644
--- a/include/oox/crypto/AgileEngine.hxx
+++ b/include/oox/crypto/AgileEngine.hxx
@@ -96,31 +96,44 @@ private:
 
     static Crypto::CryptoType cryptoType(const AgileEncryptionInfo& rInfo);
 
-public:
-    AgileEngine();
+    // Decryption
 
-    AgileEncryptionInfo& getInfo() { return mInfo;}
+    bool decryptHmacKey();
+    bool decryptHmacValue();
+
+    AgileEncryptionInfo& getInfo() { return mInfo; }
 
     void setPreset(AgileEncryptionPreset ePreset)
     {
         meEncryptionPreset = ePreset;
     }
 
-    // Decryption
-
     void decryptEncryptionKey(OUString const & rPassword);
     bool decryptAndCheckVerifierHash(OUString const & rPassword);
 
+    // Encryption
+
+    bool encryptHmacKey();
+    bool encryptHmacValue();
+
+    bool generateAndEncryptVerifierHash(OUString const & rPassword);
+
+    bool encryptEncryptionKey(OUString const & rPassword);
+    void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters);
+    bool setupEncryptionKey(OUString const & rPassword);
+
+public:
+    AgileEngine();
+
+    // Decryption
+
     bool generateEncryptionKey(OUString const & rPassword) override;
-    bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override;
+    bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
     bool decrypt(BinaryXInputStream& aInputStream,
                  BinaryXOutputStream& aOutputStream) override;
 
     bool checkDataIntegrity() override;
 
-    bool decryptHmacKey();
-    bool decryptHmacValue();
-
     // Encryption
 
     void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
@@ -132,15 +145,6 @@ public:
     bool setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override;
 
     virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override;
-
-    bool generateAndEncryptVerifierHash(OUString const & rPassword);
-
-    bool encryptHmacKey();
-    bool encryptHmacValue();
-
-    bool encryptEncryptionKey(OUString const & rPassword);
-    void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters);
-    bool setupEncryptionKey(OUString const & rPassword);
 };
 
 } // namespace core
diff --git a/include/oox/crypto/CryptoEngine.hxx b/include/oox/crypto/CryptoEngine.hxx
index 77cac9af1c3b..7b97083a1ee4 100644
--- a/include/oox/crypto/CryptoEngine.hxx
+++ b/include/oox/crypto/CryptoEngine.hxx
@@ -41,7 +41,7 @@ public:
     {}
 
     // Decryption
-    virtual bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) = 0;
+    virtual bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) = 0;
 
     virtual bool generateEncryptionKey(const OUString& rPassword) = 0;
 
diff --git a/include/oox/crypto/DocumentDecryption.hxx b/include/oox/crypto/DocumentDecryption.hxx
index 42a4c413ff18..791a119b0c6d 100644
--- a/include/oox/crypto/DocumentDecryption.hxx
+++ b/include/oox/crypto/DocumentDecryption.hxx
@@ -39,8 +39,7 @@ private:
     std::unique_ptr<CryptoEngine>   mEngine;
     OUString                        msEngineName;
 
-    bool readStrongEncryptionInfo();
-    bool readIRMEncryptionInfo();
+    void readStrongEncryptionInfo();
 
 public:
     DocumentDecryption(oox::ole::OleStorage& rOleStorage);
diff --git a/include/oox/crypto/IRMEngine.hxx b/include/oox/crypto/IRMEngine.hxx
index 3aadee705c2c..bd2cc44b0a69 100644
--- a/include/oox/crypto/IRMEngine.hxx
+++ b/include/oox/crypto/IRMEngine.hxx
@@ -30,6 +30,7 @@ namespace core
 struct OOX_DLLPUBLIC IRMEncryptionInfo
 {
     OString license;
+    bool bCanRead;
 };
 
 class OOX_DLLPUBLIC IRMEngine : public CryptoEngine
@@ -39,7 +40,7 @@ class OOX_DLLPUBLIC IRMEngine : public CryptoEngine
 public:
     IRMEngine();
 
-    bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream>& rxInputStream) override;
+    bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
 
     virtual bool generateEncryptionKey(OUString const& rPassword) override;
 
diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx
index 7bec4e5f7aee..580fe88295f5 100644
--- a/include/oox/crypto/Standard2007Engine.hxx
+++ b/include/oox/crypto/Standard2007Engine.hxx
@@ -35,7 +35,7 @@ class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine
 public:
     Standard2007Engine() = default;
 
-    bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override;
+    bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;
 
     virtual bool generateEncryptionKey(OUString const & rPassword) override;
 
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
index 5192ae905723..624048a4839a 100644
--- a/oox/source/crypto/AgileEngine.cxx
+++ b/oox/source/crypto/AgileEngine.cxx
@@ -485,14 +485,19 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
     return true;
 }
 
-bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputStream)
+bool AgileEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage)
 {
+    uno::Reference<io::XInputStream> xEncryptionInfo = rOleStorage.openInputStream("EncryptionInfo");
+
+    BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
+    aBinaryInputStream.readuInt32();    // Version
+
     // Check reserved value
     std::vector<sal_uInt8> aExpectedReservedBytes(sizeof(sal_uInt32));
     ByteOrderConverter::writeLittleEndian(aExpectedReservedBytes.data(), msfilter::AGILE_ENCRYPTION_RESERVED);
 
     uno::Sequence<sal_Int8> aReadReservedBytes(sizeof(sal_uInt32));
-    rxInputStream->readBytes(aReadReservedBytes, aReadReservedBytes.getLength());
+    xEncryptionInfo->readBytes(aReadReservedBytes, aReadReservedBytes.getLength());
 
     if (!std::equal(aReadReservedBytes.begin(), aReadReservedBytes.end(), aExpectedReservedBytes.begin()))
         return false;
@@ -512,7 +517,7 @@ bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputS
     xParser->setTokenHandler(xFastTokenHandler);
 
     InputSource aInputSource;
-    aInputSource.aInputStream = rxInputStream;
+    aInputSource.aInputStream = xEncryptionInfo;
     xParser->parseStream(aInputSource);
 
     // CHECK info data
diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx
index 187522ee4a06..800cc5436a13 100644
--- a/oox/source/crypto/DocumentDecryption.cxx
+++ b/oox/source/crypto/DocumentDecryption.cxx
@@ -39,7 +39,7 @@ bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword)
     return false;
 }
 
-bool DocumentDecryption::readStrongEncryptionInfo()
+void DocumentDecryption::readStrongEncryptionInfo()
 {
     uno::Reference<io::XInputStream> xEncryptionInfo = mrOleStorage.openInputStream("EncryptionInfo");
 
@@ -60,41 +60,6 @@ bool DocumentDecryption::readStrongEncryptionInfo()
     default:
         break;
     }
-    if (mEngine)
-        return mEngine->readEncryptionInfo(xEncryptionInfo);
-    return false;
-}
-
-bool DocumentDecryption::readIRMEncryptionInfo()
-{
-    // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4)
-    uno::Reference<io::XInputStream> xTransformInfoStream = mrOleStorage.openInputStream("\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary");
-    SAL_WARN_IF(!xTransformInfoStream.is(), "oox", "TransormInfo stream is missing!");
-    BinaryXInputStream aBinaryStream(xTransformInfoStream, true);
-
-    // MS-OFFCRYPTO 2.1.8: TransformInfoHeader
-    aBinaryStream.readuInt32();  // TransformLength
-    aBinaryStream.readuInt32();  // TransformType
-    // TransformId
-    sal_uInt32 aStringLength = aBinaryStream.readuInt32();
-    OUString sTransformId = aBinaryStream.readUnicodeArray(aStringLength / 2);
-    aBinaryStream.skip((4 - (aStringLength & 3)) & 3);  // Skip padding
-
-    // TransformName
-    aStringLength = aBinaryStream.readuInt32();
-    OUString sTransformName = aBinaryStream.readUnicodeArray(aStringLength / 2);
-    aBinaryStream.skip((4 - (aStringLength & 3)) & 3);  // Skip padding
-
-    aBinaryStream.readuInt32();  // ReaderVersion
-    aBinaryStream.readuInt32();  // UpdaterVersion
-    aBinaryStream.readuInt32();  // WriterVersion
-
-    // MS-OFFCRYPTO 2.2.5: ExtensibilityHeader
-    aBinaryStream.readuInt32();  // ExtensibilityHeader
-
-    msEngineName = "IRM"; // Set encryption info format
-    mEngine.reset(new IRMEngine);
-    return mEngine->readEncryptionInfo(xTransformInfoStream);
 }
 
 bool DocumentDecryption::readEncryptionInfo()
@@ -136,7 +101,8 @@ bool DocumentDecryption::readEncryptionInfo()
 
         if (sDataSpaceName == "DRMEncryptedDataSpace")
         {
-            return readIRMEncryptionInfo();
+            msEngineName = "IRM"; // Set encryption info format
+            mEngine.reset(new IRMEngine);
         }
         else if (sDataSpaceName == "\011DRMDataSpace") // 0x09DRMDataSpace
         {
@@ -144,7 +110,7 @@ bool DocumentDecryption::readEncryptionInfo()
         }
         else if (sDataSpaceName == "StrongEncryptionDataSpace")
         {
-            return readStrongEncryptionInfo();
+            readStrongEncryptionInfo();
         }
         else
         {
@@ -156,9 +122,13 @@ bool DocumentDecryption::readEncryptionInfo()
         // Fallback for documents generated by LO: they sometimes do not have all
         // required by MS-OFFCRYPTO specification streams (0x6DataSpaces/DataSpaceMap and others)
         SAL_WARN("oox", "Encrypted package does not contain DataSpaceMap");
-        return readStrongEncryptionInfo();
+        readStrongEncryptionInfo();
     }
-    return false;
+
+    if (!mEngine)
+        return false;
+
+    return mEngine->readEncryptionInfo(mrOleStorage);
 }
 
 uno::Sequence<beans::NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword)
diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx
index 5fab856c0c18..6975572193d5 100644
--- a/oox/source/crypto/DocumentEncryption.cxx
+++ b/oox/source/crypto/DocumentEncryption.cxx
@@ -45,16 +45,23 @@ DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStrea
             {
                 mEngine.reset(new IRMEngine);
             }
-            else
+            else if (sCryptoType == "Standard" || sCryptoType == "Agile")
             {
                 mEngine.reset(new Standard2007Engine);
             }
+            else
+            {
+                SAL_WARN("oox", "Requested encryption method \"" << sCryptoType << "\" is not supported");
+            }
         }
     }
 }
 
 bool DocumentEncryption::encrypt()
 {
+    if (!mEngine)
+        return false;
+
     Reference<XInputStream> xInputStream (mxDocumentStream->getInputStream(), UNO_SET_THROW);
     Reference<XSeekable> xSeekable(xInputStream, UNO_QUERY);
 
diff --git a/oox/source/crypto/IRMEngine.cxx b/oox/source/crypto/IRMEngine.cxx
index 94bcc773333e..6f531b2a1c14 100644
--- a/oox/source/crypto/IRMEngine.cxx
+++ b/oox/source/crypto/IRMEngine.cxx
@@ -75,6 +75,15 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a
         // TODO: some reaction?
     }
 
+    // Read rights
+    BOOL value;
+    hr = IpcAccessCheck(key, IPC_GENERIC_READ, &value);
+    if (FAILED(hr))
+    {
+        // TODO: some reaction?
+    }
+    mInfo.bCanRead = value;
+
     // Get size of decrypt block
     DWORD* blockSize;
     hr = IpcGetKeyProperty(key, IPC_KI_BLOCK_SIZE, nullptr, (LPVOID*)&blockSize);
@@ -124,11 +133,36 @@ void IRMEngine::createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionD
     aEncryptionData["license"] <<= seq;
 }
 
-bool IRMEngine::readEncryptionInfo(uno::Reference<io::XInputStream>& rxInputStream)
+bool IRMEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage)
 {
-    // MS-OFFCRYPTO 2.2.6: XrMLLicense
-    BinaryXInputStream aBinaryStream(rxInputStream, true);
+    // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4)
+    uno::Reference<io::XInputStream> xTransformInfoStream = rOleStorage.openInputStream(
+        "\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary");
+    SAL_WARN_IF(!xTransformInfoStream.is(), "oox", "TransormInfo stream is missing!");
+    BinaryXInputStream aBinaryStream(xTransformInfoStream, true);
+
+    // MS-OFFCRYPTO 2.1.8: TransformInfoHeader
+    aBinaryStream.readuInt32(); // TransformLength
+    aBinaryStream.readuInt32(); // TransformType
+    // TransformId
     sal_uInt32 aStringLength = aBinaryStream.readuInt32();
+    OUString sTransformId = aBinaryStream.readUnicodeArray(aStringLength / 2);
+    aBinaryStream.skip((4 - (aStringLength & 3)) & 3); // Skip padding
+
+    // TransformName
+    aStringLength = aBinaryStream.readuInt32();
+    OUString sTransformName = aBinaryStream.readUnicodeArray(aStringLength / 2);
+    aBinaryStream.skip((4 - (aStringLength & 3)) & 3); // Skip padding
+
+    aBinaryStream.readuInt32(); // ReaderVersion
+    aBinaryStream.readuInt32(); // UpdaterVersion
+    aBinaryStream.readuInt32(); // WriterVersion
+
+    // MS-OFFCRYPTO 2.2.5: ExtensibilityHeader
+    aBinaryStream.readuInt32(); // ExtensibilityHeader
+
+    // MS-OFFCRYPTO 2.2.6: XrMLLicense
+    aStringLength = aBinaryStream.readuInt32();
     mInfo.license = aBinaryStream.readCharArray(aStringLength);
 
     if (mInfo.license.getLength()
diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
index 05d569c32cec..86d9092be574 100644
--- a/oox/source/crypto/Standard2007Engine.cxx
+++ b/oox/source/crypto/Standard2007Engine.cxx
@@ -215,7 +215,7 @@ bool Standard2007Engine::setupEncryption(css::uno::Sequence<css::beans::NamedVal
     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;
@@ -289,9 +289,11 @@ void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> &  r
     }
 }
 
-bool Standard2007Engine::readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream)
+bool Standard2007Engine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage)
 {
+    Reference<css::io::XInputStream> rxInputStream = rOleStorage.openInputStream("EncryptionInfo");
     BinaryXInputStream aBinaryStream(rxInputStream, false);
+    aBinaryStream.readuInt32();    // Version
 
     mInfo.header.flags = aBinaryStream.readuInt32();
     if (getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_EXTERNAL))
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx
index 1b6b04db197e..11a4d2b7e9ab 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -2701,7 +2701,8 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter,
                 if ( lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName() ) )
                 {
                     ::comphelper::SequenceAsHashMap aHashData;
-                    aHashData[ OUString( "OOXPassword"  ) ] <<= pPasswordRequest->getPassword();
+                    aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword();
+                    aHashData[ OUString( "CryptoType" ) ] <<= OUString( "Standard" );
                     pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
                 }
                 else
diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx
index 23cc46af3016..b91015956b36 100644
--- a/sw/qa/extras/inc/swmodeltestbase.hxx
+++ b/sw/qa/extras/inc/swmodeltestbase.hxx
@@ -792,6 +792,7 @@ protected:
             {
                 OUString sPassword = OUString::createFromAscii(pPassword);
                 css::uno::Sequence<css::beans::NamedValue> aEncryptionData {
+                    { "CryptoType", css::uno::makeAny(OUString("Standard")) },
                     { "OOXPassword", css::uno::makeAny(sPassword) }
                 };
                 aMediaDescriptor[utl::MediaDescriptor::PROP_ENCRYPTIONDATA()] <<= aEncryptionData;


More information about the Libreoffice-commits mailing list