configure.ac                                               |    2 
 include/sfx2/strings.hrc                                   |    2 
 include/sfx2/viewfrm.hxx                                   |    1 
 officecfg/registry/schema/org/openoffice/Office/Common.xcs |   16 +
 sfx2/source/view/viewfrm.cxx                               |   40 ++
 svl/source/passwordcontainer/passwordcontainer.cxx         |  176 +++++++++----
 svl/source/passwordcontainer/passwordcontainer.hxx         |   69 ++++-
 uui/source/iahndl-authentication.cxx                       |    5 
 xmlsecurity/source/component/documentdigitalsignatures.cxx |   35 +-
 9 files changed, 274 insertions(+), 72 deletions(-)

New commits:
commit 86c57d3e6826169d5be53472fa21590fc8364748
Author:     Andras Timar <[email protected]>
AuthorDate: Tue Jul 26 15:19:06 2022 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Tue Jul 26 15:40:02 2022 +0200

    Bump version to 6.2.8.2.M9
    
    Change-Id: I87168a2e9be351774c53bb1ba49dbcc3bd6687fb

diff --git a/configure.ac b/configure.ac
index 73e4cbfc2b7f..44144ae01383 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@ dnl in order to create a configure script.
 # several non-alphanumeric characters, those are split off and used only for 
the
 # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no 
idea.
 
-AC_INIT([LibreOffice],[6.2.8.2.M8],[],[],[http://documentfoundation.org/])
+AC_INIT([LibreOffice],[6.2.8.2.M9],[],[],[http://documentfoundation.org/])
 
 AC_PREREQ([2.59])
 
commit feeeff8b228c34680373f2e3fe5b9b6cd7786731
Author:     Caolán McNamara <[email protected]>
AuthorDate: Wed Mar 23 13:03:30 2022 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Tue Jul 26 15:40:02 2022 +0200

    CVE-2022-2630[6|7] add infobar to prompt to refresh to replace old format
    
    Change-Id: Id99cbf2b50a4ebf289dae6fc67e22e20afcda35b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131976
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit bbd196ff82bda9f66b4ba32a412f10cefe6da60e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132307
    Reviewed-by: Sophie Gautier <[email protected]>
    Reviewed-by: Christian Lohmaier <[email protected]>
    (cherry picked from commit c5d01b11db3c83cb4a89d3b388d78e20dd3990b5)

diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc
index a77dbc86d77d..c196bcd19989 100644
--- a/include/sfx2/strings.hrc
+++ b/include/sfx2/strings.hrc
@@ -266,6 +266,8 @@
 #define STR_SIGNATURE_NOTVALIDATED_PARTIAL_OK   
NC_("STR_SIGNATURE_NOTVALIDATED_PARTIAL_OK", "The certificate could not be 
validated and the document is only partially signed.")
 #define STR_SIGNATURE_OK                        NC_("STR_SIGNATURE_OK", "This 
document is digitally signed and the signature is valid.")
 #define STR_SIGNATURE_SHOW                      NC_("STR_SIGNATURE_SHOW", 
"Show Signatures")
+#define STR_REFRESH_MASTER_PASSWORD             
NC_("STR_REFRESH_MASTER_PASSWORD", "The master password is stored in an 
outdated format, you should refresh it")
+#define STR_REFRESH_PASSWORD                    NC_("STR_REFRESH_PASSWORD", 
"Refresh Password")
 
 #define STR_CLOSE_PANE                          NC_("STR_CLOSE_PANE", "Close 
Pane")
 #define STR_SFX_DOCK                            NC_("STR_SFX_DOCK", "Dock")
diff --git a/include/sfx2/viewfrm.hxx b/include/sfx2/viewfrm.hxx
index 6d9ef75b8ffe..b78a0c92cd3a 100644
--- a/include/sfx2/viewfrm.hxx
+++ b/include/sfx2/viewfrm.hxx
@@ -80,6 +80,7 @@ protected:
     DECL_LINK(GetDonateHandler, Button*, void);
     DECL_LINK(SwitchReadOnlyHandler, Button*, void);
     DECL_LINK(SignDocumentHandler, Button*, void);
+    DECL_DLLPRIVATE_LINK(RefreshMasterPasswordHdl, Button*, void);
     SAL_DLLPRIVATE void KillDispatcher_Impl();
 
     virtual                 ~SfxViewFrame() override;
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index 814a45f42b6f..e4666de79a27 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/frame/XLoadable.hpp>
 #include <com/sun/star/frame/XLayoutManager.hpp>
 #include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
 #include <officecfg/Office/Common.hxx>
 #include <officecfg/Setup.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
@@ -1274,6 +1275,24 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, 
const SfxHint& rHint )
                     batch->commit();
                 }
 
+                if (officecfg::Office::Common::Passwords::HasMaster::get() &&
+                    
officecfg::Office::Common::Passwords::StorageVersion::get() == 0)
+                {
+                    // master password stored in deprecated format
+                    VclPtr<SfxInfoBarWindow> pOldMasterPasswordInfoBar =
+                        AppendInfoBar("oldmasterpassword",
+                                      SfxResId(STR_REFRESH_MASTER_PASSWORD), 
InfoBarType::Danger);
+                    if (pOldMasterPasswordInfoBar)
+                    {
+                        VclPtrInstance<PushButton> const xBtn(&GetWindow());
+                        xBtn->SetText(SfxResId(STR_REFRESH_PASSWORD));
+                       xBtn->SetSizePixel(xBtn->GetOptimalSize());
+                        xBtn->SetClickHdl(LINK(this,
+                            SfxViewFrame, RefreshMasterPasswordHdl));
+                        pOldMasterPasswordInfoBar->addButton(xBtn);
+                    }
+                }
+
                 // read-only infobar if necessary
                 const SfxViewShell *pVSh;
                 const SfxShell *pFSh;
@@ -1423,6 +1442,27 @@ IMPL_LINK_NOARG(SfxViewFrame, SignDocumentHandler, 
Button*, void)
     GetDispatcher()->Execute(SID_SIGNATURE);
 }
 
+IMPL_LINK_NOARG(SfxViewFrame, RefreshMasterPasswordHdl, Button*, void)
+{
+    bool bChanged = false;
+    try
+    {
+        Reference< task::XPasswordContainer2 > xMasterPasswd(
+            
task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+        css::uno::Reference<css::frame::XFrame> xFrame = 
GetFrame().GetFrameInterface();
+        css::uno::Reference<css::awt::XWindow> xContainerWindow = 
xFrame->getContainerWindow();
+
+        uno::Reference<task::XInteractionHandler> 
xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+                                                              
xContainerWindow));
+        bChanged = xMasterPasswd->changeMasterPassword(xTmpHandler);
+    }
+    catch (const Exception&)
+    {}
+    if (bChanged)
+        RemoveInfoBar(u"oldmasterpassword");
+}
+
 void SfxViewFrame::Construct_Impl( SfxObjectShell *pObjSh )
 {
     m_pImpl->bResizeInToOut = true;
commit cca849d3da95dfe76124053e46536471e4f9fb47
Author:     Caolán McNamara <[email protected]>
AuthorDate: Tue Mar 22 17:22:22 2022 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Tue Jul 26 15:18:24 2022 +0200

    CVE-2022-26306 add Initialization Vectors to password storage
    
    old ones default to the current all zero case and continue to work
    as before
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131974
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 192fa1e3bfc6269f2ebb91716471485a56074aea)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132306
    Reviewed-by: Thorsten Behrens <[email protected]>
    (cherry picked from commit ab77587ec300f5c30084471000663c46ddf25dad)
    
    Change-Id: I6fe3b02fafcce1b5e7133e77e76a5118177d77af

diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index cb1c57120731..34f441e9eedf 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -27,6 +27,11 @@
       <info>
         <desc>Contains a container for passwords.</desc>
       </info>
+      <prop oor:name="InitializationVector" oor:type="xs:string">
+        <info>
+          <desc>Contains an initialization vector for the password 
encryption.</desc>
+        </info>
+      </prop>
       <prop oor:name="Password" oor:type="xs:string" oor:localized="false">
         <info>
           <desc>Contains a password encoded with the master password.</desc>
@@ -915,6 +920,11 @@
         </info>
         <value>false</value>
       </prop>
+      <prop oor:name="MasterInitializationVector" oor:type="xs:string">
+        <info>
+          <desc>Contains an initialization vector for the master password 
encryption.</desc>
+        </info>
+      </prop>
       <prop oor:name="Master" oor:type="xs:string" oor:nillable="false">
         <info>
           <desc>Contains the master password encrypted by itself.</desc>
diff --git a/svl/source/passwordcontainer/passwordcontainer.cxx 
b/svl/source/passwordcontainer/passwordcontainer.cxx
index e7a007a7342b..8b7cf0ad582c 100644
--- a/svl/source/passwordcontainer/passwordcontainer.cxx
+++ b/svl/source/passwordcontainer/passwordcontainer.cxx
@@ -182,23 +182,24 @@ PassMap StorageItem::getInfo()
 
     Sequence< OUString > aNodeNames     = ConfigItem::GetNodeNames( "Store" );
     sal_Int32 aNodeCount = aNodeNames.getLength();
-    Sequence< OUString > aPropNames( aNodeCount );
-    sal_Int32 aNodeInd;
+    Sequence< OUString > aPropNames( aNodeCount * 2);
 
-    for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
-    {
-        aPropNames[aNodeInd]  = "Store/Passwordstorage['" + 
aNodeNames[aNodeInd] + "']/Password";
-    }
+    std::transform(aNodeNames.begin(), aNodeNames.end(), aPropNames.begin(),
+        [](const OUString& rName) -> OUString {
+            return "Store/Passwordstorage['" + rName + "']/Password"; });
+    std::transform(aNodeNames.begin(), aNodeNames.end(), aPropNames.getArray() 
+ aNodeCount,
+        [](const OUString& rName) -> OUString {
+            return "Store/Passwordstorage['" + rName + 
"']/InitializationVector"; });
 
     Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames );
 
-    if( aPropertyValues.getLength() != aNodeNames.getLength() )
+    if( aPropertyValues.getLength() != aNodeCount * 2)
     {
-        OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), 
"Problems during reading" );
+        OSL_FAIL( "Problems during reading" );
         return aResult;
     }
 
-    for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
+    for( sal_Int32 aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
     {
         std::vector< OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] 
);
 
@@ -208,14 +209,16 @@ PassMap StorageItem::getInfo()
             OUString aName = aUrlUsr[1];
 
             OUString aEPasswd;
+            OUString aIV;
             aPropertyValues[aNodeInd] >>= aEPasswd;
+            aPropertyValues[aNodeInd + aNodeCount] >>= aIV;
 
             PassMap::iterator aIter = aResult.find( aUrl );
             if( aIter != aResult.end() )
-                aIter->second.emplace_back( aName, aEPasswd );
+                aIter->second.emplace_back( aName, aEPasswd, aIV );
             else
             {
-                NamePassRecord aNewRecord( aName, aEPasswd );
+                NamePassRecord aNewRecord( aName, aEPasswd, aIV );
                 std::vector< NamePassRecord > listToAdd( 1, aNewRecord );
 
                 aResult.insert( PairUrlRecord( aUrl, listToAdd ) );
@@ -279,17 +282,19 @@ sal_Int32 StorageItem::getStorageVersion()
     return nResult;
 }
 
