Blame SOURCES/0004-iRelated-rhbz-1618703-Properly-handle-failure-en-dec.patch

55db36
From 9207290587ea8c8703486d60877731228eed80ce Mon Sep 17 00:00:00 2001
55db36
From: Stephan Bergmann <sbergman@redhat.com>
55db36
Date: Fri, 24 Aug 2018 10:27:01 +0200
55db36
Subject: [PATCH 4/5] iRelated rhbz#1618703: Properly handle failure
55db36
 en-/decoding PDF file
55db36
MIME-Version: 1.0
55db36
Content-Type: text/plain; charset=UTF-8
55db36
Content-Transfer-Encoding: 8bit
55db36
55db36
...when e.g. FIPS mode makes the various calls to rtl_cipher_initARCFOUR fail.
55db36
55db36
Reviewed-on: https://gerrit.libreoffice.org/59543
55db36
Tested-by: Jenkins
55db36
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
55db36
(cherry picked from commit 185a14525f114e58b48236284ed8e8644bc40e48)
55db36
Reviewed-on: https://gerrit.libreoffice.org/59573
55db36
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
55db36
Tested-by: Caolán McNamara <caolanm@redhat.com>
55db36
55db36
(cherry picked from commit 68ffc5c83ca73c58439b7c9935283541f007db44)
55db36
Conflicts:
55db36
	filter/source/pdf/impdialog.cxx
55db36
	sdext/source/pdfimport/pdfparse/pdfentries.cxx
55db36
	vcl/source/gdi/pdfwriter_impl2.cxx
55db36
55db36
Change-Id: Id1b2222249c151470e233ab814b21228f3a8b561
55db36
---
55db36
 filter/source/pdf/impdialog.cxx               |  7 +++
55db36
 .../source/pdfimport/pdfparse/pdfentries.cxx  | 42 +++++++++++-----
55db36
 vcl/source/gdi/pdfwriter_impl2.cxx            | 48 +++++++++++--------
55db36
 3 files changed, 67 insertions(+), 30 deletions(-)
55db36
55db36
diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
55db36
index 82aaf012505a..736ac0c15f26 100644
55db36
--- a/filter/source/pdf/impdialog.cxx
55db36
+++ b/filter/source/pdf/impdialog.cxx
55db36
@@ -23,6 +23,7 @@
55db36
 #include <strings.hrc>
55db36
 #include <bitmaps.hlst>
55db36
 #include <officecfg/Office/Common.hxx>
55db36
+#include <vcl/errinf.hxx>
55db36
 #include <vcl/layout.hxx>
55db36
 #include <vcl/settings.hxx>
55db36
 #include <vcl/svapp.hxx>
55db36
@@ -1351,6 +1352,12 @@ IMPL_LINK_NOARG(ImpPDFTabSecurityPage, ClickmaPbSetPwdHdl, Button*, void)
55db36
         mbHaveOwnerPassword = !aOwnerPW.isEmpty();
55db36
 
55db36
         mxPreparedPasswords = vcl::PDFWriter::InitEncryption( aOwnerPW, aUserPW, true );
55db36
+        if (!mxPreparedPasswords.is()) {
55db36
+            OUString msg;
55db36
+            ErrorHandler::GetErrorString(ERRCODE_IO_NOTSUPPORTED, msg); //TOOD: handle failure
55db36
+            ScopedVclPtrInstance<MessageDialog>(this, msg, VclMessageType::Error)->Execute();
55db36
+            return;
55db36
+        }
55db36
 
55db36
         if( mbHaveOwnerPassword )
