include/oox/crypto/AgileEngine.hxx | 40 +++++++++++++----------- include/oox/crypto/CryptoEngine.hxx | 2 - include/oox/crypto/DocumentDecryption.hxx | 3 - include/oox/crypto/IRMEngine.hxx | 3 + include/oox/crypto/Standard2007Engine.hxx | 2 - oox/source/crypto/AgileEngine.cxx | 11 ++++-- oox/source/crypto/DocumentDecryption.cxx | 50 ++++++------------------------ oox/source/crypto/DocumentEncryption.cxx | 9 ++++- oox/source/crypto/IRMEngine.cxx | 40 ++++++++++++++++++++++-- oox/source/crypto/Standard2007Engine.cxx | 6 ++- sfx2/source/dialog/filedlghelper.cxx | 3 + sw/qa/extras/inc/swmodeltestbase.hxx | 1 12 files changed, 97 insertions(+), 73 deletions(-)
New commits: commit 5a5a6d973c9bbd88d1bd6efdeefdc6bbf3043cc8 Author: Vasily Melenchuk <[email protected]> AuthorDate: Mon Sep 23 10:32:18 2019 +0300 Commit: Vasily Melenchuk <[email protected]> CommitDate: Mon Sep 23 10:21:25 2019 +0200 irm: encryption/decrypttion methods organization fixing encryption problems introduced in previous commit Change-Id: Ie03360f51b76db3fc9a4f7d343d622c6dc9fcee6 Reviewed-on: https://gerrit.libreoffice.org/79376 Reviewed-by: Vasily Melenchuk <[email protected]> Tested-by: Vasily Melenchuk <[email protected]> diff --git a/include/oox/crypto/AgileEngine.hxx b/include/oox/crypto/AgileEngine.hxx index 7a3f4788d1af..2fed653d924e 100644 --- a/include/oox/crypto/AgileEngine.hxx +++ b/include/oox/crypto/AgileEngine.hxx @@ -96,31 +96,44 @@ private: static Crypto::CryptoType cryptoType(const AgileEncryptionInfo& rInfo); -public: - AgileEngine(); + // Decryption - AgileEncryptionInfo& getInfo() { return mInfo;} + bool decryptHmacKey(); + bool decryptHmacValue(); + + AgileEncryptionInfo& getInfo() { return mInfo; } void setPreset(AgileEncryptionPreset ePreset) { meEncryptionPreset = ePreset; } - // Decryption - void decryptEncryptionKey(OUString const & rPassword); bool decryptAndCheckVerifierHash(OUString const & rPassword); + // Encryption + + bool encryptHmacKey(); + bool encryptHmacValue(); + + bool generateAndEncryptVerifierHash(OUString const & rPassword); + + bool encryptEncryptionKey(OUString const & rPassword); + void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters); + bool setupEncryptionKey(OUString const & rPassword); + +public: + AgileEngine(); + + // Decryption + bool generateEncryptionKey(OUString const & rPassword) override; - bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override; + bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; bool decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& aOutputStream) override; bool checkDataIntegrity() override; - bool decryptHmacKey(); - bool decryptHmacValue(); - // Encryption void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; @@ -132,15 +145,6 @@ public: bool setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override; virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override; - - bool generateAndEncryptVerifierHash(OUString const & rPassword); - - bool encryptHmacKey(); - bool encryptHmacValue(); - - bool encryptEncryptionKey(OUString const & rPassword); - void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters); - bool setupEncryptionKey(OUString const & rPassword); }; } // namespace core diff --git a/include/oox/crypto/CryptoEngine.hxx b/include/oox/crypto/CryptoEngine.hxx index 77cac9af1c3b..7b97083a1ee4 100644 --- a/include/oox/crypto/CryptoEngine.hxx +++ b/include/oox/crypto/CryptoEngine.hxx @@ -41,7 +41,7 @@ public: {} // Decryption - virtual bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) = 0; + virtual bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) = 0; virtual bool generateEncryptionKey(const OUString& rPassword) = 0; diff --git a/include/oox/crypto/DocumentDecryption.hxx b/include/oox/crypto/DocumentDecryption.hxx index 42a4c413ff18..791a119b0c6d 100644 --- a/include/oox/crypto/DocumentDecryption.hxx +++ b/include/oox/crypto/DocumentDecryption.hxx @@ -39,8 +39,7 @@ private: std::unique_ptr<CryptoEngine> mEngine; OUString msEngineName; - bool readStrongEncryptionInfo(); - bool readIRMEncryptionInfo(); + void readStrongEncryptionInfo(); public: DocumentDecryption(oox::ole::OleStorage& rOleStorage); diff --git a/include/oox/crypto/IRMEngine.hxx b/include/oox/crypto/IRMEngine.hxx index 3aadee705c2c..bd2cc44b0a69 100644 --- a/include/oox/crypto/IRMEngine.hxx +++ b/include/oox/crypto/IRMEngine.hxx @@ -30,6 +30,7 @@ namespace core struct OOX_DLLPUBLIC IRMEncryptionInfo { OString license; + bool bCanRead; }; class OOX_DLLPUBLIC IRMEngine : public CryptoEngine @@ -39,7 +40,7 @@ class OOX_DLLPUBLIC IRMEngine : public CryptoEngine public: IRMEngine(); - bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream>& rxInputStream) override; + bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; virtual bool generateEncryptionKey(OUString const& rPassword) override; diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx index 7bec4e5f7aee..580fe88295f5 100644 --- a/include/oox/crypto/Standard2007Engine.hxx +++ b/include/oox/crypto/Standard2007Engine.hxx @@ -35,7 +35,7 @@ class OOX_DLLPUBLIC Standard2007Engine : public CryptoEngine public: Standard2007Engine() = default; - bool readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) override; + bool readEncryptionInfo(oox::ole::OleStorage& rOleStorage) override; virtual bool generateEncryptionKey(OUString const & rPassword) override; diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx index 5192ae905723..624048a4839a 100644 --- a/oox/source/crypto/AgileEngine.cxx +++ b/oox/source/crypto/AgileEngine.cxx @@ -485,14 +485,19 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream, return true; } -bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputStream) +bool AgileEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage) { + uno::Reference<io::XInputStream> xEncryptionInfo = rOleStorage.openInputStream("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)); - rxInputStream->readBytes(aReadReservedBytes, aReadReservedBytes.getLength()); + xEncryptionInfo->readBytes(aReadReservedBytes, aReadReservedBytes.getLength()); if (!std::equal(aReadReservedBytes.begin(), aReadReservedBytes.end(), aExpectedReservedBytes.begin())) return false; @@ -512,7 +517,7 @@ bool AgileEngine::readEncryptionInfo(uno::Reference<io::XInputStream> & rxInputS xParser->setTokenHandler(xFastTokenHandler); InputSource aInputSource; - aInputSource.aInputStream = rxInputStream; + aInputSource.aInputStream = xEncryptionInfo; xParser->parseStream(aInputSource); // CHECK info data diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx index 187522ee4a06..800cc5436a13 100644 --- a/oox/source/crypto/DocumentDecryption.cxx +++ b/oox/source/crypto/DocumentDecryption.cxx @@ -39,7 +39,7 @@ bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword) return false; } -bool DocumentDecryption::readStrongEncryptionInfo() +void DocumentDecryption::readStrongEncryptionInfo() { uno::Reference<io::XInputStream> xEncryptionInfo = mrOleStorage.openInputStream("EncryptionInfo"); @@ -60,41 +60,6 @@ bool DocumentDecryption::readStrongEncryptionInfo() default: break; } - if (mEngine) - return mEngine->readEncryptionInfo(xEncryptionInfo); - return false; -} - -bool DocumentDecryption::readIRMEncryptionInfo() -{ - // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4) - uno::Reference<io::XInputStream> xTransformInfoStream = mrOleStorage.openInputStream("\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary"); - SAL_WARN_IF(!xTransformInfoStream.is(), "oox", "TransormInfo stream is missing!"); - BinaryXInputStream aBinaryStream(xTransformInfoStream, true); - - // MS-OFFCRYPTO 2.1.8: TransformInfoHeader - aBinaryStream.readuInt32(); // TransformLength - aBinaryStream.readuInt32(); // TransformType - // TransformId - sal_uInt32 aStringLength = aBinaryStream.readuInt32(); - OUString sTransformId = aBinaryStream.readUnicodeArray(aStringLength / 2); - aBinaryStream.skip((4 - (aStringLength & 3)) & 3); // Skip padding - - // TransformName - aStringLength = aBinaryStream.readuInt32(); - OUString sTransformName = aBinaryStream.readUnicodeArray(aStringLength / 2); - aBinaryStream.skip((4 - (aStringLength & 3)) & 3); // Skip padding - - aBinaryStream.readuInt32(); // ReaderVersion - aBinaryStream.readuInt32(); // UpdaterVersion - aBinaryStream.readuInt32(); // WriterVersion - - // MS-OFFCRYPTO 2.2.5: ExtensibilityHeader - aBinaryStream.readuInt32(); // ExtensibilityHeader - - msEngineName = "IRM"; // Set encryption info format - mEngine.reset(new IRMEngine); - return mEngine->readEncryptionInfo(xTransformInfoStream); } bool DocumentDecryption::readEncryptionInfo() @@ -136,7 +101,8 @@ bool DocumentDecryption::readEncryptionInfo() if (sDataSpaceName == "DRMEncryptedDataSpace") { - return readIRMEncryptionInfo(); + msEngineName = "IRM"; // Set encryption info format + mEngine.reset(new IRMEngine); } else if (sDataSpaceName == "\011DRMDataSpace") // 0x09DRMDataSpace { @@ -144,7 +110,7 @@ bool DocumentDecryption::readEncryptionInfo() } else if (sDataSpaceName == "StrongEncryptionDataSpace") { - return readStrongEncryptionInfo(); + readStrongEncryptionInfo(); } else { @@ -156,9 +122,13 @@ bool DocumentDecryption::readEncryptionInfo() // 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"); - return readStrongEncryptionInfo(); + readStrongEncryptionInfo(); } - return false; + + if (!mEngine) + return false; + + return mEngine->readEncryptionInfo(mrOleStorage); } uno::Sequence<beans::NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword) diff --git a/oox/source/crypto/DocumentEncryption.cxx b/oox/source/crypto/DocumentEncryption.cxx index 5fab856c0c18..6975572193d5 100644 --- a/oox/source/crypto/DocumentEncryption.cxx +++ b/oox/source/crypto/DocumentEncryption.cxx @@ -45,16 +45,23 @@ DocumentEncryption::DocumentEncryption(Reference<XStream> const & xDocumentStrea { mEngine.reset(new IRMEngine); } - else + else if (sCryptoType == "Standard" || sCryptoType == "Agile") { mEngine.reset(new Standard2007Engine); } + else + { + SAL_WARN("oox", "Requested encryption method \"" << sCryptoType << "\" is not supported"); + } } } } bool DocumentEncryption::encrypt() { + if (!mEngine) + return false; + Reference<XInputStream> xInputStream (mxDocumentStream->getInputStream(), UNO_SET_THROW); Reference<XSeekable> xSeekable(xInputStream, UNO_QUERY); diff --git a/oox/source/crypto/IRMEngine.cxx b/oox/source/crypto/IRMEngine.cxx index 94bcc773333e..6f531b2a1c14 100644 --- a/oox/source/crypto/IRMEngine.cxx +++ b/oox/source/crypto/IRMEngine.cxx @@ -75,6 +75,15 @@ bool IRMEngine::decrypt(BinaryXInputStream& aInputStream, BinaryXOutputStream& a // TODO: some reaction? } + // Read rights + BOOL value; + hr = IpcAccessCheck(key, IPC_GENERIC_READ, &value); + if (FAILED(hr)) + { + // TODO: some reaction? + } + mInfo.bCanRead = value; + // Get size of decrypt block DWORD* blockSize; hr = IpcGetKeyProperty(key, IPC_KI_BLOCK_SIZE, nullptr, (LPVOID*)&blockSize); @@ -124,11 +133,36 @@ void IRMEngine::createEncryptionData(comphelper::SequenceAsHashMap& aEncryptionD aEncryptionData["license"] <<= seq; } -bool IRMEngine::readEncryptionInfo(uno::Reference<io::XInputStream>& rxInputStream) +bool IRMEngine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage) { - // MS-OFFCRYPTO 2.2.6: XrMLLicense - BinaryXInputStream aBinaryStream(rxInputStream, true); + // Read TransformInfo storage for IRM ECMA documents (MS-OFFCRYPTO 2.2.4) + uno::Reference<io::XInputStream> xTransformInfoStream = rOleStorage.openInputStream( + "\006DataSpaces/TransformInfo/DRMEncryptedTransform/\006Primary"); + SAL_WARN_IF(!xTransformInfoStream.is(), "oox", "TransormInfo stream is missing!"); + BinaryXInputStream aBinaryStream(xTransformInfoStream, true); + + // MS-OFFCRYPTO 2.1.8: TransformInfoHeader + aBinaryStream.readuInt32(); // TransformLength + aBinaryStream.readuInt32(); // TransformType + // TransformId sal_uInt32 aStringLength = aBinaryStream.readuInt32(); + OUString sTransformId = aBinaryStream.readUnicodeArray(aStringLength / 2); + aBinaryStream.skip((4 - (aStringLength & 3)) & 3); // Skip padding + + // TransformName + aStringLength = aBinaryStream.readuInt32(); + OUString sTransformName = aBinaryStream.readUnicodeArray(aStringLength / 2); + aBinaryStream.skip((4 - (aStringLength & 3)) & 3); // Skip padding + + aBinaryStream.readuInt32(); // ReaderVersion + aBinaryStream.readuInt32(); // UpdaterVersion + aBinaryStream.readuInt32(); // WriterVersion + + // MS-OFFCRYPTO 2.2.5: ExtensibilityHeader + aBinaryStream.readuInt32(); // ExtensibilityHeader + + // MS-OFFCRYPTO 2.2.6: XrMLLicense + aStringLength = aBinaryStream.readuInt32(); mInfo.license = aBinaryStream.readCharArray(aStringLength); if (mInfo.license.getLength() diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx index 05d569c32cec..86d9092be574 100644 --- a/oox/source/crypto/Standard2007Engine.cxx +++ b/oox/source/crypto/Standard2007Engine.cxx @@ -215,7 +215,7 @@ bool Standard2007Engine::setupEncryption(css::uno::Sequence<css::beans::NamedVal OUString sPassword; for (int i = 0; i < rMediaEncData.getLength(); i++) { - if (rMediaEncData[i].Name == "Password") + if (rMediaEncData[i].Name == "OOXPassword") { OUString sCryptoType; rMediaEncData[i].Value >>= sPassword; @@ -289,9 +289,11 @@ void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> & r } } -bool Standard2007Engine::readEncryptionInfo(css::uno::Reference<css::io::XInputStream> & rxInputStream) +bool Standard2007Engine::readEncryptionInfo(oox::ole::OleStorage& rOleStorage) { + Reference<css::io::XInputStream> rxInputStream = rOleStorage.openInputStream("EncryptionInfo"); BinaryXInputStream aBinaryStream(rxInputStream, false); + aBinaryStream.readuInt32(); // Version mInfo.header.flags = aBinaryStream.readuInt32(); if (getFlag(mInfo.header.flags, msfilter::ENCRYPTINFO_EXTERNAL)) diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index 1b6b04db197e..11a4d2b7e9ab 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -2701,7 +2701,8 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter, if ( lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName() ) ) { ::comphelper::SequenceAsHashMap aHashData; - aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword(); + aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword(); + aHashData[ OUString( "CryptoType" ) ] <<= OUString( "Standard" ); pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) ); } else diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index 23cc46af3016..b91015956b36 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -792,6 +792,7 @@ protected: { OUString sPassword = OUString::createFromAscii(pPassword); css::uno::Sequence<css::beans::NamedValue> aEncryptionData { + { "CryptoType", css::uno::makeAny(OUString("Standard")) }, { "OOXPassword", css::uno::makeAny(sPassword) } }; aMediaDescriptor[utl::MediaDescriptor::PROP_ENCRYPTIONDATA()] <<= aEncryptionData; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