-bool StorageItem::getEncodedMP( OUString& aResult )
+bool StorageItem::getEncodedMP( OUString& aResult, OUString& aResultIV )
 {
     if( hasEncoded )
     {
         aResult = mEncoded;
+        aResultIV = mEncodedIV;
         return true;
     }
 
-    Sequence< OUString > aNodeNames( 2 );
+    Sequence< OUString > aNodeNames( 3 );
     aNodeNames[0] = "HasMaster";
     aNodeNames[1] = "Master";
+    aNodeNames[2] = "MasterInitializationVector";
 
     Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
 
@@ -301,32 +306,37 @@ bool StorageItem::getEncodedMP( OUString& aResult )
 
     aPropertyValues[0] >>= hasEncoded;
     aPropertyValues[1] >>= mEncoded;
+    aPropertyValues[2] >>= mEncodedIV;
 
     aResult = mEncoded;
+    aResultIV = mEncodedIV;
 
     return hasEncoded;
 }
 
 
-void StorageItem::setEncodedMP( const OUString& aEncoded, bool bAcceptEmpty )
+void StorageItem::setEncodedMP( const OUString& aEncoded, const OUString& 
aEncodedIV, bool bAcceptEmpty )
 {
-    Sequence< OUString > sendNames(3);
-    Sequence< uno::Any > sendVals(3);
+    Sequence< OUString > sendNames(4);
+    Sequence< uno::Any > sendVals(4);
 
     sendNames[0] = "HasMaster";
     sendNames[1] = "Master";
-    sendNames[2] = "StorageVersion";
+    sendNames[2] = "MasterInitializationVector";
+    sendNames[3] = "StorageVersion";
 
     bool bHasMaster = ( !aEncoded.isEmpty() || bAcceptEmpty );
     sendVals[0] <<= bHasMaster;
     sendVals[1] <<= aEncoded;
-    sendVals[2] <<= nCurrentStorageVersion;
+    sendVals[2] <<= aEncodedIV;
+    sendVals[3] <<= nCurrentStorageVersion;
 
     ConfigItem::SetModified();
     ConfigItem::PutProperties( sendNames, sendVals );
 
     hasEncoded = bHasMaster;
     mEncoded = aEncoded;
+    mEncodedIV = aEncodedIV;
 }
 
 
@@ -362,11 +372,13 @@ void StorageItem::update( const OUString& aURL, const 
NamePassRecord& aRecord )
     forIndex.push_back( aURL );
     forIndex.push_back( aRecord.GetUserName() );
 
-    Sequence< beans::PropertyValue > sendSeq(1);
+    Sequence< beans::PropertyValue > sendSeq(2);
 
-    sendSeq[0].Name  = "Store/Passwordstorage['" + createIndex( forIndex ) + 
"']/Password";
+    sendSeq[0].Name  = "Store/Passwordstorage['" + createIndex( forIndex ) + 
"']/InitializationVector";
+    sendSeq[0].Value <<= aRecord.GetPersistentIV();
 
-    sendSeq[0].Value <<= aRecord.GetPersPasswords();
+    sendSeq[1].Name  = "Store/Passwordstorage['" + createIndex( forIndex ) + 
"']/Password";
+    sendSeq[1].Value <<= aRecord.GetPersPasswords();
 
     ConfigItem::SetModified();
     ConfigItem::SetSetProperties( "Store", sendSeq );
@@ -427,7 +439,7 @@ void SAL_CALL PasswordContainer::disposing( const 
EventObject& )
     }
 }
 
