configure.ac                                               |    4 
 external/libffi/ExternalPackage_libffi.mk                  |   20 +
 external/libffi/ExternalProject_libffi.mk                  |   29 +-
 external/libffi/Module_libffi.mk                           |    1 
 sc/source/core/tool/interpr4.cxx                           |   17 +
 xmlsecurity/qa/unit/signing/signing.cxx                    |  167 ++++++++++++-
 xmlsecurity/source/component/documentdigitalsignatures.cxx |   23 +
 xmlsecurity/source/helper/documentsignaturehelper.cxx      |    2 
 xmlsecurity/source/helper/ooxmlsecexporter.cxx             |   58 ++--
 xmlsecurity/source/helper/xsecctl.cxx                      |   23 +
 xmlsecurity/source/helper/xsecsign.cxx                     |   14 -
 11 files changed, 293 insertions(+), 65 deletions(-)

New commits:
commit c22d06eb14479a8706d46681b7121f5b087ed56b
Author:     Andras Timar <andras.ti...@collabora.com>
AuthorDate: Tue Apr 4 13:54:57 2023 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Apr 4 13:54:57 2023 +0200

    Bumnp version to 6.4-68
    
    Change-Id: Ie53c64f8644a121d023c3a64bd975540c2dc38b9

diff --git a/configure.ac b/configure.ac
index ab08382b67d7..2ca1fb09c398 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([Collabora Office],[6.4.10.67],[],[],[https://collaboraoffice.com/])
+AC_INIT([Collabora Office],[6.4.10.68],[],[],[https://collaboraoffice.com/])
 
 dnl libnumbertext needs autoconf 2.68, but that can pick up autoconf268 just 
fine if it is installed
 dnl whereas aclocal (as run by autogen.sh) insists on using autoconf and fails 
hard
commit 381c706e5e010196c81109dafbc372c84aecb670
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Mon Feb 27 23:14:01 2023 +0100
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Apr 4 13:54:11 2023 +0200

    Underflow assert also in already calculated path
    
    Change-Id: I7bd1c4960280a6526bb82e5b95c5253775df1e1a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147937
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147958
    Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 002c7de4c1da..170e60f6afca 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3982,9 +3982,20 @@ StackVar ScInterpreter::Interpret()
                 (*aTokenMatrixMapIter).second->GetType() != svJumpMatrix)
         {
             // Path already calculated, reuse result.
-            nStackBase = sp - pCur->GetParamCount();
-            if ( nStackBase > sp )
-                nStackBase = sp;        // underflow?!?
+            if (sp >= pCur->GetParamCount())
+                nStackBase = sp - pCur->GetParamCount();
+            else
+            {
+                SAL_WARN("sc.core", "Stack anomaly with calculated path at "
+                        << aPos.Tab() << "," << aPos.Col() << "," << aPos.Row()
+                        << "  " << aPos.Format(
+                            ScRefFlags::VALID | ScRefFlags::FORCE_DOC | 
ScRefFlags::TAB_3D, pDok)
+                        << "  eOp: " << static_cast<int>(eOp)
+                        << "  params: " << 
static_cast<int>(pCur->GetParamCount())
+                        << "  nStackBase: " << nStackBase << "  sp: " << sp);
+                nStackBase = sp;
+                assert(!"underflow");
+            }
             sp = nStackBase;
             PushTokenRef( (*aTokenMatrixMapIter).second);
         }
commit e84c6947a949d9bfd26d8032e2b8e7280fe3265c
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Tue Jul 14 23:20:06 2020 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Apr 4 13:52:55 2023 +0200

    libffi: build DLL on Windows
    
    The build setup is rather horrible, with some minimal gcc MSVC
    wrapper. But the DLL is a prerequisite for the Python 3.8 build,
    which dropped the internal libffi.
    
    It's also possible to build it statically, but then you have to
    patch the Python 3 _ctypes msbuild properties.
    
    This also defaults to explicit --build and --host settings, even
    without a cross build, because the predicted name would otherwise
    differ (*-unknown-* instead of *-pc-*).
    
    Additionally a "make install" also fails...
    
    Change-Id: Ifb7dac840e23efffb9a5e342560aef9e11e0db79
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98436
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>
    (cherry picked from commit 883068462fe5bcbb01a8e14736fc06d0c3695c62)

diff --git a/configure.ac b/configure.ac
index b6f0b4597471..ab08382b67d7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8983,7 +8983,7 @@ internal)
     fi
     AC_DEFINE_UNQUOTED([PYTHON_VERSION_STRING], [L"3.7.7"])
     BUILD_TYPE="$BUILD_TYPE PYTHON"
-    if test "$OS" = LINUX; then
+    if test "$OS" = LINUX -o "$OS" = WNT ; then
         BUILD_TYPE="$BUILD_TYPE LIBFFI"
     fi
     # Embedded Python dies without Home set
diff --git a/external/libffi/ExternalPackage_libffi.mk 
b/external/libffi/ExternalPackage_libffi.mk
new file mode 100644
index 000000000000..212e63aa36af
--- /dev/null
+++ b/external/libffi/ExternalPackage_libffi.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libffi,libffi))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libffi,libffi))
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_files,libffi,$(LIBO_LIB_FOLDER),\
+    $(HOST_PLATFORM)/.libs/libffi-7.dll \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libffi/ExternalProject_libffi.mk 
b/external/libffi/ExternalProject_libffi.mk
index bdf8fe61eb76..0ff625ea3e20 100644
--- a/external/libffi/ExternalProject_libffi.mk
+++ b/external/libffi/ExternalProject_libffi.mk
@@ -14,17 +14,34 @@ $(eval $(call gb_ExternalProject_register_targets,libffi,\
 ))
 
 # set prefix so that it ends up in libffi.pc so that pkg-config in python3 
works
+# For a static Windows build, change CPPFLAGS to include -D_LIB and 
--disable-static
+# Also remove the ExternalPackage in that case
+
+libffi_WIN_PLATFORM := $(strip \
+    $(if $(filter INTEL,$(CPUNAME)),32) \
+    $(if $(filter X86_64,$(CPUNAME)),64) \
+    $(if $(filter ARM64,$(CPUNAME)),arm64) \
+    )
 
 $(call gb_ExternalProject_get_state_target,libffi,build):
        $(call gb_ExternalProject_run,build,\
+               export LIB="$(ILIB)" && \
                ./configure \
                        --enable-option-checking=fatal \
-                       $(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) 
--host=$(HOST_PLATFORM)) \
-                       --enable-static \
-                       --disable-shared \
-                       --with-pic \
-                       --enable-portable-binary \
-                       CC="$(CC) $(if $(filter 
LINUX,$(OS)),-fvisibility=hidden)" \
+                       --build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM) \
+                       $(if $(filter LINUX,$(OS)), \
+                           --disable-shared \
+                           CC="$(CC) -fvisibility=hidden" \
+                               --with-pic \
+                               --enable-portable-binary) \
+                       $(if $(filter WNT,$(OS)), \
+                           --disable-static \
+                           CC="$(call 
gb_UnpackedTarball_get_dir,libffi)/msvcc.sh -m$(libffi_WIN_PLATFORM)" \
+                           CXX="$(call 
gb_UnpackedTarball_get_dir,libffi)/msvcc.sh -m$(libffi_WIN_PLATFORM)" \
+                               LD='link' \
+                               CPP='cl -nologo -EP' \
+                               CXXCPP='cl -nologo -EP' \
+                               CPPFLAGS="-DFFI_BUILDING_DLL $(SOLARINC)") \
                        --prefix=$(call 
gb_UnpackedTarball_get_dir,libffi)/$(HOST_PLATFORM) \
                        --disable-docs \
                && $(MAKE) \
diff --git a/external/libffi/Module_libffi.mk b/external/libffi/Module_libffi.mk
index 739fd4197000..ace75480abe3 100644
--- a/external/libffi/Module_libffi.mk
+++ b/external/libffi/Module_libffi.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_Module_Module,libffi))
 $(eval $(call gb_Module_add_targets,libffi,\
        UnpackedTarball_libffi \
        ExternalProject_libffi \
+       ExternalPackage_libffi \
 ))
 
 # vim: set noet sw=4 ts=4:
commit 4b412aeb4c9f30a22e1f003ae89af609b1bf3ef0
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Mon Nov 1 21:46:43 2021 +0100
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Apr 4 13:52:51 2023 +0200

    xmlsec: fix OOXML signing with multiple certs, extend the test
    
    Signing OOXML with 3 or more times didn't work as other ids
    ("idPackageObject", "idOfficeObject", ...) were not uniqe. This
    change makes those ids unique by appending the signature id. The
    signature ID is now generated for OOXML too, while previously it
    was a hardcoded string ("idPackageSignature").
    
    The test for signing multiple OOXML was written before, but didn't
    catch the issues because it didn't assert the status of the
    document after loading it again. This is which is now fixed (and
    also added changed for the ODF test case).
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124571
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit f2e1e4ff085962a08a5d7738325b383c07afcbbd)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124598
    Reviewed-by: Jan Holesovsky <ke...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    (cherry picked from commit 59c3242b75fdc6d44992919e56bc9a379c699374)
    
    Change-Id: Ifa20ea17498b117a4c57f6eddf82f8e83bc640bc

