[Libreoffice-commits] core.git: 2 commits - include/oox include/tools oox/source tools/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Fri Jul 6 16:27:09 UTC 2018


 include/oox/crypto/AgileEngine.hxx        |    2 
 include/oox/crypto/CryptoEngine.hxx       |    4 
 include/oox/crypto/DocumentDecryption.hxx |    4 
 include/oox/crypto/Standard2007Engine.hxx |    2 
 include/tools/XmlWriter.hxx               |   10 
 oox/source/crypto/AgileEngine.cxx         |  200 +++++++++++++++++++
 oox/source/crypto/DocumentDecryption.cxx  |  306 +-----------------------------
 oox/source/crypto/Standard2007Engine.cxx  |   56 +++++
 tools/source/xml/XmlWriter.cxx            |   39 +++
 9 files changed, 325 insertions(+), 298 deletions(-)

New commits:
commit 96fb57611f8c9fa19a12c0fd9ed6e0c383962ac7
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Jul 4 17:45:00 2018 +0200

    oox: move reading of the encryption info into the crypt engine
    
    Change-Id: I92345cd8a0f9fc9172ae087e1bc1a16afdd67d8a
    Reviewed-on: https://gerrit.libreoffice.org/56972
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/include/oox/crypto/AgileEngine.hxx b/include/oox/crypto/AgileEngine.hxx
index 22233b051011..dc7538fafde4 100644
--- a/include/oox/crypto/AgileEngine.hxx
+++ b/include/oox/crypto/AgileEngine.hxx
@@ -74,6 +74,8 @@ public:
                     BinaryXInputStream& aInputStream,
                     BinaryXOutputStream& aOutputStream) override;
 
+    bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override;
+
     virtual void encrypt(
                     BinaryXInputStream& aInputStream,
                     BinaryXOutputStream& aOutputStream) override;
diff --git a/include/oox/crypto/CryptoEngine.hxx b/include/oox/crypto/CryptoEngine.hxx
index 9b988c0b2f25..0b6844671457 100644
--- a/include/oox/crypto/CryptoEngine.hxx
+++ b/include/oox/crypto/CryptoEngine.hxx
@@ -16,6 +16,8 @@
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 
+#include <com/sun/star/io/XInputStream.hpp>
+
 namespace oox {
     class BinaryXInputStream;
     class BinaryXOutputStream;
@@ -46,6 +48,8 @@ public:
                     BinaryXInputStream& aInputStream,
                     BinaryXOutputStream& aOutputStream) = 0;
 
+    virtual bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) = 0;
+
     virtual void encrypt(
                     BinaryXInputStream& aInputStream,
                     BinaryXOutputStream& aOutputStream) = 0;
diff --git a/include/oox/crypto/DocumentDecryption.hxx b/include/oox/crypto/DocumentDecryption.hxx
index 852dd9035c9f..a18e94e10412 100644
--- a/include/oox/crypto/DocumentDecryption.hxx
+++ b/include/oox/crypto/DocumentDecryption.hxx
@@ -27,7 +27,6 @@ namespace com { namespace sun { namespace star {
     namespace uno { class XComponentContext; }
 } } }
 
