[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