[Libreoffice-commits] core.git: Branch 'libreoffice-5-4' - filter/source include/filter

Caolán McNamara caolanm at redhat.com
Tue Jan 30 15:32:43 UTC 2018


 filter/source/msfilter/mscodec.cxx  |   25 +++++++++++++++++++------
 include/filter/msfilter/mscodec.hxx |    8 ++++++--
 2 files changed, 25 insertions(+), 8 deletions(-)

New commits:
commit 82e74f704ce4fe3ffe7ab74c14fe83d2d44dd088
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jan 26 10:47:24 2018 +0000

    Resolves: tdf#114221 generate both std97 and cryptoapi keys from password..
    
    when we open a cryptoapi encrypted binary msoffice document. That way when we
    save as the same format, and try to reuse the generated keys for encryption, we
    have matching std97 encryption keys available because we always export using
    that scheme.
    
    Change-Id: I25f24a01d102242615768255ce888acb08ef6447
    Reviewed-on: https://gerrit.libreoffice.org/48712
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit b5914ba44f2fff9f282b6a5cbe21cbebf19e45b2)
    Reviewed-on: https://gerrit.libreoffice.org/48914

diff --git a/filter/source/msfilter/mscodec.cxx b/filter/source/msfilter/mscodec.cxx
index 83dee6c37223..837916508d50 100644
--- a/filter/source/msfilter/mscodec.cxx
+++ b/filter/source/msfilter/mscodec.cxx
@@ -244,8 +244,9 @@ void MSCodec_Xor95::Skip( std::size_t nBytes )
     mnOffset = (mnOffset + nBytes) & 0x0F;
 }
 
-MSCodec97::MSCodec97(size_t nHashLen)
-    : m_nHashLen(nHashLen)
+MSCodec97::MSCodec97(size_t nHashLen, const OUString& rEncKeyName)
+    : m_sEncKeyName(rEncKeyName)
+    , m_nHashLen(nHashLen)
     , m_hCipher(rtl_cipher_create(rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream))
     , m_aDocId(16, 0)
     , m_aDigestValue(nHashLen, 0)
@@ -254,14 +255,14 @@ MSCodec97::MSCodec97(size_t nHashLen)
 }
 
 MSCodec_Std97::MSCodec_Std97()
-    : MSCodec97(RTL_DIGEST_LENGTH_MD5)
+    : MSCodec97(RTL_DIGEST_LENGTH_MD5, "STD97EncryptionKey")
 {
     m_hDigest = rtl_digest_create(rtl_Digest_AlgorithmMD5);
     assert(m_hDigest != nullptr);
 }
 
 MSCodec_CryptoAPI::MSCodec_CryptoAPI()
-    : MSCodec97(RTL_DIGEST_LENGTH_SHA1)
+    : MSCodec97(RTL_DIGEST_LENGTH_SHA1, "CryptoAPIEncryptionKey")
 {
 }
 
@@ -299,7 +300,7 @@ bool MSCodec97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
     bool bResult = false;
 
     ::comphelper::SequenceAsHashMap aHashData( aData );
-    uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault("STD97EncryptionKey", uno::Sequence< sal_Int8 >() );
+    uno::Sequence<sal_Int8> aKey = aHashData.getUnpackedValueOrDefault(m_sEncKeyName, uno::Sequence<sal_Int8>());
     const size_t nKeyLen = aKey.getLength();
     if (nKeyLen == m_nHashLen)
     {
@@ -327,7 +328,7 @@ uno::Sequence< beans::NamedValue > MSCodec97::GetEncryptionData()
 {
     ::comphelper::SequenceAsHashMap aHashData;
     assert(m_aDigestValue.size() == m_nHashLen);
-    aHashData[ OUString( "STD97EncryptionKey" ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast<sal_Int8*>(m_aDigestValue.data()), m_nHashLen );
+    aHashData[m_sEncKeyName] <<= uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8*>(m_aDigestValue.data()), m_nHashLen);
     aHashData[ OUString( "STD97UniqueID" ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast<sal_Int8*>(m_aDocId.data()), m_aDocId.size() );
 
     return aHashData.getAsConstNamedValueList();
@@ -380,6 +381,9 @@ void MSCodec_CryptoAPI::InitKey (
     (void)memcpy(m_aDocId.data(), pDocId, 16);
 
     lcl_PrintDigest(m_aDocId.data(), "DocId value");
+
+    //generate the old format key while we have the required data
+    m_aStd97Key = ::comphelper::DocPasswordHelper::GenerateStd97Key(pPassData, pDocId);
 }
 
 bool MSCodec97::VerifyKey(const sal_uInt8* pSaltData, const sal_uInt8* pSaltDigest)
@@ -477,6 +481,15 @@ bool MSCodec_CryptoAPI::InitCipher(sal_uInt32 nCounter)
     return (result == rtl_Cipher_E_None);
 }
 
+uno::Sequence<beans::NamedValue> MSCodec_CryptoAPI::GetEncryptionData()
+{
+    ::comphelper::SequenceAsHashMap aHashData(MSCodec97::GetEncryptionData());
+    //add in the old encryption key as well as our new key so saving using the
+    //old crypto scheme can be done without reprompt for the password
+    aHashData[OUString("STD97EncryptionKey")] <<= m_aStd97Key;
+    return aHashData.getAsConstNamedValueList();
+}
+
 void MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
 {
 #if DEBUG_MSO_ENCRYPTION_STD97
diff --git a/include/filter/msfilter/mscodec.hxx b/include/filter/msfilter/mscodec.hxx
index b0ab818449ae..aa38f6e9fc00 100644
--- a/include/filter/msfilter/mscodec.hxx
+++ b/include/filter/msfilter/mscodec.hxx
@@ -178,7 +178,7 @@ public:
 class MSFILTER_DLLPUBLIC MSCodec97
 {
 public:
-    MSCodec97(size_t nHashLen);
+    MSCodec97(size_t nHashLen, const OUString& rEncKeyName);
     virtual ~MSCodec97();
 
     /** Initializes the algorithm with the encryption data.
@@ -195,7 +195,7 @@ public:
             The sequence contains the necessary data to initialize
             the codec.
      */
-    css::uno::Sequence< css::beans::NamedValue > GetEncryptionData();
+    virtual css::uno::Sequence<css::beans::NamedValue> GetEncryptionData();
 
     /** Initializes the algorithm with the specified password and document ID.
 
@@ -317,6 +317,7 @@ private:
     MSCodec97&          operator=(const MSCodec97&) = delete;
 
 protected:
+    OUString            m_sEncKeyName;
     size_t              m_nHashLen;
     rtlCipher           m_hCipher;
     std::vector<sal_uInt8> m_aDocId;
@@ -396,6 +397,8 @@ private:
 
 class MSFILTER_DLLPUBLIC MSCodec_CryptoAPI :  public MSCodec97
 {
+private:
+    css::uno::Sequence<sal_Int8> m_aStd97Key;
 public:
     MSCodec_CryptoAPI();
 
@@ -403,6 +406,7 @@ public:
                          const sal_uInt8 pDocId[16]) override;
     virtual bool InitCipher(sal_uInt32 nCounter) override;
     virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) override;
+    virtual css::uno::Sequence<css::beans::NamedValue> GetEncryptionData() override;
 };
 
 const sal_uInt32 ENCRYPTINFO_CRYPTOAPI      = 0x00000004;


More information about the Libreoffice-commits mailing list