-std::vector< OUString > PasswordContainer::DecodePasswords( const OUString& 
aLine, const OUString& aMasterPasswd, css::task::PasswordRequestMode mode )
+std::vector< OUString > PasswordContainer::DecodePasswords( const OUString& 
aLine, const OUString& aIV, const OUString& aMasterPasswd, 
css::task::PasswordRequestMode mode )
 {
     if( !aMasterPasswd.isEmpty() )
     {
@@ -442,9 +454,16 @@ std::vector< OUString > 
PasswordContainer::DecodePasswords( const OUString& aLin
             for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
                 code[ ind ] = static_cast<char>(aMasterPasswd.copy( ind*2, 2 
).toUInt32(16));
 
+            unsigned char iv[RTL_DIGEST_LENGTH_MD5] = {0};
+            if (!aIV.isEmpty())
+            {
+                for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
+                    iv[ ind ] = static_cast<char>(aIV.copy( ind*2, 2 
).toUInt32(16));
+            }
+
             rtlCipherError result = rtl_cipher_init (
                     aDecoder, rtl_Cipher_DirectionDecode,
-                    code, RTL_DIGEST_LENGTH_MD5, nullptr, 0 );
+                    code, RTL_DIGEST_LENGTH_MD5, iv, RTL_DIGEST_LENGTH_MD5 );
 
             if( result == rtl_Cipher_E_None )
             {
@@ -477,7 +496,7 @@ std::vector< OUString > PasswordContainer::DecodePasswords( 
const OUString& aLin
         "Can't decode!", css::uno::Reference<css::uno::XInterface>(), mode);
 }
 
-OUString PasswordContainer::EncodePasswords(const std::vector< OUString >& 
lines, const OUString& aMasterPasswd )
+OUString PasswordContainer::EncodePasswords(const std::vector< OUString >& 
lines, const OUString& aIV, const OUString& aMasterPasswd)
 {
     if( !aMasterPasswd.isEmpty() )
     {
@@ -494,9 +513,16 @@ OUString PasswordContainer::EncodePasswords(const 
std::vector< OUString >& lines
             for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
                 code[ ind ] = static_cast<char>(aMasterPasswd.copy( ind*2, 2 
).toUInt32(16));
 
+            unsigned char iv[RTL_DIGEST_LENGTH_MD5] = {0};
+            if (!aIV.isEmpty())
+            {
+                for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
+                    iv[ ind ] = static_cast<char>(aIV.copy( ind*2, 2 
).toUInt32(16));
+            }
+
             rtlCipherError result = rtl_cipher_init (
                     aEncoder, rtl_Cipher_DirectionEncode,
-                    code, RTL_DIGEST_LENGTH_MD5, nullptr, 0 );
+                    code, RTL_DIGEST_LENGTH_MD5, iv, RTL_DIGEST_LENGTH_MD5 );
 
             if( result == rtl_Cipher_E_None )
             {
@@ -564,7 +590,7 @@ void PasswordContainer::UpdateVector( const OUString& aURL, 
std::vector< NamePas
 
             if( aRecord.HasPasswords( PERSISTENT_RECORD ) )
             {
-                aNPIter.SetPersPasswords( aRecord.GetPersPasswords() );
+                aNPIter.SetPersPasswords( aRecord.GetPersPasswords(), 
aRecord.GetPersistentIV() );
 
                 if( writeFile )
                 {
@@ -597,7 +623,8 @@ UserRecord PasswordContainer::CopyToUserRecord( const 
NamePassRecord& aRecord, b
     {
         try
         {
-            ::std::vector< OUString > aDecodedPasswords = DecodePasswords( 
aRecord.GetPersPasswords(), GetMasterPassword( aHandler ), 
css::task::PasswordRequestMode_PASSWORD_ENTER );
+            ::std::vector< OUString > aDecodedPasswords = DecodePasswords( 
aRecord.GetPersPasswords(), aRecord.GetPersistentIV(),
+                                                                           
GetMasterPassword( aHandler ), css::task::PasswordRequestMode_PASSWORD_ENTER );
             aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), 
aDecodedPasswords.end() );
         }
         catch( NoMasterException& )
@@ -642,6 +669,19 @@ void SAL_CALL PasswordContainer::addPersistent( const 
OUString& Url, const OUStr
     PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler );
 }
 
+OUString PasswordContainer::createIV()
+{
+    rtlRandomPool randomPool = mRandomPool.get();
+    unsigned char iv[RTL_DIGEST_LENGTH_MD5];
+    rtl_random_getBytes(randomPool, iv, RTL_DIGEST_LENGTH_MD5);
+    OUStringBuffer aBuffer;
+    for (sal_uInt8 i : iv)
+    {
+        aBuffer.append(OUString::number(i >> 4, 16));
+        aBuffer.append(OUString::number(i & 15, 16));
+    }
+    return aBuffer.makeStringAndClear();
+}
 
 void PasswordContainer::PrivateAdd( const OUString& Url, const OUString& 
UserName, const Sequence< OUString >& Passwords, char Mode, const Reference< 
XInteractionHandler >& aHandler )
 {
@@ -649,7 +689,11 @@ void PasswordContainer::PrivateAdd( const OUString& Url, 
const OUString& UserNam
     ::std::vector< OUString > aStorePass = comphelper::sequenceToContainer< 
std::vector<OUString> >( Passwords );
 
     if( Mode == PERSISTENT_RECORD )
-        aRecord.SetPersPasswords( EncodePasswords( aStorePass, 
GetMasterPassword( aHandler ) ) );
+    {
+        OUString sIV = createIV();
+        OUString sEncodedPasswords = EncodePasswords( aStorePass, sIV, 
GetMasterPassword( aHandler ) );
+        aRecord.SetPersPasswords( sEncodedPasswords, sIV );
+    }
     else if( Mode == MEMORY_RECORD )
         aRecord.SetMemPasswords( aStorePass );
     else
@@ -842,10 +886,10 @@ OUString const & PasswordContainer::GetMasterPassword( 
const Reference< XInterac
 
     if( m_aMasterPasswd.isEmpty() && aHandler.is() )
     {
-        OUString aEncodedMP;
+        OUString aEncodedMP, aEncodedMPIV;
         bool bDefaultPassword = false;
 
-        if( !m_pStorageFile->getEncodedMP( aEncodedMP ) )
+        if( !m_pStorageFile->getEncodedMP( aEncodedMP, aEncodedMPIV ) )
             aRMode = PasswordRequestMode_PASSWORD_CREATE;
         else if ( aEncodedMP.isEmpty() )
         {
@@ -867,14 +911,15 @@ OUString const & PasswordContainer::GetMasterPassword( 
const Reference< XInterac
                         m_aMasterPasswd = aPass;
                         std::vector< OUString > aMaster( 1, m_aMasterPasswd );
 
-                        m_pStorageFile->setEncodedMP( EncodePasswords( 
aMaster, m_aMasterPasswd ) );
+                        OUString sIV = createIV();
+                        m_pStorageFile->setEncodedMP( EncodePasswords( 
aMaster, sIV, m_aMasterPasswd ), sIV );
                     }
                     else
                     {
                         if (m_pStorageFile->getStorageVersion() == 0)
                             aPass = ReencodeAsOldHash(aPass);
 
-                        std::vector< OUString > aRM( DecodePasswords( 
aEncodedMP, aPass, aRMode ) );
+                        std::vector< OUString > aRM( DecodePasswords( 
aEncodedMP, aEncodedMPIV, aPass, aRMode ) );
                         if( aRM.empty() || aPass != aRM[0] )
                         {
                             bAskAgain = true;
@@ -1031,7 +1076,8 @@ Sequence< UrlRecord > SAL_CALL 
PasswordContainer::getAllPersistent( const Refere
             {
                 sal_Int32 oldLen = aUsers.getLength();
                 aUsers.realloc( oldLen + 1 );
-                aUsers[ oldLen ] = UserRecord( aNP.GetUserName(), 
comphelper::containerToSequence( DecodePasswords( aNP.GetPersPasswords(), 
GetMasterPassword( xHandler ), css::task::PasswordRequestMode_PASSWORD_ENTER ) 
) );
+                aUsers[ oldLen ] = UserRecord( aNP.GetUserName(), 
comphelper::containerToSequence( DecodePasswords( aNP.GetPersPasswords(), 
aNP.GetPersistentIV(),
+                                                                               
                                     GetMasterPassword( xHandler ), 
css::task::PasswordRequestMode_PASSWORD_ENTER ) ) );
             }
 
         if( aUsers.getLength() )
@@ -1048,12 +1094,12 @@ Sequence< UrlRecord > SAL_CALL 
PasswordContainer::getAllPersistent( const Refere
 sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const 
uno::Reference< task::XInteractionHandler >& xHandler )
 {
     bool bResult = false;
-    OUString aEncodedMP;
+    OUString aEncodedMP, aEncodedMPIV;
     uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
     ::osl::MutexGuard aGuard( mMutex );
 
     // the method should fail if there is no master password
-    if( m_pStorageFile && m_pStorageFile->useStorage() && 
m_pStorageFile->getEncodedMP( aEncodedMP ) )
+    if( m_pStorageFile && m_pStorageFile->useStorage() && 
m_pStorageFile->getEncodedMP( aEncodedMP, aEncodedMPIV ) )
     {
         if ( aEncodedMP.isEmpty() )
         {
@@ -1121,8 +1167,8 @@ sal_Bool SAL_CALL 
PasswordContainer::changeMasterPassword( const uno::Reference<
 
         bool bCanChangePassword = true;
         // if there is already a stored master password it should be entered 
by the user before the change happen
-        OUString aEncodedMP;
-        if( !m_aMasterPasswd.isEmpty() || m_pStorageFile->getEncodedMP( 
aEncodedMP ) )
+        OUString aEncodedMP, aEncodedMPIV;
+        if( !m_aMasterPasswd.isEmpty() || m_pStorageFile->getEncodedMP( 
aEncodedMP, aEncodedMPIV ) )
             bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
 
         if ( bCanChangePassword )
@@ -1141,7 +1187,8 @@ sal_Bool SAL_CALL 
PasswordContainer::changeMasterPassword( const uno::Reference<
                 // store the new master password
                 m_aMasterPasswd = aPass;
                 std::vector< OUString > aMaster( 1, m_aMasterPasswd );
-                m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, 
m_aMasterPasswd ) );
+                OUString aIV = createIV();
+                m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, aIV, 
m_aMasterPasswd ), aIV );
 
                 // store all the entries with the new password
                 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); 
nURLInd++ )
@@ -1168,7 +1215,7 @@ void SAL_CALL PasswordContainer::removeMasterPassword()
     if ( m_pStorageFile )
     {
         m_aMasterPasswd.clear();
-        m_pStorageFile->setEncodedMP( OUString() ); // let the master password 
be removed from configuration
+        m_pStorageFile->setEncodedMP( OUString(), OUString() ); // let the 
master password be removed from configuration
     }
 }
 
@@ -1179,8 +1226,8 @@ sal_Bool SAL_CALL PasswordContainer::hasMasterPassword(  )
     if ( !m_pStorageFile )
         throw uno::RuntimeException();
 
-    OUString aEncodedMP;
-    return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( 
aEncodedMP ) );
+    OUString aEncodedMP, aEncodedMPIV;
+    return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( 
aEncodedMP, aEncodedMPIV ) );
 }
 
 sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( sal_Bool bAllow )
@@ -1227,8 +1274,8 @@ sal_Bool SAL_CALL 
PasswordContainer::useDefaultMasterPassword( const uno::Refere
 
         bool bCanChangePassword = true;
         // if there is already a stored nondefault master password it should 
be entered by the user before the change happen
-        OUString aEncodedMP;
-        if( m_pStorageFile->getEncodedMP( aEncodedMP ) && 
!aEncodedMP.isEmpty() )
+        OUString aEncodedMP, aEncodedMPIV;
+        if( m_pStorageFile->getEncodedMP( aEncodedMP, aEncodedMPIV ) && 
!aEncodedMP.isEmpty() )
             bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
 
         if ( bCanChangePassword )
@@ -1245,7 +1292,7 @@ sal_Bool SAL_CALL 
PasswordContainer::useDefaultMasterPassword( const uno::Refere
 
                 // store the empty string to flag the default master password
                 m_aMasterPasswd = aPass;
-                m_pStorageFile->setEncodedMP( OUString(), true );
+                m_pStorageFile->setEncodedMP( OUString(), OUString(), true );
 
                 // store all the entries with the new password
                 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); 
nURLInd++ )
@@ -1271,8 +1318,8 @@ sal_Bool SAL_CALL 
PasswordContainer::isDefaultMasterPasswordUsed()
     if ( !m_pStorageFile )
         throw uno::RuntimeException();
 
-    OUString aEncodedMP;
-    return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( 
aEncodedMP ) && aEncodedMP.isEmpty() );
+    OUString aEncodedMP, aEncodedMPIV;
+    return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( 
aEncodedMP, aEncodedMPIV ) && aEncodedMP.isEmpty() );
 }
 
 
diff --git a/svl/source/passwordcontainer/passwordcontainer.hxx 
b/svl/source/passwordcontainer/passwordcontainer.hxx
index 6ad1eee3d0d5..94ca40dcf90b 100644
--- a/svl/source/passwordcontainer/passwordcontainer.hxx
+++ b/svl/source/passwordcontainer/passwordcontainer.hxx
@@ -36,6 +36,7 @@
 #include <unotools/configitem.hxx>
 #include <ucbhelper/interactionrequest.hxx>
 
+#include <rtl/random.h>
 #include <rtl/ref.hxx>
 #include <osl/mutex.hxx>
 
@@ -54,11 +55,12 @@ class NamePassRecord
     ::std::vector< OUString >                      m_aMemPass;
 
     // persistent passwords are encrypted in one string
-    bool                                                  m_bHasPersPass;
+    bool                                           m_bHasPersPass;
     OUString                                       m_aPersPass;
+    OUString                                       m_aPersistentIV;
 
     void InitArrays( bool bHasMemoryList, const ::std::vector< OUString >& 
aMemoryList,
-                     bool bHasPersistentList, const OUString& aPersistentList )
+                     bool bHasPersistentList, const OUString& aPersistentList, 
const OUString& aPersistentIV )
     {
         m_bHasMemPass = bHasMemoryList;
         if ( bHasMemoryList )
@@ -66,7 +68,10 @@ class NamePassRecord
 
         m_bHasPersPass = bHasPersistentList;
         if ( bHasPersistentList )
+        {
             m_aPersPass = aPersistentList;
+            m_aPersistentIV = aPersistentIV;
+        }
     }
 
 public:
@@ -78,11 +83,12 @@ public:
     {
     }
 
-    NamePassRecord( const OUString& aName, const OUString& aPersistentList )
+    NamePassRecord( const OUString& aName, const OUString& aPersistentList, 
const OUString& aPersistentIV )
         : m_aName( aName )
         , m_bHasMemPass( false )
         , m_bHasPersPass( true )
         , m_aPersPass( aPersistentList )
+        , m_aPersistentIV( aPersistentIV )
     {
     }
 
@@ -91,7 +97,8 @@ public:
         , m_bHasMemPass( false )
         , m_bHasPersPass( false )
     {
-        InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, 
aRecord.m_bHasPersPass, aRecord.m_aPersPass );
+        InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass,
+                    aRecord.m_bHasPersPass, aRecord.m_aPersPass, 
aRecord.m_aPersistentIV );
     }
 
     NamePassRecord& operator=( const NamePassRecord& aRecord )
@@ -102,7 +109,9 @@ public:
 
             m_aMemPass.clear();
             m_aPersPass.clear();
-            InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, 
aRecord.m_bHasPersPass, aRecord.m_aPersPass );
+            m_aPersistentIV.clear();
+            InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass,
+                        aRecord.m_bHasPersPass, aRecord.m_aPersPass, 
aRecord.m_aPersistentIV );
         }
         return *this;
     }