diff --git a/xmlsecurity/qa/unit/signing/signing.cxx 
b/xmlsecurity/qa/unit/signing/signing.cxx
index 85fa471d9669..2f869147db5f 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -54,6 +54,7 @@
 #include <sfx2/docfilt.hxx>
 #include <officecfg/Office/Common.hxx>
 #include <comphelper/configuration.hxx>
+#include <vcl/scheduler.hxx>
 #include <svx/signaturelinehelper.hxx>
 #include <sfx2/viewsh.hxx>
 #include <comphelper/propertyvalue.hxx>
@@ -998,55 +999,72 @@ CPPUNIT_TEST_FIXTURE(SigningTest, 
testSigningMultipleTimes_ODT)
     aMediaDescriptor["FilterName"] <<= OUString("writer8");
     xStorable->storeAsURL(aTempFile.GetURL(), 
aMediaDescriptor.getAsConstPropertyValueList());
 
-    DocumentSignatureManager aManager(mxComponentContext, 
DocumentSignatureMode::Content);
-    CPPUNIT_ASSERT(aManager.init());
-    uno::Reference<embed::XStorage> xStorage
-        = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
-            ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), 
embed::ElementModes::READWRITE);
-    CPPUNIT_ASSERT(xStorage.is());
-    aManager.setStore(xStorage);
-    aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+    {
+        DocumentSignatureManager aManager(mxComponentContext, 
DocumentSignatureMode::Content);
+        CPPUNIT_ASSERT(aManager.init());
+        uno::Reference<embed::XStorage> xStorage
+            = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+                ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), 
embed::ElementModes::READWRITE);
+        CPPUNIT_ASSERT(xStorage.is());
+        aManager.setStore(xStorage);
+        aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+
+        // Create a signature.
+        uno::Reference<security::XCertificate> xCertificate
+            = getCertificate(aManager, 
svl::crypto::SignatureMethodAlgorithm::RSA);
+
+        if (!xCertificate.is())
+            return;
+        sal_Int32 nSecurityId;
+        aManager.add(xCertificate, mxSecurityContext, 
/*rDescription=*/OUString(), nSecurityId,
+                     /*bAdESCompliant=*/true);
+
+        // Read back the signature and make sure that it's valid.
+        aManager.read(/*bUseTempStream=*/true);
+        {
+            std::vector<SignatureInformation>& rInformations
+                = aManager.getCurrentSignatureInformations();
+            CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), 
rInformations.size());
+            
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                                 rInformations[0].nStatus);
+        }
 
-    // Create a signature.
-    uno::Reference<security::XCertificate> xCertificate
-        = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::RSA);
-    if (!xCertificate.is())
-        return;
-    sal_Int32 nSecurityId;
-    aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), 
nSecurityId,
-                 /*bAdESCompliant=*/true);
+        aManager.add(xCertificate, mxSecurityContext, 
/*rDescription=*/OUString(), nSecurityId,
+                     /*bAdESCompliant=*/true);
+        aManager.read(/*bUseTempStream=*/true);
+        {
+            std::vector<SignatureInformation>& rInformations
+                = aManager.getCurrentSignatureInformations();
+            CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
rInformations.size());
+            
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                                 rInformations[1].nStatus);
+        }
 
-    // Read back the signature and make sure that it's valid.
-    aManager.read(/*bUseTempStream=*/true);
-    {
-        std::vector<SignatureInformation>& rInformations
-            = aManager.getCurrentSignatureInformations();
-        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), 
rInformations.size());
-        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
-                             rInformations[0].nStatus);
-    }
+        aManager.add(xCertificate, mxSecurityContext, 
/*rDescription=*/OUString(), nSecurityId,
+                     /*bAdESCompliant=*/true);
+        aManager.read(/*bUseTempStream=*/true);
+        {
+            std::vector<SignatureInformation>& rInformations
+                = aManager.getCurrentSignatureInformations();
+            CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), 
rInformations.size());
+            
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                                 rInformations[2].nStatus);
+        }
 
-    aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), 
nSecurityId,
-                 /*bAdESCompliant=*/true);
-    aManager.read(/*bUseTempStream=*/true);
-    {
-        std::vector<SignatureInformation>& rInformations
-            = aManager.getCurrentSignatureInformations();
-        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
rInformations.size());
-        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
-                             rInformations[1].nStatus);
+        aManager.write(/*bXAdESCompliantIfODF=*/true);
+        uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, 
uno::UNO_QUERY);
+        xTransactedObject->commit();
     }
 