55db36
         {
55db36
diff --git a/sdext/source/pdfimport/pdfparse/pdfentries.cxx b/sdext/source/pdfimport/pdfparse/pdfentries.cxx
55db36
index 16563868f25c..074fb669c8da 100644
55db36
--- a/sdext/source/pdfimport/pdfparse/pdfentries.cxx
55db36
+++ b/sdext/source/pdfimport/pdfparse/pdfentries.cxx
55db36
@@ -1159,9 +1159,13 @@ static bool check_user_password( const OString& rPwd, PDFFileImplData* pData )
55db36
     {
55db36
         // see PDF reference 1.4 Algorithm 3.4
55db36
         // encrypt pad string
55db36
-        rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
55db36
-                                aKey, nKeyLen,
55db36
-                                nullptr, 0 );
55db36
+        if (rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
55db36
+                                    aKey, nKeyLen,
55db36
+                                    nullptr, 0 )
55db36
+            != rtl_Cipher_E_None)
55db36
+        {
55db36
+            return false; //TODO: differentiate "failed to decrypt" from "wrong password"
55db36
+        }
55db36
         rtl_cipher_encodeARCFOUR( pData->m_aCipher, nPadString, sizeof( nPadString ),
55db36
                                   nEncryptedEntry, sizeof( nEncryptedEntry ) );
55db36
         bValid = (memcmp( nEncryptedEntry, pData->m_aUEntry, 32 ) == 0);
55db36
@@ -1172,8 +1176,12 @@ static bool check_user_password( const OString& rPwd, PDFFileImplData* pData )
55db36
         rtl_digest_updateMD5( pData->m_aDigest, nPadString, sizeof( nPadString ) );
55db36
         rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
55db36
         rtl_digest_getMD5( pData->m_aDigest, nEncryptedEntry, sizeof(nEncryptedEntry) );
55db36
-        rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
55db36
-                                aKey, sizeof(aKey), nullptr, 0 );
55db36
+        if (rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
55db36
+                                    aKey, sizeof(aKey), nullptr, 0 )
55db36
+            != rtl_Cipher_E_None)
55db36
+        {
55db36
+            return false; //TODO: differentiate "failed to decrypt" from "wrong password"
55db36
+        }
55db36
         rtl_cipher_encodeARCFOUR( pData->m_aCipher,
55db36
                                   nEncryptedEntry, 16,
55db36
                                   nEncryptedEntry, 16 ); // encrypt in place
55db36
@@ -1183,8 +1191,12 @@ static bool check_user_password( const OString& rPwd, PDFFileImplData* pData )
55db36
             for( sal_uInt32 j = 0; j < sizeof(aTempKey); j++ )
55db36
                 aTempKey[j] = static_cast<sal_uInt8>( aKey[j] ^ i );
55db36
 
55db36
-            rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
55db36
-                                    aTempKey, sizeof(aTempKey), nullptr, 0 );
55db36
+            if (rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
55db36
+                                        aTempKey, sizeof(aTempKey), nullptr, 0 )
55db36
+                != rtl_Cipher_E_None)
55db36
+            {
55db36
+                return false; //TODO: differentiate "failed to decrypt" from "wrong password"
55db36
+            }
55db36
             rtl_cipher_encodeARCFOUR( pData->m_aCipher,
55db36
                                       nEncryptedEntry, 16,
55db36
                                       nEncryptedEntry, 16 ); // encrypt in place
55db36
@@ -1230,8 +1242,12 @@ bool PDFFile::setupDecryptionData( const OString& rPwd ) const
55db36
         sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, m_pData.get(), true );
55db36
         if( m_pData->m_nStandardRevision == 2 )
55db36
         {
55db36
-            rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
55db36
-                                    aKey, nKeyLen, nullptr, 0 );
55db36
+            if (rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
55db36
+                                        aKey, nKeyLen, nullptr, 0 )
55db36
+                != rtl_Cipher_E_None)
55db36
+            {
55db36
+                return false; //TODO: differentiate "failed to decrypt" from "wrong password"
55db36
+            }
55db36
             rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
55db36
                                       m_pData->m_aOEntry, 32,
55db36
                                       nPwd, 32 );
55db36
@@ -1244,8 +1260,12 @@ bool PDFFile::setupDecryptionData( const OString& rPwd ) const
55db36
                 sal_uInt8 nTempKey[ENCRYPTION_KEY_LEN];
55db36
                 for( unsigned int j = 0; j < sizeof(nTempKey); j++ )
55db36
                     nTempKey[j] = sal_uInt8(aKey[j] ^ i);
