diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2020-01-03 22:40:07 +0300 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-02-10 16:19:00 +0100 |
commit | 2cd3632ac93169ad3c082ff4fb740c3d3dfff071 (patch) | |
tree | 1873d65e9387e0ce91e2c5f18c404930d5bd4a4d /comphelper | |
parent | edde4a76a66fb897c8fb49e72258dc8707b90788 (diff) |
tdf#93389: keep encryption information for autorecovered MS formats
The autorecovery data is stored in ODF, regardless of the original
document format. When restoring, type detection generates ODF data,
which is stored in the media descriptor attached to document, even
after real filter was restored (see AutoRecovery::implts_openDocs).
If real filter is not ODF, then at the save time, it doesn't find
necessary information in encryption data, and makes not encrypted
package.
This patch adds both MS binary data, and OOXML data, to existing
ODF data for recovered password-protected documents (regardless of
their real filter).
TODO: only add required information to encryption data: pass real
filter name to DocPasswordHelper::requestAndVerifyDocPassword from
AutoRecovery::implts_openDocs.
Change-Id: I4749c5ec028ca61bddf7cd77bc5969a97b1de199
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86201
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit dd198398b6e5c84ab1255a90ef96e6445b66a64f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86353
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/misc/docpasswordhelper.cxx | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/comphelper/source/misc/docpasswordhelper.cxx b/comphelper/source/misc/docpasswordhelper.cxx index d57447580bce..79c0e9a6b66a 100644 --- a/comphelper/source/misc/docpasswordhelper.cxx +++ b/comphelper/source/misc/docpasswordhelper.cxx @@ -25,6 +25,7 @@ #include <comphelper/storagehelper.hxx> #include <comphelper/hash.hxx> #include <comphelper/base64.hxx> +#include <comphelper/propertysequence.hxx> #include <comphelper/sequence.hxx> #include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/beans/PropertyValue.hpp> @@ -423,6 +424,25 @@ OUString DocPasswordHelper::GetOoxHashAsBase64( OUString aPassword; DocPasswordVerifierResult eResult = DocPasswordVerifierResult::WrongPassword; + sal_Int32 nMediaEncDataCount = rMediaEncData.getLength(); + + // tdf#93389: if the document is being restored from autorecovery, we need to add encryption + // data also for real document type. + // TODO: get real filter name here (from CheckPasswd_Impl), to only add necessary data + bool bForSalvage = false; + if (nMediaEncDataCount) + { + for (auto& val : rMediaEncData) + { + if (val.Name == "ForSalvage") + { + --nMediaEncDataCount; // don't consider this element below + val.Value >>= bForSalvage; + break; + } + } + } + // first, try provided default passwords if( pbIsDefaultPassword ) *pbIsDefaultPassword = false; @@ -449,7 +469,7 @@ OUString DocPasswordHelper::GetOoxHashAsBase64( // try media encryption data (skip, if result is OK or ABORT) if( eResult == DocPasswordVerifierResult::WrongPassword ) { - if( rMediaEncData.hasElements() ) + if (nMediaEncDataCount) { eResult = rVerifier.verifyEncryptionData( rMediaEncData ); if( eResult == DocPasswordVerifierResult::OK ) @@ -508,6 +528,26 @@ OUString DocPasswordHelper::GetOoxHashAsBase64( aEncData = comphelper::concatSequences( aEncData, OStorageHelper::CreatePackageEncryptionData(aPassword)); } + + if (bForSalvage) + { + // TODO: add individual methods for different target filter, and only call what's needed + + // 1. Prepare binary MS formats encryption data + auto aUniqueID = GenerateRandomByteSequence(16); + auto aEnc97Key = GenerateStd97Key(aPassword.getStr(), aUniqueID); + // 2. Add MS binary and OOXML encryption data to result + uno::Sequence< beans::NamedValue > aContainer(3); + aContainer[0].Name = "STD97EncryptionKey"; + aContainer[0].Value <<= aEnc97Key; + aContainer[1].Name = "STD97UniqueID"; + aContainer[1].Value <<= aUniqueID; + aContainer[2].Name = "OOXPassword"; + aContainer[2].Value <<= aPassword; + + aEncData = comphelper::concatSequences( + aEncData, aContainer); + } } return (eResult == DocPasswordVerifierResult::OK) ? aEncData : uno::Sequence< beans::NamedValue >(); |