-    aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), 
nSecurityId,
-                 /*bAdESCompliant=*/true);
-    aManager.read(/*bUseTempStream=*/true);
-    {
-        std::vector<SignatureInformation>& rInformations
-            = aManager.getCurrentSignatureInformations();
-        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), 
rInformations.size());
-        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
-                             rInformations[2].nStatus);
-    }
+    Scheduler::ProcessEventsToIdle();
+
+    createDoc(aTempFile.GetURL());
+
+    SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+    CPPUNIT_ASSERT(pBaseModel);
+    SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+    CPPUNIT_ASSERT(pObjectShell);
+    CPPUNIT_ASSERT_EQUAL(SignatureState::OK, 
pObjectShell->GetDocumentSignatureState());
 }
 
 CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
@@ -1060,54 +1078,67 @@ CPPUNIT_TEST_FIXTURE(SigningTest, 
testSigningMultipleTimes_OOXML)
     aMediaDescriptor["FilterName"] <<= OUString("MS Word 2007 XML");
     xStorable->storeAsURL(aTempFile.GetURL(), 
aMediaDescriptor.getAsConstPropertyValueList());
 
-    DocumentSignatureManager aManager(mxComponentContext, 
DocumentSignatureMode::Content);
-    CPPUNIT_ASSERT(aManager.init());
-    uno::Reference<embed::XStorage> xStorage
-        = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
-            ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), 
embed::ElementModes::READWRITE);
-    CPPUNIT_ASSERT(xStorage.is());
-    aManager.setStore(xStorage);
-    aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+    {
+        DocumentSignatureManager aManager(mxComponentContext, 
DocumentSignatureMode::Content);
+        CPPUNIT_ASSERT(aManager.init());
+        uno::Reference<embed::XStorage> xStorage
+            = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+                ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), 
embed::ElementModes::READWRITE);
+        CPPUNIT_ASSERT(xStorage.is());
+        aManager.setStore(xStorage);
+        aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+
+        // Create a signature.
+        uno::Reference<security::XCertificate> xCertificate
+            = getCertificate(aManager, 
svl::crypto::SignatureMethodAlgorithm::ECDSA);
+        if (!xCertificate.is())
+            return;
+
+        sal_Int32 nSecurityId;
+        aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
+        aManager.read(/*bUseTempStream=*/true);
+        {
+            std::vector<SignatureInformation>& rInformations
+                = aManager.getCurrentSignatureInformations();
+            CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), 
rInformations.size());
+            
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                                 rInformations[0].nStatus);
+        }
 
-    // Create a signature.
-    uno::Reference<security::XCertificate> xCertificate
-        = getCertificate(aManager, 
svl::crypto::SignatureMethodAlgorithm::ECDSA);
-    if (!xCertificate.is())
-        return;
+        aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
+        aManager.read(/*bUseTempStream=*/true);
+        {
+            std::vector<SignatureInformation>& rInformations
+                = aManager.getCurrentSignatureInformations();
+            CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
rInformations.size());
+            
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                                 rInformations[1].nStatus);
+        }
 
-    sal_Int32 nSecurityId;
-    aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
-    aManager.read(/*bUseTempStream=*/true);
-    {
-        std::vector<SignatureInformation>& rInformations
-            = aManager.getCurrentSignatureInformations();
-        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), 
rInformations.size());
-        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
-                             rInformations[0].nStatus);
-    }
+        aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
+        aManager.read(/*bUseTempStream=*/true);
+        {
+            std::vector<SignatureInformation>& rInformations
+                = aManager.getCurrentSignatureInformations();
+            CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), 
rInformations.size());
+            
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                                 rInformations[2].nStatus);
+        }
 
-    aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
-    aManager.read(/*bUseTempStream=*/true);
-    {
-        std::vector<SignatureInformation>& rInformations
-            = aManager.getCurrentSignatureInformations();
-        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
rInformations.size());
-        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
-                             rInformations[1].nStatus);
+        aManager.write(/*bXAdESCompliantIfODF=*/true);
+        uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, 
uno::UNO_QUERY);
+        xTransactedObject->commit();
     }
 
-    aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
-    aManager.read(/*bUseTempStream=*/true);
-    {
-        std::vector<SignatureInformation>& rInformations
-            = aManager.getCurrentSignatureInformations();
-        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), 
rInformations.size());
-        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
-                             rInformations[2].nStatus);
-    }
-    aManager.write(/*bXAdESCompliantIfODF=*/true);
-    uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, 
uno::UNO_QUERY);
-    xTransactedObject->commit();
+    Scheduler::ProcessEventsToIdle();
+
+    createDoc(aTempFile.GetURL());
+
+    SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+    CPPUNIT_ASSERT(pBaseModel);
+    SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+    CPPUNIT_ASSERT(pObjectShell);
+    CPPUNIT_ASSERT_EQUAL(SignatureState::PARTIAL_OK, 
pObjectShell->GetDocumentSignatureState());
 }
 
 /// Works with an existing good XAdES signature.
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx 
b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 4797bd8d8796..9267b5458783 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -62,6 +62,7 @@ public:
         return m_xDocumentHandler;
     }
 