@@ -138,15 +147,24 @@ public:
         return OUString();
     }
 
+    OUString GetPersistentIV() const
+    {
+        if ( m_bHasPersPass )
+            return m_aPersistentIV;
+
+        return OUString();
+    }
+
     void SetMemPasswords( const ::std::vector< OUString >& aMemList )
     {
         m_aMemPass = aMemList;
         m_bHasMemPass = true;
     }
 
-    void SetPersPasswords( const OUString& aPersList )
+    void SetPersPasswords( const OUString& aPersList, const OUString& aPersIV )
     {
         m_aPersPass = aPersList;
+        m_aPersistentIV = aPersIV;
         m_bHasPersPass = true;
     }
 
@@ -161,6 +179,7 @@ public:
         {
             m_bHasPersPass = false;
             m_aPersPass.clear();
+            m_aPersistentIV.clear();
         }
     }
 
@@ -184,6 +203,7 @@ private:
     PasswordContainer*     mainCont;
     bool                   hasEncoded;
     OUString        mEncoded;
+    OUString        mEncodedIV;
 
     virtual void            ImplCommit() override;
 
@@ -204,8 +224,8 @@ public:
 
     sal_Int32 getStorageVersion();
 
-    bool getEncodedMP( OUString& aResult );
-    void setEncodedMP( const OUString& aResult, bool bAcceptEnmpty = false );
+    bool getEncodedMP( OUString& aResult, OUString& aResultIV );
+    void setEncodedMP( const OUString& aResult, const OUString& aResultIV, 
bool bAcceptEmpty = false );
     void setUseStorage( bool bUse );
     bool useStorage();
 