-namespace oox { class BinaryInputStream; }
 namespace oox { namespace ole { class OleStorage; } }
 
 namespace oox {
@@ -49,9 +48,6 @@ private:
     std::unique_ptr<CryptoEngine>   mEngine;
     CryptoType                      mCryptoType;
 
-    bool readAgileEncryptionInfo( css::uno::Reference< css::io::XInputStream > const & rStream );
-    bool readStandard2007EncryptionInfo( BinaryInputStream& rStream );
-
 public:
     DocumentDecryption(
         oox::ole::OleStorage& rOleStorage,
diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx
index ea92c4b5df51..0ad7a21eec3b 100644
--- a/include/oox/crypto/Standard2007Engine.hxx
+++ b/include/oox/crypto/Standard2007Engine.hxx
@@ -48,6 +48,8 @@ public:
                     BinaryXInputStream& aInputStream,
                     BinaryXOutputStream& aOutputStream) override;
 
+    bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override;
+
     virtual void encrypt(
                     BinaryXInputStream& aInputStream,
                     BinaryXOutputStream& aOutputStream) override;
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
index 49b428053061..72cd51e16986 100644
--- a/oox/source/crypto/AgileEngine.cxx
+++ b/oox/source/crypto/AgileEngine.cxx
@@ -13,14 +13,161 @@
 #include <oox/helper/binaryinputstream.hxx>
 #include <oox/helper/binaryoutputstream.hxx>
 
+#include <sax/tools/converter.hxx>
+
 #include <comphelper/hash.hxx>
 #include <comphelper/docpasswordhelper.hxx>
+#include <comphelper/random.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/base64.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <filter/msfilter/mscodec.hxx>
+
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
+#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
+#include <com/sun/star/xml/sax/FastParser.hpp>
+#include <com/sun/star/xml/sax/FastToken.hpp>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::uno;
+using namespace css::xml::sax;
+using namespace css::xml;
 
 namespace oox {
 namespace core {
 
 namespace {
 
+OUString stripNamespacePrefix(OUString const & rsInputName)
+{
+    return rsInputName.copy(rsInputName.indexOf(":") + 1);
+}
+
+class AgileTokenHandler : public cppu::WeakImplHelper<XFastTokenHandler>
+{
+public:
+    virtual sal_Int32 SAL_CALL getTokenFromUTF8(const Sequence< sal_Int8 >& /*nIdentifier*/) override
+    {
+        return FastToken::DONTKNOW;
+    }
+
+    virtual Sequence<sal_Int8> SAL_CALL getUTF8Identifier(sal_Int32 /*nToken*/) override
+    {
+        return Sequence<sal_Int8>();
+    }
+};
+
+class AgileDocumentHandler : public ::cppu::WeakImplHelper<XFastDocumentHandler>
+{
+    AgileEncryptionInfo& mInfo;
+
+public:
+    explicit AgileDocumentHandler(AgileEncryptionInfo& rInfo) :
+        mInfo(rInfo)
+    {}
+
+    void SAL_CALL startDocument() override {}
+    void SAL_CALL endDocument() override {}
+    void SAL_CALL processingInstruction( const OUString& /*rTarget*/, const OUString& /*rData*/ ) override {}
+    void SAL_CALL setDocumentLocator( const Reference< XLocator >& /*xLocator*/ ) override {}
+    void SAL_CALL startFastElement( sal_Int32 /*Element*/, const Reference< XFastAttributeList >& /*Attribs*/ ) override {}
+
+    void SAL_CALL startUnknownElement( const OUString& /*aNamespace*/, const OUString& rName, const Reference< XFastAttributeList >& aAttributeList ) override
+    {
+        const OUString& rLocalName = stripNamespacePrefix(rName);
+
+        for (const Attribute& rAttribute : aAttributeList->getUnknownAttributes())
+        {
+            const OUString& rAttrLocalName = stripNamespacePrefix(rAttribute.Name);
+
+            if (rAttrLocalName == "spinCount")
+            {
+                ::sax::Converter::convertNumber(mInfo.spinCount, rAttribute.Value);
+            }
+            else if (rAttrLocalName == "saltSize")
+            {
+                ::sax::Converter::convertNumber(mInfo.saltSize, rAttribute.Value);
+            }
+            else if (rAttrLocalName == "blockSize")
+            {
+                ::sax::Converter::convertNumber(mInfo.blockSize, rAttribute.Value);
+            }
+            else if (rAttrLocalName == "keyBits")
+            {
+                ::sax::Converter::convertNumber(mInfo.keyBits, rAttribute.Value);
+            }
+            else if (rAttrLocalName == "hashSize")
+            {
+                ::sax::Converter::convertNumber(mInfo.hashSize, rAttribute.Value);
+            }
+            else if (rAttrLocalName == "cipherAlgorithm")
+            {
+                mInfo.cipherAlgorithm = rAttribute.Value;
+            }
+            else if (rAttrLocalName == "cipherChaining")
+            {
+                mInfo.cipherChaining = rAttribute.Value;
+            }
+            else if (rAttrLocalName == "hashAlgorithm")
+            {
+                mInfo.hashAlgorithm = rAttribute.Value;
+            }
+            else if (rAttrLocalName == "saltValue")
+            {
+                Sequence<sal_Int8> saltValue;
+                comphelper::Base64::decode(saltValue, rAttribute.Value);
+                if (rLocalName == "encryptedKey")
+                    mInfo.saltValue = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(saltValue);
+                else if (rLocalName == "keyData")
+                    mInfo.keyDataSalt = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(saltValue);
+            }
+            else if (rAttrLocalName == "encryptedVerifierHashInput")
+            {
+                Sequence<sal_Int8> encryptedVerifierHashInput;
+                comphelper::Base64::decode(encryptedVerifierHashInput, rAttribute.Value);
+                mInfo.encryptedVerifierHashInput = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(encryptedVerifierHashInput);
+            }
+            else if (rAttrLocalName == "encryptedVerifierHashValue")
+            {
+                Sequence<sal_Int8> encryptedVerifierHashValue;
+                comphelper::Base64::decode(encryptedVerifierHashValue, rAttribute.Value);
+                mInfo.encryptedVerifierHashValue = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(encryptedVerifierHashValue);
+            }
+            else if (rAttrLocalName == "encryptedKeyValue")
+            {
+                Sequence<sal_Int8> encryptedKeyValue;
+                comphelper::Base64::decode(encryptedKeyValue, rAttribute.Value);
+                mInfo.encryptedKeyValue = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(encryptedKeyValue);
+            }
+        }
+    }
+
+    void SAL_CALL endFastElement( sal_Int32 /*aElement*/ ) override
+    {}
+    void SAL_CALL endUnknownElement( const OUString& /*aNamespace*/, const OUString& /*aName*/ ) override
+    {}
+
+    Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 /*aElement*/, const Reference< XFastAttributeList >& /*aAttribs*/ ) override
+    {
+        return nullptr;
+    }
+
+    Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& /*aNamespace*/, const OUString& /*aName*/, const Reference< XFastAttributeList >& /*aAttribs*/ ) override
+    {
+        return this;
+    }
+
+    void SAL_CALL characters( const OUString& /*aChars*/ ) override
+    {}
+};
+
 const sal_uInt32 constSegmentLength = 4096;
 
 bool hashCalc(std::vector<sal_uInt8>& output,
@@ -163,6 +310,59 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
     return true;
 }
 
+bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputStream)
+{
+    mInfo.spinCount = 0;
+    mInfo.saltSize = 0;
+    mInfo.keyBits = 0;
+    mInfo.hashSize = 0;
+    mInfo.blockSize = 0;
+
+    Reference<XFastDocumentHandler> xFastDocumentHandler(new AgileDocumentHandler(mInfo));
+    Reference<XFastTokenHandler> xFastTokenHandler(new AgileTokenHandler);
+
+    Reference<XFastParser> xParser(css::xml::sax::FastParser::create(comphelper::getProcessComponentContext()));
+
+    xParser->setFastDocumentHandler(xFastDocumentHandler);
+    xParser->setTokenHandler(xFastTokenHandler);
+
+    InputSource aInputSource;
+    aInputSource.aInputStream = rxInputStream;
+    xParser->parseStream(aInputSource);
+
+    // CHECK info data
+    if (2 > mInfo.blockSize || mInfo.blockSize > 4096)
+        return false;
+
+    if (0 > mInfo.spinCount || mInfo.spinCount > 10000000)
+        return false;
+
+    if (1 > mInfo.saltSize|| mInfo.saltSize > 65536) // Check
+        return false;
+
+    // AES 128 CBC with SHA1
+    if (mInfo.keyBits         == 128 &&
+        mInfo.cipherAlgorithm == "AES" &&
+        mInfo.cipherChaining  == "ChainingModeCBC" &&
+        mInfo.hashAlgorithm   == "SHA1" &&
+        mInfo.hashSize        == msfilter::SHA1_HASH_LENGTH)
+    {
+        return true;
+    }
+
+    // AES 256 CBC with SHA512
+    if (mInfo.keyBits         == 256 &&
+        mInfo.cipherAlgorithm == "AES" &&
+        mInfo.cipherChaining  == "ChainingModeCBC" &&
+        mInfo.hashAlgorithm   == "SHA512" &&
+        mInfo.hashSize        == msfilter::SHA512_HASH_LENGTH)
+    {
+        return true;
+    }
+
+    return false;
+}
+
 void AgileEngine::writeEncryptionInfo(
                         const OUString& /*aPassword*/,
                         BinaryXOutputStream& /*rStream*/)
diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx
index bd8dff7e022a..40d854123568 100644
--- a/oox/source/crypto/DocumentDecryption.cxx
+++ b/oox/source/crypto/DocumentDecryption.cxx
@@ -10,18 +10,11 @@
 
 #include <oox/crypto/DocumentDecryption.hxx>
 
-#include <comphelper/base64.hxx>
 #include <comphelper/sequenceashashmap.hxx>
-#include <sax/tools/converter.hxx>
 #include <cppuhelper/implbase.hxx>
 
-#include <com/sun/star/io/XSeekable.hpp>
 #include <com/sun/star/io/XStream.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
-#include <com/sun/star/xml/sax/XFastParser.hpp>
-#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
-#include <com/sun/star/xml/sax/FastParser.hpp>
-#include <com/sun/star/xml/sax/FastToken.hpp>
 #include <oox/crypto/AgileEngine.hxx>
 #include <oox/crypto/Standard2007Engine.hxx>
 #include <oox/helper/binaryinputstream.hxx>
@@ -31,158 +24,9 @@
 namespace oox {
 namespace core {
 
-using namespace css::beans;
-using namespace css::io;
-using namespace css::lang;
-using namespace css::uno;
-using namespace css::xml::sax;
-using namespace css::xml;
+using namespace css;
 
-namespace {
-
-std::vector<sal_uInt8> convertToVector(Sequence<sal_Int8> const & input)
-{
-    const sal_uInt8* inputArray = reinterpret_cast<const sal_uInt8*>(input.getConstArray());
-    return std::vector<sal_uInt8>(inputArray, inputArray + input.getLength());
-}
-
-class AgileTokenHandler : public cppu::WeakImplHelper<XFastTokenHandler>
-{
-public:
-    virtual sal_Int32 SAL_CALL getTokenFromUTF8( const Sequence< sal_Int8 >& /*nIdentifier*/ ) override
-    {
-        return FastToken::DONTKNOW;
-    }
-
-    virtual Sequence<sal_Int8> SAL_CALL getUTF8Identifier(sal_Int32 /*nToken*/) override
-    {
-        return Sequence<sal_Int8>();
-    }
-};
-
-class AgileDocumentHandler : public ::cppu::WeakImplHelper<XFastDocumentHandler>
-{
-    AgileEncryptionInfo& mInfo;
-
-public:
-    explicit AgileDocumentHandler(AgileEncryptionInfo& rInfo) :
-        mInfo(rInfo)
-    {}
-
-    void SAL_CALL startDocument() override
-    {}
-    void SAL_CALL endDocument() override
-    {}
-    void SAL_CALL processingInstruction( const OUString& /*rTarget*/, const OUString& /*rData*/ ) override
-    {}
-    void SAL_CALL setDocumentLocator( const Reference< XLocator >& /*xLocator*/ ) override
-    {}
-    void SAL_CALL startFastElement( sal_Int32 /*Element*/, const Reference< XFastAttributeList >& /*Attribs*/ ) override
-    {}
-
-    void SAL_CALL startUnknownElement( const OUString& /*aNamespace*/, const OUString& rName, const Reference< XFastAttributeList >& aAttributeList ) override
-    {
-        const auto& localname = [](const OUString &a) { return a.copy(a.indexOf(":") + 1); };
-        const OUString& rLocalName = localname(rName);
-        if (rLocalName == "keyData")
-        {
-            for (const Attribute& rAttribute : aAttributeList->getUnknownAttributes())
-            {
-                if (localname(rAttribute.Name) == "saltValue")
-                {
-                    Sequence<sal_Int8> keyDataSalt;
-                    ::comphelper::Base64::decode(keyDataSalt, rAttribute.Value);
-                    mInfo.keyDataSalt = convertToVector(keyDataSalt);
-                }
-            }
-        }
-        else if (rLocalName == "encryptedKey")
-        {
-            for (const Attribute& rAttribute : aAttributeList->getUnknownAttributes())
-            {
-                const OUString& rAttrLocalName = localname(rAttribute.Name);
-                if (rAttrLocalName == "spinCount")
-                {
-                    ::sax::Converter::convertNumber(mInfo.spinCount, rAttribute.Value);
-                }
-                else if (rAttrLocalName == "saltSize")
-                {
-                    ::sax::Converter::convertNumber(mInfo.saltSize, rAttribute.Value);
-                }
-                else if (rAttrLocalName == "blockSize")
-                {
-                    ::sax::Converter::convertNumber(mInfo.blockSize, rAttribute.Value);
-                }
-                else if (rAttrLocalName == "keyBits")
-                {
-                    ::sax::Converter::convertNumber(mInfo.keyBits, rAttribute.Value);
-                }
-                else if (rAttrLocalName == "hashSize")
-                {
-                    ::sax::Converter::convertNumber(mInfo.hashSize, rAttribute.Value);
-                }
-                else if (rAttrLocalName == "cipherAlgorithm")
-                {
-                    mInfo.cipherAlgorithm = rAttribute.Value;
-                }
-                else if (rAttrLocalName == "cipherChaining")
-                {
-                    mInfo.cipherChaining = rAttribute.Value;
-                }
-                else if (rAttrLocalName == "hashAlgorithm")
-                {
-                    mInfo.hashAlgorithm = rAttribute.Value;
-                }
-                else if (rAttrLocalName == "saltValue")
-                {
-                    Sequence<sal_Int8> saltValue;
-                    ::comphelper::Base64::decode(saltValue, rAttribute.Value);
-                    mInfo.saltValue = convertToVector(saltValue);
-                }
-                else if (rAttrLocalName == "encryptedVerifierHashInput")
-                {
-                    Sequence<sal_Int8> encryptedVerifierHashInput;
-                    ::comphelper::Base64::decode(encryptedVerifierHashInput, rAttribute.Value);
-                    mInfo.encryptedVerifierHashInput = convertToVector(encryptedVerifierHashInput);
-                }
-                else if (rAttrLocalName == "encryptedVerifierHashValue")
-                {
-                    Sequence<sal_Int8> encryptedVerifierHashValue;
-                    ::comphelper::Base64::decode(encryptedVerifierHashValue, rAttribute.Value);
-                    mInfo.encryptedVerifierHashValue = convertToVector(encryptedVerifierHashValue);
-                }
-                else if (rAttrLocalName == "encryptedKeyValue")
-                {
-                    Sequence<sal_Int8> encryptedKeyValue;
-                    ::comphelper::Base64::decode(encryptedKeyValue, rAttribute.Value);
-                    mInfo.encryptedKeyValue = convertToVector(encryptedKeyValue);
-                }
-            }
-        }
-    }
-
-    void SAL_CALL endFastElement( sal_Int32 /*aElement*/ ) override
-    {}
-    void SAL_CALL endUnknownElement( const OUString& /*aNamespace*/, const OUString& /*aName*/ ) override
-    {}
-
-    Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 /*aElement*/, const Reference< XFastAttributeList >& /*aAttribs*/ ) override
-    {
-        return nullptr;
-    }
-
-    Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& /*aNamespace*/, const OUString& /*aName*/, const Reference< XFastAttributeList >& /*aAttribs*/ ) override
-    {
-        return this;
-    }
-
-    void SAL_CALL characters( const OUString& /*aChars*/ ) override
-    {}
-};
-
-} // namespace
-
-DocumentDecryption::DocumentDecryption(oox::ole::OleStorage& rOleStorage, Reference<XComponentContext> const & xContext) :
+DocumentDecryption::DocumentDecryption(oox::ole::OleStorage& rOleStorage, uno::Reference<uno::XComponentContext> const & xContext) :
     mxContext(xContext),
     mrOleStorage(rOleStorage),
     mCryptoType(UNKNOWN)
@@ -190,136 +34,19 @@ DocumentDecryption::DocumentDecryption(oox::ole::OleStorage& rOleStorage, Refere
 
 bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword)
 {
-    if (mEngine.get())
+    if (mEngine)
         return mEngine->generateEncryptionKey(rPassword);
     return false;
 }
 
-bool DocumentDecryption::readAgileEncryptionInfo(Reference< XInputStream > const & xInputStream)
-{
-    AgileEngine* engine = new AgileEngine;
-    mEngine.reset(engine);
-    AgileEncryptionInfo& info = engine->getInfo();
-    info.spinCount = 0;
-    info.saltSize = 0;
-    info.keyBits = 0;
-    info.hashSize = 0;
-    info.blockSize = 0;
-
-    Reference<XFastDocumentHandler> xFastDocumentHandler( new AgileDocumentHandler(info) );
-    Reference<XFastTokenHandler>    xFastTokenHandler   ( new AgileTokenHandler );
-
-    Reference<XFastParser> xParser(css::xml::sax::FastParser::create(mxContext));
-
-    xParser->setFastDocumentHandler(xFastDocumentHandler);
-    xParser->setTokenHandler(xFastTokenHandler);
-
-    InputSource aInputSource;
-    aInputSource.aInputStream = xInputStream;
-    xParser->parseStream(aInputSource);
-
-    // CHECK info data
-    if (2 > info.blockSize || info.blockSize > 4096)
-        return false;
-
-    if (0 > info.spinCount || info.spinCount > 10000000)
-        return false;
-
-    if (1 > info.saltSize|| info.saltSize > 65536) // Check
-        return false;
-
-    // AES 128 CBC with SHA1
-    if (info.keyBits         == 128 &&
-        info.cipherAlgorithm == "AES" &&
-        info.cipherChaining  == "ChainingModeCBC" &&
-        info.hashAlgorithm   == "SHA1" &&
-        info.hashSize        == msfilter::SHA1_HASH_LENGTH)
-    {
-        return true;
-    }
-
-    // AES 256 CBC with SHA512
-    if (info.keyBits         == 256 &&
-        info.cipherAlgorithm == "AES" &&
-        info.cipherChaining  == "ChainingModeCBC" &&
-        info.hashAlgorithm   == "SHA512" &&
-        info.hashSize        == msfilter::SHA512_HASH_LENGTH)
-    {
-        return true;
-    }
-
-    return false;
-}
-
-bool DocumentDecryption::readStandard2007EncryptionInfo(BinaryInputStream& rStream)
-{
-    Standard2007Engine* engine = new Standard2007Engine;
-    mEngine.reset(engine);
-    msfilter::StandardEncryptionInfo& info = engine->getInfo();
-
-    info.header.flags = rStream.readuInt32();
-    if (getFlag(info.header.flags, msfilter::ENCRYPTINFO_EXTERNAL))
-        return false;
-
-    sal_uInt32 nHeaderSize = rStream.readuInt32();
-
-    sal_uInt32 actualHeaderSize = sizeof(info.header);
-
-    if (nHeaderSize < actualHeaderSize)
-        return false;
-
-    info.header.flags = rStream.readuInt32();
-    info.header.sizeExtra = rStream.readuInt32();
-    info.header.algId = rStream.readuInt32();
-    info.header.algIdHash = rStream.readuInt32();
-    info.header.keyBits = rStream.readuInt32();
-    info.header.providedType = rStream.readuInt32();
-    info.header.reserved1 = rStream.readuInt32();
-    info.header.reserved2 = rStream.readuInt32();
-
-    rStream.skip(nHeaderSize - actualHeaderSize);
-
-    info.verifier.saltSize = rStream.readuInt32();
-    rStream.readArray(info.verifier.salt, SAL_N_ELEMENTS(info.verifier.salt));
-    rStream.readArray(info.verifier.encryptedVerifier, SAL_N_ELEMENTS(info.verifier.encryptedVerifier));
-    info.verifier.encryptedVerifierHashSize = rStream.readuInt32();
-    rStream.readArray(info.verifier.encryptedVerifierHash, SAL_N_ELEMENTS(info.verifier.encryptedVerifierHash));
-
-    if (info.verifier.saltSize != 16)
-        return false;
-
-    // check flags and algorithm IDs, required are AES128 and SHA-1
-    if (!getFlag(info.header.flags, msfilter::ENCRYPTINFO_CRYPTOAPI))
-        return false;
-
-    if (!getFlag(info.header.flags, msfilter::ENCRYPTINFO_AES))
-        return false;
-
-    // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
-    if (info.header.algId != 0 && info.header.algId != msfilter::ENCRYPT_ALGO_AES128)
-        return false;
-
-    // hash algorithm ID 0 defaults to SHA-1 too
-    if (info.header.algIdHash != 0 && info.header.algIdHash != msfilter::ENCRYPT_HASH_SHA1)
-        return false;
-
-    if (info.verifier.encryptedVerifierHashSize != 20)
-        return false;
-
-    return !rStream.isEof();
-}
-
 bool DocumentDecryption::readEncryptionInfo()
 {
     if (!mrOleStorage.isStorage())
         return false;
 
-    Reference<XInputStream> xEncryptionInfo(mrOleStorage.openInputStream("EncryptionInfo"), UNO_SET_THROW);
-
-    bool bResult = false;
+    uno::Reference<io::XInputStream> xEncryptionInfo(mrOleStorage.openInputStream("EncryptionInfo"), uno::UNO_QUERY);
 
     BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
-
     sal_uInt32 aVersion = aBinaryInputStream.readuInt32();
 
     switch (aVersion)
@@ -327,21 +54,22 @@ bool DocumentDecryption::readEncryptionInfo()
         case msfilter::VERSION_INFO_2007_FORMAT:
         case msfilter::VERSION_INFO_2007_FORMAT_SP2:
             mCryptoType = STANDARD_2007; // Set encryption info format
-            bResult = readStandard2007EncryptionInfo( aBinaryInputStream );
+            mEngine.reset(new Standard2007Engine);
             break;
         case msfilter::VERSION_INFO_AGILE:
             mCryptoType = AGILE; // Set encryption info format
-            aBinaryInputStream.skip(4);
-            bResult = readAgileEncryptionInfo( xEncryptionInfo );
+            xEncryptionInfo->skipBytes(4);
+            mEngine.reset(new AgileEngine);
             break;
         default:
             break;
     }
-
-    return bResult;
+    if (mEngine)
+        return mEngine->readEncryptionInfo(xEncryptionInfo);
+    return false;
 }
 
