summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2018-07-04 17:45:00 +0200
committerTomaž Vajngerl <quikee@gmail.com>2018-07-06 18:26:47 +0200
commit96fb57611f8c9fa19a12c0fd9ed6e0c383962ac7 (patch)
tree04612c2b2f6e32fbb692b3744682f3a54bc9bab4 /oox
parent72aa159a6fce92f47a56a8de8c7f8260577dd936 (diff)
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@gmail.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/crypto/AgileEngine.cxx200
-rw-r--r--oox/source/crypto/DocumentDecryption.cxx306
-rw-r--r--oox/source/crypto/Standard2007Engine.cxx56
3 files changed, 273 insertions, 289 deletions
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