+    void writeSignature();
     void writeSignedInfo();
     void writeCanonicalizationMethod();
     void writeCanonicalizationTransform();
@@ -220,7 +221,7 @@ void OOXMLSecExporter::Impl::writeKeyInfo()
 void OOXMLSecExporter::Impl::writePackageObject()
 {
     rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-    pAttributeList->AddAttribute("Id", "idPackageObject");
+    pAttributeList->AddAttribute("Id", "idPackageObject_" + 
m_rInformation.ouSignatureId);
     m_xDocumentHandler->startElement(
         "Object", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
 
@@ -299,8 +300,9 @@ void 
OOXMLSecExporter::Impl::writePackageObjectSignatureProperties()
         "SignatureProperties", uno::Reference<xml::sax::XAttributeList>(new 
SvXMLAttributeList()));
     {
         rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-        pAttributeList->AddAttribute("Id", "idSignatureTime");
-        pAttributeList->AddAttribute("Target", "#idPackageSignature");
+
+        pAttributeList->AddAttribute("Id", "idSignatureTime_" + 
m_rInformation.ouSignatureId);
+        pAttributeList->AddAttribute("Target", "#" + 
m_rInformation.ouSignatureId);
         m_xDocumentHandler->startElement(
             "SignatureProperty", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
     }
@@ -379,7 +381,7 @@ void OOXMLSecExporter::Impl::writeOfficeObject()
 {
     {
         rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-        pAttributeList->AddAttribute("Id", "idOfficeObject");
+        pAttributeList->AddAttribute("Id", "idOfficeObject_" + 
m_rInformation.ouSignatureId);
         m_xDocumentHandler->startElement(
             "Object", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
     }
@@ -387,8 +389,8 @@ void OOXMLSecExporter::Impl::writeOfficeObject()
         "SignatureProperties", uno::Reference<xml::sax::XAttributeList>(new 
SvXMLAttributeList()));
     {
         rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-        pAttributeList->AddAttribute("Id", "idOfficeV1Details");
-        pAttributeList->AddAttribute("Target", "#idPackageSignature");
+        pAttributeList->AddAttribute("Id", "idOfficeV1Details_" + 
m_rInformation.ouSignatureId);
+        pAttributeList->AddAttribute("Target", "#" + 
m_rInformation.ouSignatureId);
         m_xDocumentHandler->startElement(
             "SignatureProperty", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
     }
@@ -476,7 +478,7 @@ void OOXMLSecExporter::Impl::writePackageSignature()
     {
         rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
         pAttributeList->AddAttribute("xmlns:xd", NS_XD);
-        pAttributeList->AddAttribute("Target", "#idPackageSignature");
+        pAttributeList->AddAttribute("Target", "#" + 
m_rInformation.ouSignatureId);
         m_xDocumentHandler->startElement(
             "xd:QualifyingProperties",
             uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
@@ -519,6 +521,25 @@ void OOXMLSecExporter::Impl::writeSignatureLineImages()
     }
 }
 
+void OOXMLSecExporter::Impl::writeSignature()
+{
+    rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
+    pAttributeList->AddAttribute("xmlns", NS_XMLDSIG);
+    pAttributeList->AddAttribute("Id", m_rInformation.ouSignatureId);
+    getDocumentHandler()->startElement(
+        "Signature", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
+
+    writeSignedInfo();
+    writeSignatureValue();
+    writeKeyInfo();
+    writePackageObject();
+    writeOfficeObject();
+    writePackageSignature();
+    writeSignatureLineImages();
+
+    getDocumentHandler()->endElement("Signature");
+}
+
 OOXMLSecExporter::OOXMLSecExporter(
     const uno::Reference<uno::XComponentContext>& xComponentContext,
     const uno::Reference<embed::XStorage>& xRootStorage,
@@ -531,23 +552,6 @@ OOXMLSecExporter::OOXMLSecExporter(
 
 OOXMLSecExporter::~OOXMLSecExporter() = default;
 
-void OOXMLSecExporter::writeSignature()
-{
-    rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-    pAttributeList->AddAttribute("xmlns", NS_XMLDSIG);
-    pAttributeList->AddAttribute("Id", "idPackageSignature");
-    m_pImpl->getDocumentHandler()->startElement(
-        "Signature", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
-
-    m_pImpl->writeSignedInfo();
-    m_pImpl->writeSignatureValue();
-    m_pImpl->writeKeyInfo();
-    m_pImpl->writePackageObject();
-    m_pImpl->writeOfficeObject();
-    m_pImpl->writePackageSignature();
-    m_pImpl->writeSignatureLineImages();
-
-    m_pImpl->getDocumentHandler()->endElement("Signature");
-}
+void OOXMLSecExporter::writeSignature() { m_pImpl->writeSignature(); }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/helper/xsecsign.cxx 
b/xmlsecurity/source/helper/xsecsign.cxx
index e0cda6c43695..8676f70c1041 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -150,14 +150,14 @@ css::uno::Reference< 
css::xml::crypto::sax::XReferenceResolvedListener > XSecCon
     }
     else // OOXML
     {
-        internalSignatureInfor.signatureInfor.ouSignatureId = 
"idPackageSignature";
+        OUString aID = createId();
+        internalSignatureInfor.signatureInfor.ouSignatureId = aID;
 
-        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idPackageObject", -1, OUString());
+        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idPackageObject_" + aID, -1, OUString());
         size++;
-        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idOfficeObject", -1, OUString());
+        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idOfficeObject_" + aID, -1, OUString());
         size++;
-        OUString aId = "idSignedProperties_" +  
internalSignatureInfor.signatureInfor.ouSignatureId;
-        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, aId, -1, OUString());
+        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idSignedProperties_" + aID, -1, OUString());
         size++;
     }
 
commit 3a6f016c6d43a393bdc4aa288ab2501b656e30e9
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Wed Oct 27 14:15:17 2021 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Apr 4 13:51:24 2023 +0200

    xmlsec: signing the document fails the 3rd time (invalid signature)
    
    Signing the document 3 or more times produces an invalid signature.
    The cause of this is that xmlsec is confused because we have 3
    signatures, which all have the same SignedProperties with the ID
    "idSignedProperties", but it expect them to be unique.
    
    This issue is fixed by making the ID unique with adding the ID of
    the Signature to the SignedProperties ID, so this makes them unique
    inside the same Signature.
    
    Also UnsignedProperties have a unique ID usign the same approach,
    but they aren't referenced - luckily.
    
    Change-Id: I53c7249a82fc0623586548db9fa25bdc0e7c4101
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124278
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit fd5463343ab7f784070f1ab87a345eed20803d07)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124327
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    (cherry picked from commit b883bc9d8ca4a9c6037166b2eff09095aef145e0)

diff --git a/xmlsecurity/qa/unit/signing/signing.cxx 
b/xmlsecurity/qa/unit/signing/signing.cxx
index 0f9b52a45367..85fa471d9669 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -917,13 +917,13 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testXAdESNotype)
     // attribute", i.e. the signature without such an attribute was not 
preserved correctly.
     assertXPathNoAttribute(pXmlDoc,
                            
"/odfds:document-signatures/dsig:Signature[1]/dsig:SignedInfo/"
-                           "dsig:Reference[@URI='#idSignedProperties']",
+                           "dsig:Reference[starts-with(@URI, 
'#idSignedProperties')]",
                            "Type");
 
     // New signature always has the Type attribute.
     assertXPath(pXmlDoc,
                 "/odfds:document-signatures/dsig:Signature[2]/dsig:SignedInfo/"
-                "dsig:Reference[@URI='#idSignedProperties']",
+                "dsig:Reference[starts-with(@URI, '#idSignedProperties')]",
                 "Type", "http://uri.etsi.org/01903#SignedProperties";);
 }
 
@@ -982,12 +982,132 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testXAdES)
     // Assert that the digest of the signing certificate is included.
     assertXPath(pXmlDoc, "//xd:CertDigest", 1);
 