@@ -226,6 +246,29 @@ private:
     css::uno::Reference< css::lang::XComponent > mComponent;
     SysCredentialsConfig mUrlContainer;
 
+    class RandomPool
+    {
+    private:
+        rtlRandomPool m_aRandomPool;
+    public:
+        RandomPool() : m_aRandomPool(rtl_random_createPool())
+        {
+        }
+        rtlRandomPool get()
+        {
+            return m_aRandomPool;
+        }
+        ~RandomPool()
+        {
+            // Clean up random pool memory
+            rtl_random_destroyPool(m_aRandomPool);
+        }
+    };
+
+    RandomPool mRandomPool;
+
+    OUString createIV();
+
     /// @throws css::uno::RuntimeException
     css::uno::Sequence< css::task::UserRecord > CopyToUserRecordSequence(
                                         const ::std::vector< NamePassRecord >& 
original,
@@ -276,10 +319,10 @@ css::task::UrlRecord find(
                               const css::uno::Reference< 
css::task::XInteractionHandler >& Handler );
 
     /// @throws css::uno::RuntimeException
-    static ::std::vector< OUString > DecodePasswords( const OUString& aLine, 
const OUString& aMasterPassword, css::task::PasswordRequestMode mode );
+    static ::std::vector< OUString > DecodePasswords( const OUString& aLine, 
const OUString& aIV, const OUString& aMasterPassword, 
css::task::PasswordRequestMode mode );
 
     /// @throws css::uno::RuntimeException
-    static OUString EncodePasswords(const std::vector< OUString >& lines, 
const OUString& aMasterPassword );
+    static OUString EncodePasswords(const std::vector< OUString >& lines, 
const OUString& aIV, const OUString& aMasterPassword );
 
 public:
     PasswordContainer( const css::uno::Reference< 
css::lang::XMultiServiceFactory >& );
commit 9bbb6a495a3e7181601de488bec18b78e48010e5
Author:     Caolán McNamara <[email protected]>
AuthorDate: Mon Mar 21 20:58:34 2022 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Tue Jul 26 15:16:49 2022 +0200

    CVE-2022-26307 make hash encoding match decoding
    
    Seeing as old versions of the hash may be in the users config, add a
    StorageVersion field to the office config Passwords section which
    defaults to 0 to indicate the old hash is in use.
    
    Try the old varient when StorageVersion is 0. When a new encoded master
    password it set write StorageVersion of 1 to indicate a new hash is in
    use and use the new style when StorageVersion is 1.
    
    Change-Id: I3174c37a5891bfc849984e0ec5c2c392b9c6e7b1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132080
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <[email protected]>
    (cherry picked from commit e890f54dbac57f3ab5acf4fbd31222095d3e8ab6)

diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index 225567c53a06..cb1c57120731 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -903,6 +903,12 @@
         </info>
         <value>false</value>
       </prop>
+      <prop oor:name="StorageVersion" oor:type="xs:int" oor:nillable="false">
+        <info>
+          <desc>Specifies what version of encoding scheme the password 
container uses.</desc>
+        </info>
+        <value>0</value>
+      </prop>
       <prop oor:name="HasMaster" oor:type="xs:boolean" oor:nillable="false">
         <info>
           <desc>Specifies if there is a valid master password.</desc>
diff --git a/svl/source/passwordcontainer/passwordcontainer.cxx 
b/svl/source/passwordcontainer/passwordcontainer.cxx
index eb52bc98e520..e7a007a7342b 100644
--- a/svl/source/passwordcontainer/passwordcontainer.cxx
+++ b/svl/source/passwordcontainer/passwordcontainer.cxx
@@ -17,7 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-
 #include "passwordcontainer.hxx"
 
 #include <unotools/pathoptions.hxx>
@@ -262,6 +261,23 @@ bool StorageItem::useStorage()
     return aResult;
 }
 