-Sequence<NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword)
+uno::Sequence<beans::NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword)
 {
     comphelper::SequenceAsHashMap aEncryptionData;
 
@@ -358,27 +86,27 @@ Sequence<NamedValue> DocumentDecryption::createEncryptionData(const OUString& rP
     return aEncryptionData.getAsConstNamedValueList();
 }
 
-bool DocumentDecryption::decrypt(const Reference<XStream>& xDocumentStream)
+bool DocumentDecryption::decrypt(const uno::Reference<io::XStream>& xDocumentStream)
 {
-    bool aResult = false;
+    bool bResult = false;
 
     if (!mrOleStorage.isStorage())
         return false;
 
     // open the required input streams in the encrypted package
-    Reference<XInputStream> xEncryptedPackage(mrOleStorage.openInputStream("EncryptedPackage"), UNO_SET_THROW);
+    uno::Reference<io::XInputStream> xEncryptedPackage(mrOleStorage.openInputStream("EncryptedPackage"), uno::UNO_QUERY);
 
     // create temporary file for unencrypted package
-    Reference<XOutputStream> xDecryptedPackage(xDocumentStream->getOutputStream(), UNO_SET_THROW);
+    uno::Reference<io::XOutputStream> xDecryptedPackage(xDocumentStream->getOutputStream(), uno::UNO_QUERY);
     BinaryXOutputStream aDecryptedPackage(xDecryptedPackage, true);
     BinaryXInputStream aEncryptedPackage(xEncryptedPackage, true);
 
-    aResult = mEngine->decrypt(aEncryptedPackage, aDecryptedPackage);
+    bResult = mEngine->decrypt(aEncryptedPackage, aDecryptedPackage);
 
     xDecryptedPackage->flush();
     aDecryptedPackage.seekToStart();
 
-    return aResult;
+    return bResult;
 }
 
 } // namespace core
diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
index 8955101f6842..6da188f514c5 100644
--- a/oox/source/crypto/Standard2007Engine.cxx
+++ b/oox/source/crypto/Standard2007Engine.cxx
@@ -226,6 +226,62 @@ void Standard2007Engine::encrypt(BinaryXInputStream& aInputStream,
     }
 }
 
+bool Standard2007Engine::readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream)
+{
+    BinaryXInputStream aBinaryStream(rxInputStream, false);
+
+    mInfo.header.flags = aBinaryStream.readuInt32();
+    if (getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_EXTERNAL))
+        return false;
+
+    sal_uInt32 nHeaderSize = aBinaryStream.readuInt32();
+
+    sal_uInt32 actualHeaderSize = sizeof(mInfo.header);
+
+    if (nHeaderSize < actualHeaderSize)
+        return false;
+
+    mInfo.header.flags = aBinaryStream.readuInt32();
+    mInfo.header.sizeExtra = aBinaryStream.readuInt32();
+    mInfo.header.algId = aBinaryStream.readuInt32();
+    mInfo.header.algIdHash = aBinaryStream.readuInt32();
+    mInfo.header.keyBits = aBinaryStream.readuInt32();
+    mInfo.header.providedType = aBinaryStream.readuInt32();
+    mInfo.header.reserved1 = aBinaryStream.readuInt32();
+    mInfo.header.reserved2 = aBinaryStream.readuInt32();
+
+    aBinaryStream.skip(nHeaderSize - actualHeaderSize);
+
+    mInfo.verifier.saltSize = aBinaryStream.readuInt32();
+    aBinaryStream.readArray(mInfo.verifier.salt, SAL_N_ELEMENTS(mInfo.verifier.salt));
+    aBinaryStream.readArray(mInfo.verifier.encryptedVerifier, SAL_N_ELEMENTS(mInfo.verifier.encryptedVerifier));
+    mInfo.verifier.encryptedVerifierHashSize = aBinaryStream.readuInt32();
+    aBinaryStream.readArray(mInfo.verifier.encryptedVerifierHash, SAL_N_ELEMENTS(mInfo.verifier.encryptedVerifierHash));
+
+    if (mInfo.verifier.saltSize != 16)
+        return false;
+
+    // check flags and algorithm IDs, required are AES128 and SHA-1
+    if (!getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_CRYPTOAPI))
+        return false;
+
+    if (!getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_AES))
+        return false;
+
+    // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
+    if (mInfo.header.algId != 0 && mInfo.header.algId != msfilter::ENCRYPT_ALGO_AES128)
+        return false;
+
+    // hash algorithm ID 0 defaults to SHA-1 too
+    if (mInfo.header.algIdHash != 0 && mInfo.header.algIdHash != msfilter::ENCRYPT_HASH_SHA1)
+        return false;
+
+    if (mInfo.verifier.encryptedVerifierHashSize != 20)
+        return false;
+
+    return !aBinaryStream.isEof();
+}
+
 } // namespace core
 } // namespace oox
 