-    // Assert that the Type attribute on the idSignedProperties reference is
-    // not missing.
-    assertXPath(pXmlDoc,
-                "/odfds:document-signatures/dsig:Signature/dsig:SignedInfo/"
-                "dsig:Reference[@URI='#idSignedProperties']",
-                "Type", "http://uri.etsi.org/01903#SignedProperties";);
+    // Assert that the Type attribute is set on all URI's that start with 
#idSignedProperties
+    assertXPath(pXmlDoc, "//dsig:Reference[starts-with(@URI, 
'#idSignedProperties')]", "Type",
+                "http://uri.etsi.org/01903#SignedProperties";);
+}
+
+CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT)
+{
+    createDoc("");
+
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("writer8");
+    xStorable->storeAsURL(aTempFile.GetURL(), 
aMediaDescriptor.getAsConstPropertyValueList());
+
+    DocumentSignatureManager aManager(mxComponentContext, 
DocumentSignatureMode::Content);
+    CPPUNIT_ASSERT(aManager.init());
+    uno::Reference<embed::XStorage> xStorage
+        = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+            ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), 
embed::ElementModes::READWRITE);
+    CPPUNIT_ASSERT(xStorage.is());
+    aManager.setStore(xStorage);
+    aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+
+    // Create a signature.
+    uno::Reference<security::XCertificate> xCertificate
+        = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::RSA);
+    if (!xCertificate.is())
+        return;
+    sal_Int32 nSecurityId;
+    aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), 
nSecurityId,
+                 /*bAdESCompliant=*/true);
+
+    // Read back the signature and make sure that it's valid.
+    aManager.read(/*bUseTempStream=*/true);
+    {
+        std::vector<SignatureInformation>& rInformations
+            = aManager.getCurrentSignatureInformations();
+        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), 
rInformations.size());
+        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                             rInformations[0].nStatus);
+    }
+
+    aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), 
nSecurityId,
+                 /*bAdESCompliant=*/true);
+    aManager.read(/*bUseTempStream=*/true);
+    {
+        std::vector<SignatureInformation>& rInformations
+            = aManager.getCurrentSignatureInformations();
+        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
rInformations.size());
+        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                             rInformations[1].nStatus);
+    }
+
+    aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), 
nSecurityId,
+                 /*bAdESCompliant=*/true);
+    aManager.read(/*bUseTempStream=*/true);
+    {
+        std::vector<SignatureInformation>& rInformations
+            = aManager.getCurrentSignatureInformations();
+        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), 
rInformations.size());
+        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                             rInformations[2].nStatus);
+    }
+}
+
+CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
+{
+    createDoc("");
+
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("MS Word 2007 XML");
+    xStorable->storeAsURL(aTempFile.GetURL(), 
aMediaDescriptor.getAsConstPropertyValueList());
+
+    DocumentSignatureManager aManager(mxComponentContext, 
DocumentSignatureMode::Content);
+    CPPUNIT_ASSERT(aManager.init());
+    uno::Reference<embed::XStorage> xStorage
+        = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+            ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), 
embed::ElementModes::READWRITE);
+    CPPUNIT_ASSERT(xStorage.is());
+    aManager.setStore(xStorage);
+    aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+
+    // Create a signature.
+    uno::Reference<security::XCertificate> xCertificate
+        = getCertificate(aManager, 
svl::crypto::SignatureMethodAlgorithm::ECDSA);
+    if (!xCertificate.is())
+        return;
+
+    sal_Int32 nSecurityId;
+    aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
+    aManager.read(/*bUseTempStream=*/true);
+    {
+        std::vector<SignatureInformation>& rInformations
+            = aManager.getCurrentSignatureInformations();
+        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), 
rInformations.size());
+        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                             rInformations[0].nStatus);
+    }
+
+    aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
+    aManager.read(/*bUseTempStream=*/true);
+    {
+        std::vector<SignatureInformation>& rInformations
+            = aManager.getCurrentSignatureInformations();
+        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
rInformations.size());
+        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                             rInformations[1].nStatus);
+    }
+
+    aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, 
/*bAdESCompliant=*/false);
+    aManager.read(/*bUseTempStream=*/true);
+    {
+        std::vector<SignatureInformation>& rInformations
+            = aManager.getCurrentSignatureInformations();
+        CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), 
rInformations.size());
+        
CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+                             rInformations[2].nStatus);
+    }
+    aManager.write(/*bXAdESCompliantIfODF=*/true);
+    uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, 
uno::UNO_QUERY);
+    xTransactedObject->commit();
 }
 
 /// Works with an existing good XAdES signature.
diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx 
b/xmlsecurity/source/helper/documentsignaturehelper.cxx
index ddff308ee52f..65135d758a1a 100644
--- a/xmlsecurity/source/helper/documentsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx
@@ -522,7 +522,7 @@ void DocumentSignatureHelper::writeSignedProperties(
 {
     {
         rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-        pAttributeList->AddAttribute("Id", "idSignedProperties");
+        pAttributeList->AddAttribute("Id", "idSignedProperties_" + 
signatureInfo.ouSignatureId);
         xDocumentHandler->startElement("xd:SignedProperties", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
     }
 
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx 
b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 1e031644b0b5..4797bd8d8796 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -158,7 +158,7 @@ void OOXMLSecExporter::Impl::writeSignedInfoReferences()
         {
             {
                 rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-                if (rReference.ouURI != "idSignedProperties")
+                if (!rReference.ouURI.startsWith("idSignedProperties"))
                     pAttributeList->AddAttribute("Type",
                                                  
"http://www.w3.org/2000/09/xmldsig#Object";);
                 else
@@ -168,7 +168,7 @@ void OOXMLSecExporter::Impl::writeSignedInfoReferences()
                 m_xDocumentHandler->startElement(
                     "Reference", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
             }
-            if (rReference.ouURI == "idSignedProperties")
+            if (rReference.ouURI.startsWith("idSignedProperties"))
             {
                 m_xDocumentHandler->startElement(
                     "Transforms",
diff --git a/xmlsecurity/source/helper/xsecctl.cxx 
b/xmlsecurity/source/helper/xsecctl.cxx
index 6bd88e24f91e..cdfe643bd0f7 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -532,7 +532,7 @@ void writeUnsignedProperties(
 {
     {
         rtl::Reference<SvXMLAttributeList> pAttributeList(new 
SvXMLAttributeList());
-        pAttributeList->AddAttribute("Id", "idUnsignedProperties");
+        pAttributeList->AddAttribute("Id", "idUnsignedProperties_" + 
signatureInfo.ouSignatureId);
         xDocumentHandler->startElement("xd:UnsignedProperties", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
     }
 
@@ -649,16 +649,21 @@ void XSecController::exportSignature(
                  * same-document reference
                  */
                 {
-                    pAttributeList->AddAttribute(
+                    if (refInfor.ouURI.startsWith("idSignedProperties"))
+                    {
+                        pAttributeList->AddAttribute("URI", 
"#idSignedProperties_" + signatureInfo.ouSignatureId);
+                        if (bXAdESCompliantIfODF && !refInfor.ouType.isEmpty())
+                        {
+                            // The reference which points to the 
SignedProperties
+                            // shall have this specific type.
+                            pAttributeList->AddAttribute("Type", 
refInfor.ouType);
+                        }
+                    }
+                    else
+                    {
+                        pAttributeList->AddAttribute(
                         "URI",
                         "#" + refInfor.ouURI);
-
-                    if (bXAdESCompliantIfODF && refInfor.ouURI == 
"idSignedProperties" && !refInfor.ouType.isEmpty())
-                    {
-                        // The reference which points to the SignedProperties
-                        // shall have this specific type.
-                        pAttributeList->AddAttribute("Type",
-                                                     refInfor.ouType);
                     }
                 }
 
diff --git a/xmlsecurity/source/helper/xsecsign.cxx 
b/xmlsecurity/source/helper/xsecsign.cxx
index fd33a320d9bd..e0cda6c43695 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -134,8 +134,9 @@ css::uno::Reference< 
css::xml::crypto::sax::XReferenceResolvedListener > XSecCon
 
         if (bXAdESCompliantIfODF)
         {
+            OUString aId = "idSignedProperties_" +  
internalSignatureInfor.signatureInfor.ouSignatureId;
             // We write a new reference, so it's possible to use the correct 
type URI.
-            
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idSignedProperties", -1, 
"http://uri.etsi.org/01903#SignedProperties";);
+            
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, aId, -1, "http://uri.etsi.org/01903#SignedProperties";);
             size++;
         }
 
@@ -147,13 +148,16 @@ css::uno::Reference< 
css::xml::crypto::sax::XReferenceResolvedListener > XSecCon
             size++;
         }
     }
-    else
+    else // OOXML
     {
+        internalSignatureInfor.signatureInfor.ouSignatureId = 
"idPackageSignature";
+
         
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idPackageObject", -1, OUString());
         size++;
         
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idOfficeObject", -1, OUString());
         size++;
-        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, "idSignedProperties", -1, OUString());
+        OUString aId = "idSignedProperties_" +  
internalSignatureInfor.signatureInfor.ouSignatureId;
+        
internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, 
digestID, aId, -1, OUString());
         size++;
     }
 
commit 8aedae2e182490bbbaa9d8607370911275e4d10a
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu Mar 3 14:22:37 2022 +0000
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Apr 4 13:50:49 2023 +0200

    CVE-2022-26305 compare authors using Thumbprint
    
    Change-Id: I338f58eb07cbf0a3d13a7dafdaddac09252a8546
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130929
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 65442205b5b274ad309308162f150f8d41648f72)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130866
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit a7aaa78acea4c1d51283c2fce54ff9f5339026f8)

diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx 
b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 84b9a80b0c72..dd9192ead0bd 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>
@@ -669,9 +670,23 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
     Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = 
SvtSecurityOptions().GetTrustedAuthors();
 
     return std::any_of(aTrustedAuthors.begin(), aTrustedAuthors.end(),
-        [&xAuthor, &sSerialNum](const SvtSecurityOptions::Certificate& 
rAuthor) {
-            return xmlsecurity::EqualDistinguishedNames(rAuthor[0], 
xAuthor->getIssuerName())
-                && ( rAuthor[1] == sSerialNum );
+        [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();
         });
 }
 

Reply via email to