+sal_Int32 StorageItem::getStorageVersion()
+{
+    Sequence<OUString> aNodeNames { "StorageVersion" };
+
+    Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
+
+    if( aPropertyValues.getLength() != aNodeNames.getLength() )
+    {
+        OSL_FAIL( "Problems during reading" );
+        return 0;
+    }
+
+    sal_Int32 nResult = 0;
+    aPropertyValues[0] >>= nResult;
+
+    return nResult;
+}
 
 bool StorageItem::getEncodedMP( OUString& aResult )
 {
@@ -294,15 +310,17 @@ bool StorageItem::getEncodedMP( OUString& aResult )
 
 void StorageItem::setEncodedMP( const OUString& aEncoded, bool bAcceptEmpty )
 {
-    Sequence< OUString > sendNames(2);
-    Sequence< uno::Any > sendVals(2);
+    Sequence< OUString > sendNames(3);
+    Sequence< uno::Any > sendVals(3);
 
     sendNames[0] = "HasMaster";
     sendNames[1] = "Master";
+    sendNames[2] = "StorageVersion";
 
     bool bHasMaster = ( !aEncoded.isEmpty() || bAcceptEmpty );
     sendVals[0] <<= bHasMaster;
     sendVals[1] <<= aEncoded;
+    sendVals[2] <<= nCurrentStorageVersion;
 
     ConfigItem::SetModified();
     ConfigItem::PutProperties( sendNames, sendVals );
@@ -803,6 +821,18 @@ OUString PasswordContainer::RequestPasswordFromUser( 
PasswordRequestMode aRMode,
     return aResult;
 }
 
+// Mangle the key to match an old bug
+static OUString ReencodeAsOldHash(const OUString& rPass)
+{
+    OUStringBuffer aBuffer;
+    for (int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ++ind)
+    {
+        unsigned char i = static_cast<char>(rPass.copy(ind * 2, 
2).toUInt32(16));
+        aBuffer.append(static_cast< sal_Unicode >('a' + (i >> 4)));
+        aBuffer.append(static_cast< sal_Unicode >('a' + (i & 15)));
+    }
+    return aBuffer.makeStringAndClear();
+}
 
 OUString const & PasswordContainer::GetMasterPassword( const Reference< 
XInteractionHandler >& aHandler )
 {
@@ -841,6 +871,9 @@ OUString const & PasswordContainer::GetMasterPassword( 
const Reference< XInterac
                     }
                     else
                     {
+                        if (m_pStorageFile->getStorageVersion() == 0)
+                            aPass = ReencodeAsOldHash(aPass);
+
                         std::vector< OUString > aRM( DecodePasswords( 
aEncodedMP, aPass, aRMode ) );
                         if( aRM.empty() || aPass != aRM[0] )
                         {
@@ -1045,6 +1078,12 @@ sal_Bool SAL_CALL 
PasswordContainer::authorizateWithMasterPassword( const uno::R
 
                 do {
                     aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
+
+                    if (!aPass.isEmpty() && 
m_pStorageFile->getStorageVersion() == 0)
+                    {
+                        aPass = ReencodeAsOldHash(aPass);
+                    }
+
                     bResult = ( !aPass.isEmpty() && aPass == m_aMasterPasswd );
                     aRMode = PasswordRequestMode_PASSWORD_REENTER; // further 
questions with error notification
                 } while( !bResult && !aPass.isEmpty() );
diff --git a/svl/source/passwordcontainer/passwordcontainer.hxx 
b/svl/source/passwordcontainer/passwordcontainer.hxx
index ad62ac0c91bd..6ad1eee3d0d5 100644
--- a/svl/source/passwordcontainer/passwordcontainer.hxx
+++ b/svl/source/passwordcontainer/passwordcontainer.hxx
@@ -170,6 +170,10 @@ public:
 typedef ::std::pair< const OUString, ::std::vector< NamePassRecord > > 
PairUrlRecord;
 typedef ::std::map< OUString, ::std::vector< NamePassRecord > > PassMap;
 
+// org.openoffice.Office.Common/Passwords/StorageVersion bump if details of
+// how password details are saved changes. Enables migration from previous
+// schemes.
+constexpr sal_Int32 nCurrentStorageVersion = 1;
 
 class PasswordContainer;
 
@@ -198,6 +202,8 @@ public:
     void remove( const OUString& url, const OUString& rec );
     void clear();
 
+    sal_Int32 getStorageVersion();
+
     bool getEncodedMP( OUString& aResult );
     void setEncodedMP( const OUString& aResult, bool bAcceptEnmpty = false );
     void setUseStorage( bool bUse );
diff --git a/uui/source/iahndl-authentication.cxx 
b/uui/source/iahndl-authentication.cxx
index d151a36138e7..ecb06a182daf 100644
--- a/uui/source/iahndl-authentication.cxx
+++ b/uui/source/iahndl-authentication.cxx
@@ -437,8 +437,9 @@ executeMasterPasswordDialog(
     OUStringBuffer aBuffer;
     for (sal_uInt8 i : aKey)
     {
-        aBuffer.append(static_cast< sal_Unicode >('a' + (i >> 4)));
-        aBuffer.append(static_cast< sal_Unicode >('a' + (i & 15)));
+        // match PasswordContainer::DecodePasswords aMasterPasswd.copy(index * 
2, 2).toUInt32(16));
+        aBuffer.append(OUString::number(i >> 4, 16));
+        aBuffer.append(OUString::number(i & 15, 16));
     }
     rInfo.SetPassword(aBuffer.makeStringAndClear());
 }
commit 47be08bbd23852b3dcc4b24f6a5a72873ce2610f
Author:     Caolán McNamara <[email protected]>
AuthorDate: Thu Mar 3 14:22:37 2022 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Tue Jul 26 15:16:30 2022 +0200

    CVE-2022-26305 compare authors using Thumbprint
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130929
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <[email protected]>
    (cherry picked from commit 65442205b5b274ad309308162f150f8d41648f72)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130866
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit a7aaa78acea4c1d51283c2fce54ff9f5339026f8)
    
    Change-Id: I338f58eb07cbf0a3d13a7dafdaddac09252a8546

diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx 
b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index fdd08892d24a..073ad0646d52 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -19,9 +19,10 @@
 
 #include <resourcemanager.hxx>
 
-#include <digitalsignaturesdialog.hxx>
+#include <certificate.hxx>
 #include <certificatechooser.hxx>
 #include <certificateviewer.hxx>
+#include <digitalsignaturesdialog.hxx>
 #include <macrosecurity.hxx>
 #include <biginteger.hxx>
 #include <strings.hrc>
@@ -624,20 +625,26 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
     OUString sSerialNum = 
xmlsecurity::bigIntegerToNumericString(xAuthor->getSerialNumber());
 
     Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = 
SvtSecurityOptions().GetTrustedAuthors();
-    const SvtSecurityOptions::Certificate* pAuthors = 
aTrustedAuthors.getConstArray();
-    const SvtSecurityOptions::Certificate* pAuthorsEnd = pAuthors + 
aTrustedAuthors.getLength();
-    for ( ; pAuthors != pAuthorsEnd; ++pAuthors )
-    {
-        SvtSecurityOptions::Certificate aAuthor = *pAuthors;
-        if (xmlsecurity::EqualDistinguishedNames(aAuthor[0], 
xAuthor->getIssuerName())
-            && (aAuthor[1] == sSerialNum))
-        {
-            bFound = true;
-            break;
-        }
-    }
 
-    return bFound;
+    return std::any_of(aTrustedAuthors.begin(), aTrustedAuthors.end(),
+        [this, &xAuthor, &sSerialNum](const SvtSecurityOptions::Certificate& 
rAuthor) {
+            if (!xmlsecurity::EqualDistinguishedNames(rAuthor[0], 
xAuthor->getIssuerName()))
+                return false;
+            if (rAuthor[1] != sSerialNum)
+                return false;
+
+            DocumentSignatureManager aSignatureManager(mxCtx, {});
+            if (!aSignatureManager.init())
+                return false;
+            uno::Reference<css::security::XCertificate> xCert = 
aSignatureManager.getSecurityEnvironment()->createCertificateFromAscii(rAuthor[2]);
+
+            auto pAuthor = 
dynamic_cast<xmlsecurity::Certificate*>(xAuthor.get());
+            auto pCert = dynamic_cast<xmlsecurity::Certificate*>(xCert.get());
+            if (pAuthor && pCert)
+                return pCert->getSHA256Thumbprint() == 
pAuthor->getSHA256Thumbprint();
+
+            return xCert->getSHA1Thumbprint() == xAuthor->getSHA1Thumbprint();
+        });
 }
 
 uno::Sequence<Reference<css::security::XCertificate>>

Reply via email to