commit 72aa159a6fce92f47a56a8de8c7f8260577dd936
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Jul 4 17:18:43 2018 +0200

    XmlWriter: support namespaces, writing of base64 attribute
    
    Change-Id: I3c1d885d239178b46578123fd83d3aa1d7ccd023
    Reviewed-on: https://gerrit.libreoffice.org/56971
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/include/tools/XmlWriter.hxx b/include/tools/XmlWriter.hxx
index 8224df417f1b..6095d1379bfe 100644
--- a/include/tools/XmlWriter.hxx
+++ b/include/tools/XmlWriter.hxx
@@ -13,6 +13,7 @@
 #include <tools/toolsdllapi.h>
 #include <tools/stream.hxx>
 #include <memory>
+#include <vector>
 
 namespace tools
 {
@@ -23,8 +24,8 @@ struct XmlWriterImpl;
  * all the internal libxml2 workings and uses types that are native for LO
  * development.
  *
- * The codepage used for XML is always "utf-8" and the output is indented so it
- * is easier to read.
+ * The codepage used for XML is always "utf-8" and the output is indented by
+ * default so it is easier to read.
  *
  */
 class TOOLS_DLLPUBLIC XmlWriter final
@@ -37,15 +38,18 @@ public:
 
     ~XmlWriter();
 
-    bool startDocument();
+    bool startDocument(sal_Int32 nIndent = 2);
     void endDocument();
 
     void startElement(const OString& sName);
+    void startElement(const OString& sPrefix, const OString& sName, const OString& sNamespaceUri);
     void endElement();
 
     void attribute(const OString& sTagName, const OString& aValue);
     void attribute(const OString& sTagName, const OUString& aValue);
     void attribute(const OString& sTagName, sal_Int32 aNumber);
+    void attributeBase64(const OString& sTagName, std::vector<sal_uInt8> const& rValueInBytes);
+    void attributeBase64(const OString& sTagName, std::vector<char> const& rValueInBytes);
 
     void content(const OString& sValue);
     void content(const OUString& sValue);
diff --git a/tools/source/xml/XmlWriter.cxx b/tools/source/xml/XmlWriter.cxx
index ba2c3936f51b..8895e92064db 100644
--- a/tools/source/xml/XmlWriter.cxx
+++ b/tools/source/xml/XmlWriter.cxx
@@ -54,14 +54,14 @@ XmlWriter::~XmlWriter()
         endDocument();
 }
 
