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

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