summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2019-09-23 20:48:41 +0300
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2019-12-04 13:43:21 +0100
commit78149c3847533639542ea55d97c168e0fbcd9822 (patch)
treedda90afb80aea5731329df9d764ec7b169b23eb3 /oox
parent74b6308b8e86da2bd36d241424ff03cae8a52dd2 (diff)
irm: refactoring of decrypt methods
to allow usage of decryt methods outside of LO we should avoid direct usage of OleStorage in CryptoEngine: it is not accessible outside of core. Change-Id: Id60b338445a5950aa40b84d788c94b8fa025e717
Diffstat (limited to 'oox')
-rw-r--r--oox/source/core/filterdetect.cxx2
-rw-r--r--oox/source/core/xmlfilterbase.cxx2
-rw-r--r--oox/source/crypto/AgileEngine.cxx25
-rw-r--r--oox/source/crypto/DocumentDecryption.cxx59
-rw-r--r--oox/source/crypto/DocumentEncryption.cxx10
-rw-r--r--oox/source/crypto/IRMEngine.cxx30
-rw-r--r--oox/source/crypto/Standard2007Engine.cxx26
7 files changed, 132 insertions, 22 deletions
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index 4537e61a93c8..7e72d28482df 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -300,7 +300,7 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript
{
try
{
- DocumentDecryption aDecryptor(aOleStorage);
+ DocumentDecryption aDecryptor(mxContext, aOleStorage);
if( aDecryptor.readEncryptionInfo() )
{
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index c404e3bec6bf..c1c2972f4e9c 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -918,7 +918,7 @@ bool XmlFilterBase::implFinalizeExport( MediaDescriptor& rMediaDescriptor )
Reference< XStream> xDocumentStream (FilterBase::implGetOutputStream(rMediaDescriptor));
oox::ole::OleStorage aOleStorage( getComponentContext(), xDocumentStream, true );
- DocumentEncryption encryptor(getMainDocumentStream(), aOleStorage, aMediaEncData);
+ DocumentEncryption encryptor( getComponentContext(), getMainDocumentStream(), aOleStorage, aMediaEncData );
bRet = encryptor.encrypt();
if (bRet)
aOleStorage.commit();
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
index da454fbe1abe..f1f2b2eb488a 100644
--- a/oox/source/crypto/AgileEngine.cxx
+++ b/oox/source/crypto/AgileEngine.cxx
@@ -29,6 +29,7 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/SequenceInputStream.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
@@ -219,8 +220,9 @@ CryptoHashType cryptoHashTypeFromString(OUString const & sAlgorithm)
} // namespace
-AgileEngine::AgileEngine()
- : meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512)
+AgileEngine::AgileEngine(const Reference< XComponentContext >& rxContext) :
+ meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512),
+ mxContext(rxContext)
{}
Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo)
@@ -484,9 +486,24 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
return true;
}
-bool AgileEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage)
+uno::Reference<io::XInputStream> AgileEngine::getStream(Sequence<NamedValue> & rStreams, const OUString sStreamName)
{
- uno::Reference<io::XInputStream> xEncryptionInfo = rOleStorage.openInputStream("EncryptionInfo");
+ for (const auto & aStream : rStreams)
+ {
+ if (aStream.Name == sStreamName)
+ {
+ css::uno::Sequence<sal_Int8> aSeq;
+ aStream.Value >>= aSeq;
+ Reference<XInputStream> aStream(io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW);
+ return aStream;
+ }
+ }
+ return nullptr;
+}
+
+bool AgileEngine::readEncryptionInfo(Sequence<NamedValue> aStreams)
+{
+ uno::Reference<io::XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo");
BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
aBinaryInputStream.readuInt32(); // Version
diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx
index 5139a5380b0f..9a485688b487 100644
--- a/oox/source/crypto/DocumentDecryption.cxx
+++ b/oox/source/crypto/DocumentDecryption.cxx
@@ -23,14 +23,61 @@
#include <oox/helper/binaryoutputstream.hxx>
#include <oox/ole/olestorage.hxx>
+namespace {
+
+void lcl_getListOfStreams(oox::StorageBase* pStorage, std::vector<OUString>& rElementNames)
+{
+ std::vector< OUString > oElementNames;
+ pStorage->getElementNames(oElementNames);
+ for (const auto & sName : oElementNames)
+ {
+ oox::StorageRef rSubStorage = pStorage->openSubStorage(sName, false);
+ if (rSubStorage && rSubStorage->isStorage())
+ {
+ lcl_getListOfStreams(rSubStorage.get(), rElementNames);
+ }
+ else
+ {
+ if (pStorage->isRootStorage())
+ rElementNames.push_back(sName);
+ else
+ rElementNames.push_back(pStorage->getPath() + "/" + sName);
+ }
+ }
+}
+
+}
+
namespace oox {
namespace core {
using namespace css;
-DocumentDecryption::DocumentDecryption(oox::ole::OleStorage& rOleStorage) :
+DocumentDecryption::DocumentDecryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ oox::ole::OleStorage& rOleStorage) :
+ mxContext(rxContext),
mrOleStorage(rOleStorage)
-{}
+{
+ // Get OLE streams into sequences for later use in CryptoEngine
+ std::vector< OUString > aStreamNames;
+ lcl_getListOfStreams(&mrOleStorage, aStreamNames);
+
+ comphelper::SequenceAsHashMap aStreamsData;
+ for (const auto & sStreamName : aStreamNames)
+ {
+ uno::Reference<io::XInputStream> xStream = mrOleStorage.openInputStream(sStreamName);
+ assert(xStream.is());
+ BinaryXInputStream aBinaryInputStream(xStream, true);
+
+ css::uno::Sequence< sal_Int8 > oData;
+ sal_Int32 nStreamSize = aBinaryInputStream.size();
+ sal_Int32 nReadBytes = aBinaryInputStream.readData(oData, nStreamSize);
+
+ assert(nStreamSize == nReadBytes);
+ aStreamsData[sStreamName] <<= oData;
+ }
+ maStreamsSequence = aStreamsData.getAsConstNamedValueList();
+}
bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword)
{
@@ -51,11 +98,11 @@ void DocumentDecryption::readStrongEncryptionInfo()
case msfilter::VERSION_INFO_2007_FORMAT:
case msfilter::VERSION_INFO_2007_FORMAT_SP2:
msEngineName = "Standard"; // Set encryption info format
- mEngine.reset(new Standard2007Engine);
+ mEngine.reset(new Standard2007Engine(mxContext));
break;
case msfilter::VERSION_INFO_AGILE:
msEngineName = "Agile"; // Set encryption info format
- mEngine.reset(new AgileEngine);
+ mEngine.reset(new AgileEngine(mxContext));
break;
default:
break;
@@ -102,7 +149,7 @@ bool DocumentDecryption::readEncryptionInfo()
if (sDataSpaceName == "DRMEncryptedDataSpace")
{
msEngineName = "IRM"; // Set encryption info format
- mEngine.reset(new IRMEngine);
+ mEngine.reset(new IRMEngine(mxContext));
}
else if (sDataSpaceName == "\011DRMDataSpace") // 0x09DRMDataSpace
{
@@ -128,7 +175,7 @@ bool DocumentDecryption::readEncryptionInfo()
if (!mEngine)
return false;
- return mEngine->readEncryptionInfo(mrOleStorage);
+ return mEngine->readEncryptionInfo(maStreamsSequence);
}
uno::Sequence<beans::NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword)
diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx
index 6975572193d5..8aac457c67d2 100644
--- a/oox/source/crypto/DocumentEncryption.cxx
+++ b/oox/source/crypto/DocumentEncryption.cxx
@@ -27,10 +27,12 @@ namespace core {
using namespace css::io;
using namespace css::uno;
-DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStream,
+DocumentEncryption::DocumentEncryption(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ Reference<XStream> const & xDocumentStream,
oox::ole::OleStorage& rOleStorage,
Sequence<css::beans::NamedValue>& rMediaEncData)
- : mxDocumentStream(xDocumentStream)
+ : mxContext(rxContext)
+ , mxDocumentStream(xDocumentStream)
, mrOleStorage(rOleStorage)
, mMediaEncData(rMediaEncData)
{
@@ -43,11 +45,11 @@ DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStrea
rMediaEncData[i].Value >>= sCryptoType;
if (sCryptoType == "IRM")
{
- mEngine.reset(new IRMEngine);
+ mEngine.reset(new IRMEngine(mxContext));
}
else if (sCryptoType == "Standard" || sCryptoType == "Agile")
{
- mEngine.reset(new Standard2007Engine);
+ mEngine.reset(new Standard2007Engine(mxContext));
}
else
{
diff --git a/oox/source/crypto/IRMEngine.cxx b/oox/source/crypto/IRMEngine.cxx
index 6f531b2a1c14..1301a3b51279 100644
--- a/oox/source/crypto/IRMEngine.cxx
+++ b/oox/source/crypto/IRMEngine.cxx
@@ -29,6 +29,7 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/SequenceInputStream.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
@@ -49,7 +50,10 @@ namespace oox
{
namespace core
{
-IRMEngine::IRMEngine() {}
+IRMEngine::IRMEngine(const Reference<XComponentContext>& rxContext)
+ : mxContext(rxContext)
+{
+}
bool IRMEngine::checkDataIntegrity() { return true; }
@@ -133,11 +137,29 @@ void IRMEngine::createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionD
aEncryptionData["license"] <<= seq;
}
-bool IRMEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage)
+uno::Reference<io::XInputStream> IRMEngine::getStream(Sequence<NamedValue>& rStreams,
+ const OUString sStreamName)
+{
+ for (const auto& aStream : rStreams)
+ {
+ if (aStream.Name == sStreamName)
+ {
+ css::uno::Sequence<sal_Int8> aSeq;
+ aStream.Value >>= aSeq;
+ Reference<XInputStream> aStream(
+ io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq),
+ UNO_QUERY_THROW);
+ return aStream;
+ }
+ }
+ return nullptr;
+}
+
+bool IRMEngine::readEncryptionInfo(uno::Sequence<beans::NamedValue> aStreams)
{
// Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4)
- uno::Reference<io::XInputStream> xTransformInfoStream = rOleStorage.openInputStream(
- "\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary");
+ uno::Reference<io::XInputStream> xTransformInfoStream
+ = getStream(aStreams, "\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary");
SAL_WARN_IF(!xTransformInfoStream.is(), "oox", "TransormInfo stream is missing!");
BinaryXInputStream aBinaryStream(xTransformInfoStream, true);
diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
index 86d9092be574..b48f6e517758 100644
--- a/oox/source/crypto/Standard2007Engine.cxx
+++ b/oox/source/crypto/Standard2007Engine.cxx
@@ -11,6 +11,7 @@
#include <oox/crypto/Standard2007Engine.hxx>
#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/SequenceInputStream.hpp>
#include <oox/crypto/CryptTools.hxx>
#include <oox/helper/binaryinputstream.hxx>
#include <oox/helper/binaryoutputstream.hxx>
@@ -44,6 +45,12 @@ constexpr const sal_uInt32 AES128Size = 16;
} // end anonymous namespace
+Standard2007Engine::Standard2007Engine(const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ : mxContext(rxContext)
+{
+
+}
+
bool Standard2007Engine::generateVerifier()
{
// only support key of size 128 bit (16 byte)
@@ -289,9 +296,24 @@ void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> & r
}
}
-bool Standard2007Engine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage)
+css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName)
+{
+ for (const auto & aStream : rStreams)
+ {
+ if (aStream.Name == sStreamName)
+ {
+ css::uno::Sequence<sal_Int8> aSeq;
+ aStream.Value >>= aSeq;
+ Reference<XInputStream> aStream(css::io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW);
+ return aStream;
+ }
+ }
+ return nullptr;
+}
+
+bool Standard2007Engine::readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams)
{
- Reference<css::io::XInputStream> rxInputStream = rOleStorage.openInputStream("EncryptionInfo");
+ Reference<css::io::XInputStream> rxInputStream = getStream(aStreams, "EncryptionInfo");
BinaryXInputStream aBinaryStream(rxInputStream, false);
aBinaryStream.readuInt32(); // Version