-bool XmlWriter::startDocument()
+bool XmlWriter::startDocument(sal_Int32 nIndent)
 {
     xmlOutputBufferPtr xmlOutBuffer
         = xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback, mpImpl->mpStream, nullptr);
     mpImpl->mpWriter = xmlNewTextWriter(xmlOutBuffer);
     if (mpImpl->mpWriter == nullptr)
         return false;
-    xmlTextWriterSetIndent(mpImpl->mpWriter, 1);
+    xmlTextWriterSetIndent(mpImpl->mpWriter, nIndent);
     xmlTextWriterStartDocument(mpImpl->mpWriter, nullptr, "UTF-8", nullptr);
     return true;
 }
@@ -73,6 +73,26 @@ void XmlWriter::endDocument()
     mpImpl->mpWriter = nullptr;
 }
 
+void XmlWriter::startElement(const OString& sPrefix, const OString& sName,
+                             const OString& sNamespaceUri)
+{
+    xmlChar* xmlName = xmlCharStrdup(sName.getStr());
+    xmlChar* xmlPrefix = nullptr;
+    xmlChar* xmlNamespaceUri = nullptr;
+    if (!sPrefix.isEmpty())
+        xmlPrefix = xmlCharStrdup(sPrefix.getStr());
+    if (!sNamespaceUri.isEmpty())
+        xmlNamespaceUri = xmlCharStrdup(sNamespaceUri.getStr());
+
+    xmlTextWriterStartElementNS(mpImpl->mpWriter, xmlPrefix, xmlName, xmlNamespaceUri);
+
+    xmlFree(xmlName);
+    if (!sPrefix.isEmpty())
+        xmlFree(xmlPrefix);
+    if (!sNamespaceUri.isEmpty())
+        xmlFree(xmlNamespaceUri);
+}
+
 void XmlWriter::startElement(const OString& sName)
 {
     xmlChar* xmlName = xmlCharStrdup(sName.getStr());
@@ -82,6 +102,21 @@ void XmlWriter::startElement(const OString& sName)
 
 void XmlWriter::endElement() { xmlTextWriterEndElement(mpImpl->mpWriter); }
 
+void XmlWriter::attributeBase64(const OString& rsName, std::vector<sal_uInt8> const& rValueInBytes)
+{
+    std::vector<char> aSignedBytes(rValueInBytes.begin(), rValueInBytes.end());
+    attributeBase64(rsName, aSignedBytes);
+}
+
+void XmlWriter::attributeBase64(const OString& rsName, std::vector<char> const& rValueInBytes)
+{
+    xmlChar* xmlName = xmlCharStrdup(rsName.getStr());
+    xmlTextWriterStartAttribute(mpImpl->mpWriter, xmlName);
+    xmlTextWriterWriteBase64(mpImpl->mpWriter, rValueInBytes.data(), 0, rValueInBytes.size());
+    xmlTextWriterEndAttribute(mpImpl->mpWriter);
+    xmlFree(xmlName);
+}
+
 void XmlWriter::attribute(const OString& name, const OString& value)
 {
     xmlChar* xmlName = xmlCharStrdup(name.getStr());


More information about the Libreoffice-commits mailing list