55db36
-                rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
55db36
-                                        nTempKey, nKeyLen, nullptr, 0 );
55db36
+                if (rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
55db36
+                                            nTempKey, nKeyLen, nullptr, 0 )
55db36
+                    != rtl_Cipher_E_None)
55db36
+                {
55db36
+                    return false; //TODO: differentiate "failed to decrypt" from "wrong password"
55db36
+                }
55db36
                 rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
55db36
                                           nPwd, 32,
55db36
                                           nPwd, 32 ); // decrypt inplace
55db36
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx
55db36
index e4f567d6bfd9..e85cf15e4395 100644
55db36
--- a/vcl/source/gdi/pdfwriter_impl2.cxx
55db36
+++ b/vcl/source/gdi/pdfwriter_impl2.cxx
55db36
@@ -1443,29 +1443,39 @@ bool PDFWriterImpl::computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPass
55db36
             //Step 4, the key is in nMD5Sum
55db36
             //step 5 already done, data is in i_pPaddedUserPassword
55db36
             //step 6
55db36
-            rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode,
55db36
-                                     nMD5Sum, i_nKeyLength , nullptr, 0 );
55db36
-            // encrypt the user password using the key set above
55db36
-            rtl_cipher_encodeARCFOUR( aCipher, i_pPaddedUserPassword, ENCRYPTED_PWD_SIZE, // the data to be encrypted
55db36
-                                      &io_rOValue[0], sal_Int32(io_rOValue.size()) ); //encrypted data
55db36
-            //Step 7, only if 128 bit
55db36
-            if( i_nKeyLength == SECUR_128BIT_KEY )
55db36
+            if (rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode,
55db36
+                                        nMD5Sum, i_nKeyLength , nullptr, 0 )
55db36
+                == rtl_Cipher_E_None)
55db36
             {
55db36
-                sal_uInt32 i, y;
55db36
-                sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key
55db36
-
55db36
-                for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1
55db36
+                // encrypt the user password using the key set above
55db36
+                rtl_cipher_encodeARCFOUR( aCipher, i_pPaddedUserPassword, ENCRYPTED_PWD_SIZE, // the data to be encrypted
55db36
+                                          &io_rOValue[0], sal_Int32(io_rOValue.size()) ); //encrypted data
55db36
+                //Step 7, only if 128 bit
55db36
+                if( i_nKeyLength == SECUR_128BIT_KEY )
55db36
                 {
55db36
-                    for( y = 0; y < sizeof( nLocalKey ); y++ )
55db36
-                        nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i );
55db36
-
55db36
-                    rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode,
55db36
-                                            nLocalKey, SECUR_128BIT_KEY, nullptr, 0 ); //destination data area, on init can be NULL
55db36
-                    rtl_cipher_encodeARCFOUR( aCipher, &io_rOValue[0], sal_Int32(io_rOValue.size()), // the data to be encrypted
55db36
-                                              &io_rOValue[0], sal_Int32(io_rOValue.size()) ); // encrypted data, can be the same as the input, encrypt "in place"
55db36
-                    //step 8, store in class data member
55db36
+                    sal_uInt32 i, y;
55db36
+                    sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key
55db36
+
55db36
+                    for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1
55db36
+                    {
55db36
+                        for( y = 0; y < sizeof( nLocalKey ); y++ )
55db36
+                            nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i );
55db36
+
55db36
+                        if (rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode,
55db36
+                                                    nLocalKey, SECUR_128BIT_KEY, nullptr, 0 ) //destination data area, on init can be NULL
55db36
+                            != rtl_Cipher_E_None)
55db36
+                        {
55db36
+                            bSuccess = false;
55db36
+                            break;
55db36
+                        }
55db36
+                        rtl_cipher_encodeARCFOUR( aCipher, &io_rOValue[0], sal_Int32(io_rOValue.size()), // the data to be encrypted
55db36
+                                                  &io_rOValue[0], sal_Int32(io_rOValue.size()) ); // encrypted data, can be the same as the input, encrypt "in place"
55db36
+                        //step 8, store in class data member
55db36
+                    }
55db36
                 }
55db36
             }
55db36
+            else
55db36
+                bSuccess = false;
55db36
         }
55db36
         else
55db36
             bSuccess = false;
55db36
-- 
55db36
2.17.1
55db36