diff options
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/core/filterdetect.cxx | 8 | ||||
-rw-r--r-- | oox/source/core/xmlfilterbase.cxx | 2 | ||||
-rw-r--r-- | oox/source/crypto/AgileEngine.cxx | 129 | ||||
-rw-r--r-- | oox/source/crypto/CryptTools.cxx | 4 | ||||
-rw-r--r-- | oox/source/crypto/DocumentDecryption.cxx | 59 | ||||
-rw-r--r-- | oox/source/crypto/DocumentEncryption.cxx | 6 | ||||
-rw-r--r-- | oox/source/crypto/Standard2007Engine.cxx | 123 | ||||
-rw-r--r-- | oox/source/crypto/StrongEncryptionDataSpace.cxx | 189 |
8 files changed, 257 insertions, 263 deletions
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index 9cd0bf3199ea..e5e461173102 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -250,16 +250,16 @@ bool lclIsZipPackage( const Reference< XComponentContext >& rxContext, const Ref class PasswordVerifier : public IDocPasswordVerifier { public: - explicit PasswordVerifier( DocumentDecryption& aDecryptor ); + explicit PasswordVerifier( crypto::DocumentDecryption& aDecryptor ); virtual DocPasswordVerifierResult verifyPassword( const OUString& rPassword, Sequence<NamedValue>& rEncryptionData ) override; virtual DocPasswordVerifierResult verifyEncryptionData( const Sequence<NamedValue>& rEncryptionData ) override; private: - DocumentDecryption& mDecryptor; + crypto::DocumentDecryption& mDecryptor; }; -PasswordVerifier::PasswordVerifier( DocumentDecryption& aDecryptor ) : +PasswordVerifier::PasswordVerifier( crypto::DocumentDecryption& aDecryptor ) : mDecryptor(aDecryptor) {} @@ -308,7 +308,7 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript { try { - DocumentDecryption aDecryptor(mxContext, aOleStorage); + crypto::DocumentDecryption aDecryptor(mxContext, aOleStorage); if( aDecryptor.readEncryptionInfo() ) { diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index b52e6a0d9a28..5c99e70e7c82 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -909,7 +909,7 @@ bool XmlFilterBase::implFinalizeExport( MediaDescriptor& rMediaDescriptor ) Reference< XStream> xDocumentStream (FilterBase::implGetOutputStream(rMediaDescriptor)); oox::ole::OleStorage aOleStorage( getComponentContext(), xDocumentStream, true ); - DocumentEncryption encryptor( getComponentContext(), getMainDocumentStream(), aOleStorage, aMediaEncData ); + crypto::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 54dd841ef2bf..eb4edd709739 100644 --- a/oox/source/crypto/AgileEngine.cxx +++ b/oox/source/crypto/AgileEngine.cxx @@ -21,7 +21,6 @@ #include <comphelper/processfactory.hxx> #include <comphelper/base64.hxx> #include <comphelper/sequence.hxx> -#include <comphelper/sequenceashashmap.hxx> #include <filter/msfilter/mscodec.hxx> #include <tools/stream.hxx> @@ -29,8 +28,6 @@ #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/io/XSequenceOutputStream.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> @@ -46,15 +43,7 @@ using namespace css::xml::sax; using namespace css::xml; namespace oox { -namespace core { - -extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* - com_sun_star_comp_oox_crypto_Agile_get_implementation( - XComponentContext* pCtx, Sequence<Any> const& /*arguments*/) -{ - return cppu::acquire(new AgileEngine(pCtx/*, arguments*/)); -} - +namespace crypto { namespace { @@ -160,13 +149,13 @@ public: comphelper::Base64::decode(encryptedKeyValue, rAttribute.Value); mInfo.encryptedKeyValue = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(encryptedKeyValue); } - else if (rAttrLocalName == "encryptedHmacKey") + if (rAttrLocalName == "encryptedHmacKey") { Sequence<sal_Int8> aValue; comphelper::Base64::decode(aValue, rAttribute.Value); mInfo.hmacEncryptedKey = comphelper::sequenceToContainer<std::vector<sal_uInt8>>(aValue); } - else if (rAttrLocalName == "encryptedHmacValue") + if (rAttrLocalName == "encryptedHmacValue") { Sequence<sal_Int8> aValue; comphelper::Base64::decode(aValue, rAttribute.Value); @@ -230,9 +219,8 @@ CryptoHashType cryptoHashTypeFromString(OUString const & sAlgorithm) } // namespace -AgileEngine::AgileEngine(const Reference< XComponentContext >& rxContext) : - meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512), - mxContext(rxContext) +AgileEngine::AgileEngine() + : meEncryptionPreset(AgileEncryptionPreset::AES_256_SHA512) {} Crypto::CryptoType AgileEngine::cryptoType(const AgileEncryptionInfo& rInfo) @@ -359,7 +347,7 @@ void AgileEngine::decryptEncryptionKey(OUString const & rPassword) } // TODO: Rename -sal_Bool AgileEngine::generateEncryptionKey(OUString const & rPassword) +bool AgileEngine::generateEncryptionKey(OUString const & rPassword) { bool bResult = decryptAndCheckVerifierHash(rPassword); @@ -423,7 +411,7 @@ bool AgileEngine::decryptHmacValue() return true; } -sal_Bool AgileEngine::checkDataIntegrity() +bool AgileEngine::checkDataIntegrity() { bool bResult = (mInfo.hmacHash.size() == mInfo.hmacCalculatedHash.size() && std::equal(mInfo.hmacHash.begin(), mInfo.hmacHash.end(), mInfo.hmacCalculatedHash.begin())); @@ -431,14 +419,11 @@ sal_Bool AgileEngine::checkDataIntegrity() return bResult; } -sal_Bool AgileEngine::decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, - css::uno::Reference<css::io::XOutputStream>& rxOutputStream) +bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, + BinaryXOutputStream& aOutputStream) { CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm)); - BinaryXInputStream aInputStream(rxInputStream, true); - BinaryXOutputStream aOutputStream(rxOutputStream, true); - sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes // account for size in HMAC std::vector<sal_uInt8> aSizeBytes(sizeof(sal_uInt32)); @@ -496,39 +481,17 @@ sal_Bool AgileEngine::decrypt(const css::uno::Reference<css::io::XInputStream>& mInfo.hmacCalculatedHash = aCryptoHash.finalize(); - rxOutputStream->flush(); - return true; } -uno::Reference<io::XInputStream> AgileEngine::getStream(const Sequence<NamedValue> & rStreams, const OUString sStreamName) +bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputStream) { - 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; -} - -sal_Bool AgileEngine::readEncryptionInfo(const Sequence<NamedValue>& aStreams) -{ - uno::Reference<io::XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo"); - - BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true); - aBinaryInputStream.readuInt32(); // Version - // Check reserved value std::vector<sal_uInt8> aExpectedReservedBytes(sizeof(sal_uInt32)); ByteOrderConverter::writeLittleEndian(aExpectedReservedBytes.data(), msfilter::AGILE_ENCRYPTION_RESERVED); uno::Sequence<sal_Int8> aReadReservedBytes(sizeof(sal_uInt32)); - xEncryptionInfo->readBytes(aReadReservedBytes, aReadReservedBytes.getLength()); + rxInputStream->readBytes(aReadReservedBytes, aReadReservedBytes.getLength()); if (!std::equal(aReadReservedBytes.begin(), aReadReservedBytes.end(), aExpectedReservedBytes.begin())) return false; @@ -548,7 +511,7 @@ sal_Bool AgileEngine::readEncryptionInfo(const Sequence<NamedValue>& aStreams) xParser->setTokenHandler(xFastTokenHandler); InputSource aInputSource; - aInputSource.aInputStream = xEncryptionInfo; + aInputSource.aInputStream = rxInputStream; xParser->parseStream(aInputSource); // CHECK info data @@ -620,7 +583,7 @@ bool AgileEngine::encryptHmacKey() return false; // Encrypted salt must be multiple of block size - sal_Int32 nEncryptedSaltSize = oox::core::roundUp(mInfo.hashSize, mInfo.blockSize); + sal_Int32 nEncryptedSaltSize = oox::crypto::roundUp(mInfo.hashSize, mInfo.blockSize); // We need to extend hmacSalt to multiple of block size, padding with 0x36 std::vector<sal_uInt8> extendedSalt(mInfo.hmacKey); @@ -696,33 +659,14 @@ bool AgileEngine::encryptEncryptionKey(OUString const & rPassword) return true; } -sal_Bool AgileEngine::setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) +bool AgileEngine::setupEncryption(OUString const & rPassword) { if (meEncryptionPreset == AgileEncryptionPreset::AES_128_SHA1) setupEncryptionParameters({ 100000, 16, 128, 20, 16, OUString("AES"), OUString("ChainingModeCBC"), OUString("SHA1") }); else setupEncryptionParameters({ 100000, 16, 256, 64, 16, OUString("AES"), OUString("ChainingModeCBC"), OUString("SHA512") }); - OUString sPassword; - for (int i = 0; i < rMediaEncData.getLength(); i++) - { - if (rMediaEncData[i].Name == "OOXPassword") - { - OUString sCryptoType; - rMediaEncData[i].Value >>= sPassword; - } - } - - return setupEncryptionKey(sPassword); -} - -uno::Sequence<beans::NamedValue> AgileEngine::createEncryptionData(const OUString & rPassword) -{ - comphelper::SequenceAsHashMap aEncryptionData; - aEncryptionData["OOXPassword"] <<= rPassword; - aEncryptionData["CryptoType"] <<= OUString("AgileEngine"); - - return aEncryptionData.getAsConstNamedValueList(); + return setupEncryptionKey(rPassword); } void AgileEngine::setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters) @@ -756,13 +700,8 @@ bool AgileEngine::setupEncryptionKey(OUString const & rPassword) return true; } -css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptionInfo() +void AgileEngine::writeEncryptionInfo(BinaryXOutputStream & rStream) { - Reference<XOutputStream> aEncryptionInfoStream( - mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext), - UNO_QUERY); - BinaryXOutputStream rStream(aEncryptionInfoStream, false); - rStream.WriteUInt32(msfilter::VERSION_INFO_AGILE); rStream.WriteUInt32(msfilter::AGILE_ENCRYPTION_RESERVED); @@ -816,29 +755,19 @@ css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptionInfo() aXmlWriter.endDocument(); } rStream.writeMemory(aMemStream.GetData(), aMemStream.GetSize()); - - rStream.close(); - aEncryptionInfoStream->flush(); - - Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); - return aEncryptionInfoSequenceStream->getWrittenBytes(); } -css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptedDocument(const css::uno::Reference<css::io::XInputStream>& rxInputStream) +void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream, + css::uno::Reference<css::io::XOutputStream> & rxOutputStream, + sal_uInt32 nSize) { CryptoHash aCryptoHash(mInfo.hmacKey, cryptoHashTypeFromString(mInfo.hashAlgorithm)); - Reference<XOutputStream> aOutputStream( - mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext), - UNO_QUERY); - BinaryXOutputStream aBinaryOutputStream(aOutputStream, false); - + BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false); BinaryXInputStream aBinaryInputStream(rxInputStream, false); - Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY); - sal_uInt32 nLength = xSeekable->getLength(); std::vector<sal_uInt8> aSizeBytes(sizeof(sal_uInt32)); - ByteOrderConverter::writeLittleEndian(aSizeBytes.data(), nLength); + ByteOrderConverter::writeLittleEndian(aSizeBytes.data(), nSize); aBinaryOutputStream.writeMemory(aSizeBytes.data(), aSizeBytes.size()); // size aCryptoHash.update(aSizeBytes, aSizeBytes.size()); @@ -868,7 +797,7 @@ css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptedDocument(const css::uno: while ((inputLength = aBinaryInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0) { sal_uInt32 correctedInputLength = inputLength % mInfo.blockSize == 0 ? - inputLength : oox::core::roundUp(inputLength, sal_uInt32(mInfo.blockSize)); + inputLength : oox::crypto::roundUp(inputLength, sal_uInt32(mInfo.blockSize)); // Update Key sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&nSegment); @@ -889,21 +818,9 @@ css::uno::Sequence<sal_Int8> AgileEngine::writeEncryptedDocument(const css::uno: } mInfo.hmacHash = aCryptoHash.finalize(); encryptHmacValue(); - - Reference<XSequenceOutputStream> aSequenceStream(aOutputStream, UNO_QUERY); - return aSequenceStream->getWrittenBytes(); -} - - -css::uno::Sequence<css::beans::NamedValue> AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream) -{ - comphelper::SequenceAsHashMap aStreams; - aStreams["EncryptedPackage"] <<= writeEncryptedDocument(rxInputStream); - aStreams["EncryptionInfo"] <<= writeEncryptionInfo(); - return aStreams.getAsConstNamedValueList(); } -} // namespace core +} // namespace crypto } // namespace oox /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/crypto/CryptTools.cxx b/oox/source/crypto/CryptTools.cxx index 6ca316b0a9b6..b492d4b93975 100644 --- a/oox/source/crypto/CryptTools.cxx +++ b/oox/source/crypto/CryptTools.cxx @@ -27,7 +27,7 @@ #endif // USE_TLS_NSS namespace oox { -namespace core { +namespace crypto { #if USE_TLS_OPENSSL struct CryptoImpl @@ -481,7 +481,7 @@ std::vector<sal_uInt8> CryptoHash::finalize() return aHash; } -} // namespace core +} // namespace crypto } // namespace oox /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx index ea3ed1123532..c0ce829e70a6 100644 --- a/oox/source/crypto/DocumentDecryption.cxx +++ b/oox/source/crypto/DocumentDecryption.cxx @@ -21,6 +21,14 @@ #include <oox/ole/olestorage.hxx> #include <filter/msfilter/mscodec.hxx> +#include <com/sun/star/task/PasswordRequestMode.hpp> +#include <comphelper/docpasswordrequest.hxx> +#include <comphelper/stillreadwriteinteraction.hxx> +#include <com/sun/star/task/InteractionHandler.hpp> +#include <com/sun/star/task/PasswordContainer.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> + + namespace { void lcl_getListOfStreams(oox::StorageBase* pStorage, std::vector<OUString>& rElementNames) @@ -47,7 +55,7 @@ void lcl_getListOfStreams(oox::StorageBase* pStorage, std::vector<OUString>& rEl } namespace oox { -namespace core { +namespace crypto { using namespace css; @@ -84,33 +92,6 @@ bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword) return false; } -void DocumentDecryption::readStrongEncryptionInfo() -{ - uno::Reference<io::XInputStream> xEncryptionInfo = mrOleStorage.openInputStream("EncryptionInfo"); - - BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true); - sal_uInt32 aVersion = aBinaryInputStream.readuInt32(); - - uno::Sequence< uno::Any > aArguments; - - switch (aVersion) - { - case msfilter::VERSION_INFO_2007_FORMAT: - case msfilter::VERSION_INFO_2007_FORMAT_SP2: - mxPackageEncryption.set( - mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( - "com.sun.star.comp.oox.crypto.Standard2007Engine", aArguments, mxContext), css::uno::UNO_QUERY); - break; - case msfilter::VERSION_INFO_AGILE: - mxPackageEncryption.set( - mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( - "com.sun.star.comp.oox.crypto.AgileEngine", aArguments, mxContext), css::uno::UNO_QUERY); - break; - default: - break; - } -} - bool DocumentDecryption::readEncryptionInfo() { if (!mrOleStorage.isStorage()) @@ -118,6 +99,8 @@ bool DocumentDecryption::readEncryptionInfo() // Read 0x6DataSpaces/DataSpaceMap uno::Reference<io::XInputStream> xDataSpaceMap = mrOleStorage.openInputStream("\006DataSpaces/DataSpaceMap"); + OUString sDataSpaceName; + if (xDataSpaceMap.is()) { BinaryXInputStream aDataSpaceStream(xDataSpaceMap, true); @@ -126,7 +109,6 @@ bool DocumentDecryption::readEncryptionInfo() sal_uInt32 aEntryCount = aDataSpaceStream.readuInt32(); SAL_WARN_IF(aEntryCount != 1, "oox", "DataSpaceMap contains more than one entry. Some content may be skipped"); - OUString sDataSpaceName; // Read each DataSpaceMapEntry (MS-OFFCRYPTO 2.1.6.1) for (sal_uInt32 i = 0; i < aEntryCount; i++) { @@ -147,25 +129,20 @@ bool DocumentDecryption::readEncryptionInfo() sDataSpaceName = aDataSpaceStream.readUnicodeArray(aDataSpaceNameLength / 2); aDataSpaceStream.skip((4 - (aDataSpaceNameLength & 3)) & 3); // Skip padding } - - uno::Sequence< uno::Any > aArguments; - mxPackageEncryption.set( - mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( - "com.sun.star.comp.oox.crypto." + sDataSpaceName, aArguments, mxContext), css::uno::UNO_QUERY); - - if (!mxPackageEncryption.is() && sDataSpaceName == "StrongEncryptionDataSpace") - { - readStrongEncryptionInfo(); - } } else { // Fallback for documents generated by LO: they sometimes do not have all // required by MS-OFFCRYPTO specification streams (0x6DataSpaces/DataSpaceMap and others) SAL_WARN("oox", "Encrypted package does not contain DataSpaceMap"); - readStrongEncryptionInfo(); + sDataSpaceName = "StrongEncryptionDataSpace"; } + uno::Sequence< uno::Any > aArguments; + mxPackageEncryption.set( + mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto." + sDataSpaceName, aArguments, mxContext), css::uno::UNO_QUERY); + if (!mxPackageEncryption.is()) { // we do not know how to decrypt this document @@ -210,7 +187,7 @@ bool DocumentDecryption::decrypt(const uno::Reference<io::XStream>& xDocumentStr return bResult; } -} // namespace core +} // namespace crypto } // namespace oox /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx index 70b7f2a3a4e9..5776c8164917 100644 --- a/oox/source/crypto/DocumentEncryption.cxx +++ b/oox/source/crypto/DocumentEncryption.cxx @@ -19,7 +19,7 @@ #include <oox/ole/olestorage.hxx> namespace oox { -namespace core { +namespace crypto { using namespace css::io; using namespace css::uno; @@ -43,7 +43,7 @@ DocumentEncryption::DocumentEncryption(const Reference< XComponentContext >& rxC rMediaEncData[i].Value >>= sCryptoType; if (sCryptoType == "Standard") - sCryptoType = "Standard2007Engine"; + sCryptoType = "StrongEncryptionDataSpace"; Sequence<Any> aArguments; mxPackageEncryption.set( @@ -96,7 +96,7 @@ bool DocumentEncryption::encrypt() return true; } -} // namespace core +} // namespace crypto } // namespace oox /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx index 9ddde339b1d5..f89b29f48ccb 100644 --- a/oox/source/crypto/Standard2007Engine.cxx +++ b/oox/source/crypto/Standard2007Engine.cxx @@ -10,10 +10,6 @@ #include <oox/crypto/Standard2007Engine.hxx> -#include <com/sun/star/io/XStream.hpp> -#include <com/sun/star/io/XSeekable.hpp> -#include <com/sun/star/io/SequenceInputStream.hpp> -#include <com/sun/star/io/XSequenceOutputStream.hpp> #include <oox/crypto/CryptTools.hxx> #include <oox/helper/binaryinputstream.hxx> #include <oox/helper/binaryoutputstream.hxx> @@ -21,20 +17,9 @@ #include <rtl/random.h> #include <comphelper/hash.hxx> -#include <comphelper/sequenceashashmap.hxx> - -using namespace css::io; -using namespace css::uno; namespace oox { -namespace core { - -extern "C" SAL_DLLPUBLIC_EXPORT XInterface* - com_sun_star_comp_oox_crypto_Standard2007_get_implementation( - XComponentContext* pCtx, Sequence<Any> const& /*arguments*/) -{ - return cppu::acquire(new Standard2007Engine(pCtx/*, arguments*/)); -} +namespace crypto { /* =========================================================================== */ /* Kudos to Caolan McNamara who provided the core decryption implementations. */ @@ -54,12 +39,6 @@ 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) @@ -138,7 +117,7 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword) return true; } -sal_Bool Standard2007Engine::generateEncryptionKey(const OUString& password) +bool Standard2007Engine::generateEncryptionKey(const OUString& password) { mKey.clear(); /* @@ -180,12 +159,9 @@ sal_Bool Standard2007Engine::generateEncryptionKey(const OUString& password) return std::equal(hash.begin(), hash.end(), verifierHash.begin()); } -sal_Bool Standard2007Engine::decrypt(const css::uno::Reference<css::io::XInputStream>& rxInputStream, - css::uno::Reference<css::io::XOutputStream>& rxOutputStream) +bool Standard2007Engine::decrypt(BinaryXInputStream& aInputStream, + BinaryXOutputStream& aOutputStream) { - BinaryXInputStream aInputStream(rxInputStream, true); - BinaryXOutputStream aOutputStream(rxOutputStream, true); - sal_uInt32 totalSize = aInputStream.readuInt32(); // Document unencrypted size - 4 bytes aInputStream.skip(4); // Reserved 4 Bytes @@ -204,27 +180,15 @@ sal_Bool Standard2007Engine::decrypt(const css::uno::Reference<css::io::XInputSt aOutputStream.writeMemory(outputBuffer.data(), writeLength); remaining -= outputLength; } - - rxOutputStream->flush(); - return true; } -sal_Bool Standard2007Engine::checkDataIntegrity() +bool Standard2007Engine::checkDataIntegrity() { return true; } -css::uno::Sequence<css::beans::NamedValue> Standard2007Engine::createEncryptionData(const OUString& rPassword) -{ - comphelper::SequenceAsHashMap aEncryptionData; - aEncryptionData["OOXPassword"] <<= rPassword; - aEncryptionData["CryptoType"] <<= OUString("Standard2007Engine"); - - return aEncryptionData.getAsConstNamedValueList(); -} - -sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) +bool Standard2007Engine::setupEncryption(OUString const & password) { mInfo.header.flags = msfilter::ENCRYPTINFO_AES | msfilter::ENCRYPTINFO_CRYPTOAPI; mInfo.header.algId = msfilter::ENCRYPT_ALGO_AES128; @@ -238,17 +202,7 @@ sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans mKey.clear(); mKey.resize(keyLength, 0); - OUString sPassword; - for (int i = 0; i < rMediaEncData.getLength(); i++) - { - if (rMediaEncData[i].Name == "OOXPassword") - { - OUString sCryptoType; - rMediaEncData[i].Value >>= sPassword; - } - } - - if (!calculateEncryptionKey(sPassword)) + if (!calculateEncryptionKey(password)) return false; if (!generateVerifier()) @@ -257,13 +211,8 @@ sal_Bool Standard2007Engine::setupEncryption(const css::uno::Sequence<css::beans return true; } -css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptionInfo() +void Standard2007Engine::writeEncryptionInfo(BinaryXOutputStream& rStream) { - Reference<XOutputStream> aEncryptionInfoStream( - mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext), - UNO_QUERY); - BinaryXOutputStream rStream(aEncryptionInfoStream, false); - rStream.WriteUInt32(msfilter::VERSION_INFO_2007_FORMAT); sal_uInt32 cspNameSize = (lclCspName.getLength() * 2) + 2; @@ -279,25 +228,19 @@ css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptionInfo() rStream.WriteUInt16(0); rStream.writeMemory(&mInfo.verifier, sizeof(msfilter::EncryptionVerifierAES)); - - rStream.close(); - aEncryptionInfoStream->flush(); - - Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); - return aEncryptionInfoSequenceStream->getWrittenBytes(); } -css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptedDocument(const css::uno::Reference<css::io::XInputStream> & rxInputStream) +void Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream, + css::uno::Reference<css::io::XOutputStream> & rxOutputStream, + sal_uInt32 nSize) { - Reference<XOutputStream> aOutputStream( - mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.io.SequenceOutputStream", mxContext), - UNO_QUERY); - BinaryXOutputStream aBinaryOutputStream(aOutputStream, false); + if (mKey.empty()) + return; + BinaryXOutputStream aBinaryOutputStream(rxOutputStream, false); BinaryXInputStream aBinaryInputStream(rxInputStream, false); - Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY); - aBinaryOutputStream.WriteUInt32(xSeekable->getLength()); // size + aBinaryOutputStream.WriteUInt32(nSize); // size aBinaryOutputStream.WriteUInt32(0U); // reserved std::vector<sal_uInt8> inputBuffer(1024); @@ -317,43 +260,11 @@ css::uno::Sequence<sal_Int8> Standard2007Engine::writeEncryptedDocument(const cs outputLength = aEncryptor.update(outputBuffer, inputBuffer, inputLength); aBinaryOutputStream.writeMemory(outputBuffer.data(), outputLength); } - - Reference<XSequenceOutputStream> aSequenceStream(aOutputStream, UNO_QUERY); - return aSequenceStream->getWrittenBytes(); -} - -css::uno::Sequence<css::beans::NamedValue> Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream> & rxInputStream) -{ - if (mKey.empty()) - return css::uno::Sequence<css::beans::NamedValue>(); - - comphelper::SequenceAsHashMap aStreams; - - aStreams["EncryptedPackage"] <<= writeEncryptedDocument(rxInputStream); - aStreams["EncryptionInfo"] <<= writeEncryptionInfo(); - return aStreams.getAsConstNamedValueList(); -} - -css::uno::Reference<css::io::XInputStream> Standard2007Engine::getStream(const 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; } -sal_Bool Standard2007Engine::readEncryptionInfo(const css::uno::Sequence<css::beans::NamedValue>& aStreams) +bool Standard2007Engine::readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) { - Reference<css::io::XInputStream> rxInputStream = getStream(aStreams, "EncryptionInfo"); BinaryXInputStream aBinaryStream(rxInputStream, false); - aBinaryStream.readuInt32(); // Version mInfo.header.flags = aBinaryStream.readuInt32(); if (getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_EXTERNAL)) @@ -407,7 +318,7 @@ sal_Bool Standard2007Engine::readEncryptionInfo(const css::uno::Sequence<css::be return !aBinaryStream.isEof(); } -} // namespace core +} // namespace crypto } // namespace oox /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/crypto/StrongEncryptionDataSpace.cxx b/oox/source/crypto/StrongEncryptionDataSpace.cxx new file mode 100644 index 000000000000..c651d558794a --- /dev/null +++ b/oox/source/crypto/StrongEncryptionDataSpace.cxx @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <oox/crypto/StrongEncryptionDataSpace.hxx> +#include <oox/crypto/AgileEngine.hxx> +#include <oox/crypto/Standard2007Engine.hxx> +#include <com/sun/star/io/SequenceInputStream.hpp> +#include <com/sun/star/io/XSequenceOutputStream.hpp> + +#include <comphelper/sequenceashashmap.hxx> + +using namespace css; +using namespace css::beans; +using namespace css::io; +using namespace css::lang; +using namespace css::uno; + +namespace oox +{ +namespace crypto +{ +StrongEncryptionDataSpace::StrongEncryptionDataSpace(const Reference<XComponentContext>& rxContext) + : mxContext(rxContext) + , mCryptoEngine(new Standard2007Engine()) +{ +} + +sal_Bool StrongEncryptionDataSpace::generateEncryptionKey(const OUString& rPassword) +{ + if (!mCryptoEngine) + return false; + + return mCryptoEngine->generateEncryptionKey(rPassword); +} + +sal_Bool StrongEncryptionDataSpace::checkDataIntegrity() +{ + if (!mCryptoEngine) + return false; + + return mCryptoEngine->checkDataIntegrity(); +} + +sal_Bool StrongEncryptionDataSpace::decrypt(const Reference<XInputStream>& rxInputStream, + Reference<XOutputStream>& rxOutputStream) +{ + if (!mCryptoEngine) + return false; + + BinaryXInputStream aInputStream(rxInputStream, true); + BinaryXOutputStream aOutputStream(rxOutputStream, true); + + mCryptoEngine->decrypt(aInputStream, aOutputStream); + + rxOutputStream->flush(); + return true; +} + +Reference<XInputStream> StrongEncryptionDataSpace::getStream(const Sequence<NamedValue>& rStreams, + const OUString sStreamName) +{ + for (const auto& aStream : rStreams) + { + if (aStream.Name == sStreamName) + { + Sequence<sal_Int8> aSeq; + aStream.Value >>= aSeq; + Reference<XInputStream> aStream( + io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), + UNO_QUERY_THROW); + return aStream; + } + } + return nullptr; +} + +sal_Bool StrongEncryptionDataSpace::readEncryptionInfo(const Sequence<NamedValue>& aStreams) +{ + Reference<XInputStream> xEncryptionInfo = getStream(aStreams, "EncryptionInfo"); + if (!xEncryptionInfo.is()) + return false; + + BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true); + sal_uInt32 aVersion = aBinaryInputStream.readuInt32(); + + Sequence<Any> aArguments; + + switch (aVersion) + { + case msfilter::VERSION_INFO_2007_FORMAT: + case msfilter::VERSION_INFO_2007_FORMAT_SP2: + mCryptoEngine.reset(new Standard2007Engine()); + break; + case msfilter::VERSION_INFO_AGILE: + mCryptoEngine.reset(new AgileEngine()); + break; + default: + break; + } + + if (!mCryptoEngine) + return false; + + return mCryptoEngine->readEncryptionInfo(xEncryptionInfo); +} + +sal_Bool StrongEncryptionDataSpace::setupEncryption(const Sequence<NamedValue>& rMediaEncData) +{ + if (!mCryptoEngine) + return false; + + OUString sPassword; + for (const auto& aParam : rMediaEncData) + { + if (aParam.Name == "OOXPassword") + { + aParam.Value >>= sPassword; + } + } + + return mCryptoEngine->setupEncryption(sPassword); +} + +Sequence<NamedValue> StrongEncryptionDataSpace::createEncryptionData(const OUString& rPassword) +{ + comphelper::SequenceAsHashMap aEncryptionData; + aEncryptionData["OOXPassword"] <<= rPassword; + aEncryptionData["CryptoType"] <<= OUString("StrongEncryptionDataSpace"); + + return aEncryptionData.getAsConstNamedValueList(); +} + +Sequence<NamedValue> +StrongEncryptionDataSpace::encrypt(const Reference<XInputStream>& rxInputStream) +{ + if (!mCryptoEngine) + return Sequence<NamedValue>(); + + Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY); + if (!xSeekable.is()) + return Sequence<NamedValue>(); + + sal_uInt32 aLength = xSeekable->getLength(); // check length of the stream + + Reference<XOutputStream> xOutputStream( + mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); + + mCryptoEngine->encrypt(rxInputStream, xOutputStream, aLength); + + comphelper::SequenceAsHashMap aStreams; + + Reference<XSequenceOutputStream> xEncodedFileSequenceStream(xOutputStream, UNO_QUERY); + aStreams["EncryptedPackage"] <<= xEncodedFileSequenceStream->getWrittenBytes(); + + Reference<XOutputStream> aEncryptionInfoStream( + mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.io.SequenceOutputStream", mxContext), + UNO_QUERY); + BinaryXOutputStream rStream(aEncryptionInfoStream, false); + mCryptoEngine->writeEncryptionInfo(rStream); + aEncryptionInfoStream->flush(); + Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream, + UNO_QUERY); + + aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes(); + + return aStreams.getAsConstNamedValueList(); +} + +} // namespace crypto +} // namespace oox + +extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* +com_sun_star_comp_oox_crypto_StrongEncryptionDataSpace_get_implementation( + uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/) +{ + return cppu::acquire(new oox::crypto::StrongEncryptionDataSpace(pCtx)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |