summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RepositoryExternal.mk4
-rw-r--r--configure.ac122
-rw-r--r--connectivity/source/parse/sqlbison.y6
-rw-r--r--desktop/source/app/cmdlineargs.cxx10
-rw-r--r--download.lst16
-rw-r--r--external/curl/ExternalPackage_curl.mk4
-rw-r--r--external/curl/ExternalProject_curl.mk9
-rw-r--r--external/curl/UnpackedTarball_curl.mk3
-rw-r--r--external/curl/curl-7.26.0_win-proxy.patch2
-rw-r--r--external/curl/curl-ios.patch.117
-rw-r--r--external/curl/curl-msvc-disable-protocols.patch.17
-rw-r--r--external/curl/zlib.patch.04
-rw-r--r--external/expat/expat-winapi.patch11
-rw-r--r--external/gpgmepp/ExternalProject_gpgmepp.mk2
-rw-r--r--external/libassuan/ExternalProject_libassuan.mk2
-rw-r--r--external/libgpg-error/ExternalProject_libgpg-error.mk2
-rw-r--r--external/liblangtag/UnpackedTarball_liblangtag.mk3
-rw-r--r--external/liblangtag/Wformat-overflow.patch17
-rw-r--r--external/libxml2/libxml2-config.patch.14
-rw-r--r--external/libxml2/libxml2-global-symbols.patch4
-rw-r--r--external/nss/ExternalProject_nss.mk8
-rw-r--r--external/nss/UnpackedTarball_nss.mk1
-rw-r--r--external/nss/nsinstall.py12
-rw-r--r--external/nss/nss-android.patch.16
-rw-r--r--external/nss/nss-ios.patch6
-rw-r--r--external/nss/nss.getopt.patch.025
-rw-r--r--external/openssl/UnpackedTarball_openssl.mk1
-rw-r--r--external/openssl/ccb0a11145ee72b042d10593a64eaf9e8a55ec12.patch.156
-rw-r--r--external/xmlsec/0001-xmlSecX509DataGetNodeContent-don-t-return-0-for-non-.patch.168
-rw-r--r--external/xmlsec/UnpackedTarball_xmlsec.mk1
-rw-r--r--filter/source/graphicfilter/icgm/bitmap.cxx10
-rw-r--r--include/svl/sigstruct.hxx42
-rw-r--r--include/svx/sdr/table/tablecontroller.hxx1
-rw-r--r--include/svx/selectioncontroller.hxx2
-rw-r--r--include/vcl/BitmapTools.hxx3
-rw-r--r--include/xmloff/xmlimp.hxx6
-rw-r--r--include/xmloff/xmlnmspe.hxx10
-rw-r--r--include/xmloff/xmltoken.hxx13
-rw-r--r--instsetoo_native/inc_openoffice/unix/find-requires-x11.sh4
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx5
-rw-r--r--lotuswordpro/qa/cppunit/data/pass/ofz20517-1.lwpbin0 -> 21429 bytes
-rw-r--r--lotuswordpro/source/filter/lwprowlayout.cxx11
-rw-r--r--lotuswordpro/source/filter/lwptablelayout.cxx9
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx43
-rw-r--r--sc/source/ui/docshell/docfunc.cxx3
-rw-r--r--sc/source/ui/view/dbfunc3.cxx10
-rw-r--r--sc/source/ui/view/viewdata.cxx6
-rw-r--r--sc/source/ui/view/viewfunc.cxx16
-rw-r--r--sfx2/source/appl/macroloader.cxx9
-rw-r--r--sfx2/source/doc/iframe.cxx20
-rw-r--r--sfx2/source/inc/macroloader.hxx2
-rw-r--r--shell/source/unix/exec/shellexec.cxx14
-rw-r--r--solenv/bin/modules/installer/simplepackage.pm2
-rw-r--r--svl/source/crypto/cryptosign.cxx16
-rw-r--r--svx/source/svdraw/selectioncontroller.cxx4
-rw-r--r--svx/source/svdraw/svdview.cxx29
-rw-r--r--svx/source/table/svdotable.cxx7
-rw-r--r--svx/source/table/tablecontroller.cxx45
-rw-r--r--sw/source/core/edit/edfcol.cxx3
-rw-r--r--sw/source/filter/basflt/fltshell.cxx5
-rw-r--r--sw/source/filter/html/htmlplug.cxx7
-rw-r--r--sw/source/filter/ww8/ww8scan.cxx37
-rw-r--r--sw/source/filter/ww8/ww8scan.hxx6
-rw-r--r--sw/source/filter/xml/xmltexti.cxx9
-rw-r--r--sw/source/uibase/uiview/uivwimp.cxx2
-rw-r--r--vcl/source/app/salvtables.cxx3
-rw-r--r--vcl/source/control/button.cxx2
-rw-r--r--vcl/source/font/fontcharmap.cxx18
-rw-r--r--vcl/source/window/dialog.cxx2
-rw-r--r--vcl/source/window/mouse.cxx19
-rw-r--r--vcl/source/window/toolbox.cxx2
-rw-r--r--vcl/source/window/window.cxx4
-rw-r--r--vcl/source/window/winproc.cxx47
-rw-r--r--wizards/source/access2base/DoCmd.xba2
-rw-r--r--xmloff/source/core/xmlimp.cxx26
-rw-r--r--xmloff/source/core/xmltoken.cxx13
-rw-r--r--xmloff/source/draw/ximpshap.cxx4
-rw-r--r--xmloff/source/token/tokens.txt10
-rw-r--r--xmlsecurity/inc/biginteger.hxx3
-rw-r--r--xmlsecurity/inc/xmlsec-wrapper.h4
-rw-r--r--xmlsecurity/inc/xmlsignaturehelper.hxx12
-rw-r--r--xmlsecurity/inc/xsecctl.hxx20
-rw-r--r--xmlsecurity/qa/unit/signing/data/02_doc_macros_signed_by_attacker_manipulated.odtbin0 -> 14045 bytes
-rw-r--r--xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated.odtbin0 -> 13139 bytes
-rw-r--r--xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated2.odtbin0 -> 13160 bytes
-rw-r--r--xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated_triple.odtbin0 -> 13237 bytes
-rw-r--r--xmlsecurity/qa/unit/signing/data/02_doc_signed_by_trusted_person_manipulated.odtbin0 -> 14003 bytes
-rw-r--r--xmlsecurity/qa/unit/signing/data/signed_with_x509certificate_chain.odtbin0 -> 13585 bytes
-rw-r--r--xmlsecurity/qa/unit/signing/signing.cxx135
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.cxx50
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx15
-rw-r--r--xmlsecurity/source/helper/documentsignaturehelper.cxx63
-rw-r--r--xmlsecurity/source/helper/documentsignaturemanager.cxx12
-rw-r--r--xmlsecurity/source/helper/ooxmlsecexporter.cxx23
-rw-r--r--xmlsecurity/source/helper/ooxmlsecparser.cxx1458
-rw-r--r--xmlsecurity/source/helper/ooxmlsecparser.hxx75
-rw-r--r--xmlsecurity/source/helper/pdfsignaturehelper.cxx8
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx162
-rw-r--r--xmlsecurity/source/helper/xsecctl.cxx194
-rw-r--r--xmlsecurity/source/helper/xsecparser.cxx1706
-rw-r--r--xmlsecurity/source/helper/xsecparser.hxx106
-rw-r--r--xmlsecurity/source/helper/xsecsign.cxx60
-rw-r--r--xmlsecurity/source/helper/xsecverify.cxx227
-rw-r--r--xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx4
-rw-r--r--xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx47
-rw-r--r--xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx6
-rw-r--r--xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx25
-rw-r--r--xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx8
108 files changed, 4326 insertions, 1093 deletions
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 5db8ff9b9f06..3f15773b9f36 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -1558,7 +1558,7 @@ $(call gb_ExternalProject_use_package,$(1),openssl)
endef
define gb_LinkTarget__use_openssl_headers
-$(call gb_LinkTarget_use_external_project,$(1),openssl)
+$(call gb_LinkTarget_use_external_project,$(1),openssl,full)
$(call gb_LinkTarget_set_include,$(1),\
-I$(call gb_UnpackedTarball_get_dir,openssl)/include \
$$(INCLUDE) \
@@ -2753,7 +2753,7 @@ $(call gb_LinkTarget_set_include,$(1),\
ifeq ($(COM),MSC)
$(call gb_LinkTarget_add_libs,$(1),\
- $(call gb_UnpackedTarball_get_dir,curl)/builds/libcurl-vc12-$(if $(filter X86_64,$(CPUNAME)),x64,x86)-$(if $(MSVC_USE_DEBUG_RUNTIME),debug,release)-dll-ipv6-sspi-winssl/lib/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).lib \
+ $(call gb_UnpackedTarball_get_dir,curl)/builds/libcurl-vc12-$(if $(filter X86_64,$(CPUNAME)),x64,x86)-$(if $(MSVC_USE_DEBUG_RUNTIME),debug,release)-dll-ipv6-sspi-schannel/lib/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).lib \
)
else
$(call gb_LinkTarget_add_libs,$(1),\
diff --git a/configure.ac b/configure.ac
index 74fa63e31fe7..3d894cfbdd4e 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.2.10.30],[],[],[https://collaboraoffice.com/])
+AC_INIT([Collabora Office],[6.2.10.36],[],[],[https://collaboraoffice.com/])
AC_PREREQ([2.59])
@@ -2736,7 +2736,7 @@ dnl ENABLE_JAVA="TRUE" if we want there to be *run-time* (and build-time) suppor
dnl ENABLE_JAVA="" indicate no Java support at all
dnl ===================================================================
-dnl Check OS X SDK and compiler
+dnl Check macOS SDK and compiler
dnl ===================================================================
if test $_os = Darwin; then
@@ -2749,8 +2749,8 @@ if test $_os = Darwin; then
# For developers with a current Xcode, the lowest-numbered SDK
# higher than or equal to the minimum required should be found.
- AC_MSG_CHECKING([what Mac OS X SDK to use])
- for _macosx_sdk in ${with_macosx_sdk-11.1 10.15 10.14 10.13 10.12}; do
+ AC_MSG_CHECKING([what macOS SDK to use])
+ for _macosx_sdk in ${with_macosx_sdk-11.3 11.1 11.0 10.15 10.14 10.13}; do
MACOSX_SDK_PATH=`xcrun --sdk macosx${_macosx_sdk} --show-sdk-path 2> /dev/null`
if test -d "$MACOSX_SDK_PATH"; then
with_macosx_sdk="${_macosx_sdk}"
@@ -2764,24 +2764,12 @@ if test $_os = Darwin; then
fi
done
if test ! -d "$MACOSX_SDK_PATH"; then
- AC_MSG_ERROR([Could not find an appropriate Mac OS X SDK])
+ AC_MSG_ERROR([Could not find an appropriate macOS SDK])
fi
- if test $_os = iOS; then
- if test "$enable_ios_simulator" = "yes"; then
- useos=iphonesimulator
- else
- useos=iphoneos
- fi
- MACOSX_SDK_PATH=`xcrun --sdk ${useos} --show-sdk-path 2> /dev/null`
- fi
AC_MSG_RESULT([SDK $with_macosx_sdk at $MACOSX_SDK_PATH])
-
case $with_macosx_sdk in
- 10.12)
- MACOSX_SDK_VERSION=101200
- ;;
10.13)
MACOSX_SDK_VERSION=101300
;;
@@ -2791,16 +2779,30 @@ if test $_os = Darwin; then
10.15)
MACOSX_SDK_VERSION=101500
;;
+ 11.0)
+ MACOSX_SDK_VERSION=110000
+ ;;
11.1)
MACOSX_SDK_VERSION=110100
;;
+ 11.3)
+ MACOSX_SDK_VERSION=110300
+ ;;
*)
- AC_MSG_ERROR([with-macosx-sdk $with_macosx_sdk is not a supported value, supported values are 10.12--11.1])
+ AC_MSG_ERROR([with-macosx-sdk $with_macosx_sdk is not a supported value, supported values are 10.13--11.3])
;;
esac
+ if test "$host_cpu" = arm64 -a $MACOSX_SDK_VERSION -lt 110000; then
+ AC_MSG_ERROR([with-macosx-sdk $with_macosx_sdk is not a supported value for Apple Silicon])
+ fi
+
if test "$with_macosx_version_min_required" = "" ; then
- with_macosx_version_min_required="10.9";
+ if test "$host_cpu" = x86_64; then
+ with_macosx_version_min_required="10.10";
+ else
+ with_macosx_version_min_required="11.0";
+ fi
fi
if test "$with_macosx_version_max_allowed" = "" ; then
@@ -2814,10 +2816,17 @@ if test $_os = Darwin; then
FRAMEWORKSHOME="$MACOSX_SDK_PATH/System/Library/Frameworks"
MACOSX_DEPLOYMENT_TARGET="$with_macosx_version_min_required"
+ AC_MSG_CHECKING([whether Xcode is new enough])
+ my_xcode_ver1=$(xcrun xcodebuild -version | head -n 1)
+ my_xcode_ver2=${my_xcode_ver1#Xcode }
+ my_xcode_ver3=$(printf %s "$my_xcode_ver2" | $AWK -F. '{ print $1*100+($2<100?$2:99) }')
+ if test "$my_xcode_ver3" -ge 1103; then
+ AC_MSG_RESULT([yes ($my_xcode_ver2)])
+ else
+ AC_MSG_ERROR(["$my_xcode_ver1" is too old or unrecognized, must be at least Xcode 11.3])
+ fi
+
case "$with_macosx_version_min_required" in
- 10.9)
- MAC_OS_X_VERSION_MIN_REQUIRED="1090"
- ;;
10.10)
MAC_OS_X_VERSION_MIN_REQUIRED="101000"
;;
@@ -2836,35 +2845,59 @@ if test $_os = Darwin; then
10.15)
MAC_OS_X_VERSION_MIN_REQUIRED="101500"
;;
+ 10.16)
+ MAC_OS_X_VERSION_MIN_REQUIRED="101600"
+ ;;
+ 11.0)
+ MAC_OS_X_VERSION_MIN_REQUIRED="110000"
+ ;;
+ 11.1)
+ MAC_OS_X_VERSION_MIN_REQUIRED="110100"
+ ;;
+ 11.3)
+ MAC_OS_X_VERSION_MIN_REQUIRED="110300"
+ ;;
*)
- AC_MSG_ERROR([with-macosx-version-min-required $with_macosx_version_min_required is not a supported value, supported values are 10.9--15])
+ AC_MSG_ERROR([with-macosx-version-min-required $with_macosx_version_min_required is not a supported value, supported values are 10.10--11.3])
;;
esac
- MAC_OS_X_VERSION_MIN_REQUIRED_DOTS=$with_macosx_version_min_required
LIBTOOL=/usr/bin/libtool
INSTALL_NAME_TOOL=install_name_tool
if test -z "$save_CC"; then
- AC_MSG_CHECKING([what compiler to use])
stdlib=-stdlib=libc++
- if test "$ENABLE_LTO" = TRUE; then
- lto=-flto
+
+ AC_MSG_CHECKING([what C compiler to use])
+ CC="`xcrun -find clang`"
+ CC_BASE=`first_arg_basename "$CC"`
+ if test "$host_cpu" = x86_64; then
+ CC+=" -target x86_64-apple-macos"
+ else
+ CC+=" -target arm64-apple-macos"
fi
- CC="`xcrun -find clang` -m64 $lto -mmacosx-version-min=$with_macosx_version_min_required -isysroot $MACOSX_SDK_PATH"
- CXX="`xcrun -find clang++` -m64 $lto $stdlib -mmacosx-version-min=$with_macosx_version_min_required -isysroot $MACOSX_SDK_PATH"
+ CC+=" -mmacosx-version-min=$with_macosx_version_min_required -isysroot $MACOSX_SDK_PATH"
+ AC_MSG_RESULT([$CC])
+
+ AC_MSG_CHECKING([what C++ compiler to use])
+ CXX="`xcrun -find clang++`"
+ CXX_BASE=`first_arg_basename "$CXX"`
+ if test "$host_cpu" = x86_64; then
+ CXX+=" -target x86_64-apple-macos"
+ else
+ CXX+=" -target arm64-apple-macos"
+ fi
+ CXX+=" $stdlib -mmacosx-version-min=$with_macosx_version_min_required -isysroot $MACOSX_SDK_PATH"
+ AC_MSG_RESULT([$CXX])
+
INSTALL_NAME_TOOL=`xcrun -find install_name_tool`
AR=`xcrun -find ar`
NM=`xcrun -find nm`
STRIP=`xcrun -find strip`
LIBTOOL=`xcrun -find libtool`
RANLIB=`xcrun -find ranlib`
- AC_MSG_RESULT([$CC and $CXX])
fi
case "$with_macosx_version_max_allowed" in
- 10.9)
- MAC_OS_X_VERSION_MAX_ALLOWED="1090"
- ;;
10.10)
MAC_OS_X_VERSION_MAX_ALLOWED="101000"
;;
@@ -2883,17 +2916,23 @@ if test $_os = Darwin; then
10.15)
MAC_OS_X_VERSION_MAX_ALLOWED="101500"
;;
+ 11.0)
+ MAC_OS_X_VERSION_MAX_ALLOWED="110000"
+ ;;
11.1)
MAC_OS_X_VERSION_MAX_ALLOWED="110100"
;;
+ 11.3)
+ MAC_OS_X_VERSION_MAX_ALLOWED="110300"
+ ;;
*)
- AC_MSG_ERROR([with-macosx-version-max-allowed $with_macosx_version_max_allowed is not a supported value, supported values are 10.9--11.1])
+ AC_MSG_ERROR([with-macosx-version-max-allowed $with_macosx_version_max_allowed is not a supported value, supported values are 10.10--11.3])
;;
esac
AC_MSG_CHECKING([that macosx-version-min-required is coherent with macosx-version-max-allowed])
if test $MAC_OS_X_VERSION_MIN_REQUIRED -gt $MAC_OS_X_VERSION_MAX_ALLOWED; then
- AC_MSG_ERROR([the version minimumn required, $MAC_OS_X_VERSION_MIN_REQUIRED, must be <= the version maximum allowed, $MAC_OS_X_VERSION_MAX_ALLOWED])
+ AC_MSG_ERROR([the version minimum required, $MAC_OS_X_VERSION_MIN_REQUIRED, must be <= the version maximum allowed, $MAC_OS_X_VERSION_MAX_ALLOWED])
else
AC_MSG_RESULT([ok])
fi
@@ -2964,11 +3003,9 @@ if test $_os = Darwin; then
AC_MSG_CHECKING([whether to sandbox the application])
- if test -z "$MACOSX_CODESIGNING_IDENTITY" -a "$enable_macosx_sandbox" = yes; then
- AC_MSG_ERROR([OS X sandboxing requires code signing])
- elif test -n "$ENABLE_JAVA" -a "$enable_macosx_sandbox" = yes; then
- AC_MSG_ERROR([OS X sandboxing (actually App Store rules) disallows use of Java])
- elif test -n "$MACOSX_CODESIGNING_IDENTITY" -a "$enable_macosx_sandbox" = yes; then
+ if test -n "$ENABLE_JAVA" -a "$enable_macosx_sandbox" = yes; then
+ AC_MSG_ERROR([macOS sandboxing (actually App Store rules) disallows use of Java])
+ elif test "$enable_macosx_sandbox" = yes; then
ENABLE_MACOSX_SANDBOX=TRUE
AC_DEFINE(HAVE_FEATURE_MACOSX_SANDBOX)
AC_MSG_RESULT([yes])
@@ -2976,17 +3013,16 @@ if test $_os = Darwin; then
AC_MSG_RESULT([no])
fi
- AC_MSG_CHECKING([what OS X app bundle identifier to use])
+ AC_MSG_CHECKING([what macOS app bundle identifier to use])
MACOSX_BUNDLE_IDENTIFIER=$with_macosx_bundle_identifier
AC_MSG_RESULT([$MACOSX_BUNDLE_IDENTIFIER])
fi
AC_SUBST(MACOSX_SDK_PATH)
AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
AC_SUBST(MAC_OS_X_VERSION_MIN_REQUIRED)
-AC_SUBST(MAC_OS_X_VERSION_MIN_REQUIRED_DOTS)
AC_SUBST(MAC_OS_X_VERSION_MAX_ALLOWED)
AC_SUBST(INSTALL_NAME_TOOL)
-AC_SUBST(LIBTOOL) # Note that the OS X libtool command is unrelated to GNU libtool
+AC_SUBST(LIBTOOL) # Note that the macOS libtool command is unrelated to GNU libtool
AC_SUBST(MACOSX_CODESIGNING_IDENTITY)
AC_SUBST(MACOSX_PACKAGE_SIGNING_IDENTITY)
AC_SUBST(ENABLE_MACOSX_SANDBOX)
diff --git a/connectivity/source/parse/sqlbison.y b/connectivity/source/parse/sqlbison.y
index a93f3401cabc..0d2853e73105 100644
--- a/connectivity/source/parse/sqlbison.y
+++ b/connectivity/source/parse/sqlbison.y
@@ -74,9 +74,15 @@ inline connectivity::OSQLInternalNode* newNode(const OUString& _newValue,
// yyi is the internal number of the rule that is currently being reduced
// This can be mapped to external rule number via the yyrmap.
+#if defined YYBISON && YYBISON >= 30800
+#define SQL_NEW_RULE newNode("", SQLNodeType::Rule, yyr1[yyrule])
+#define SQL_NEW_LISTRULE newNode("", SQLNodeType::ListRule, yyr1[yyrule])
+#define SQL_NEW_COMMALISTRULE newNode("", SQLNodeType::CommaListRule, yyr1[yyrule])
+#else
#define SQL_NEW_RULE newNode("", SQLNodeType::Rule, yyr1[yyn])
#define SQL_NEW_LISTRULE newNode("", SQLNodeType::ListRule, yyr1[yyn])
#define SQL_NEW_COMMALISTRULE newNode("", SQLNodeType::CommaListRule, yyr1[yyn])
+#endif
extern connectivity::OSQLParser* xxx_pGLOBAL_SQLPARSER;
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
index 381147cd534e..846714158e25 100644
--- a/desktop/source/app/cmdlineargs.cxx
+++ b/desktop/source/app/cmdlineargs.cxx
@@ -29,6 +29,7 @@
#include <tools/stream.hxx>
#include <vcl/svapp.hxx>
#include <rtl/uri.hxx>
+#include <tools/urlobj.hxx>
#include <rtl/ustring.hxx>
#include <rtl/process.h>
#include <comphelper/lok.hxx>
@@ -169,7 +170,14 @@ CommandLineEvent CheckOfficeURI(/* in,out */ OUString& arg, CommandLineEvent cur
}
if (nURIlen < 0)
nURIlen = rest2.getLength();
- arg = rest2.copy(0, nURIlen);
+ auto const uri = rest2.copy(0, nURIlen);
+ if (INetURLObject(uri).GetProtocol() == INetProtocol::Macro) {
+ // Let the "Open" machinery process the full command URI (leading to failure, by intention,
+ // as the "Open" machinery does not know about those command URI schemes):
+ curEvt = CommandLineEvent::Open;
+ } else {
+ arg = uri;
+ }
return curEvt;
}
diff --git a/download.lst b/download.lst
index 5a4ad84c0e46..3473daf8e1ab 100644
--- a/download.lst
+++ b/download.lst
@@ -29,8 +29,8 @@ export CPPUNIT_SHA256SUM := 3d569869d27b48860210c758c4f313082103a5e58219a7669b52
export CPPUNIT_TARBALL := cppunit-1.14.0.tar.gz
export CT2N_SHA256SUM := 71b238efd2734be9800af07566daea8d6685aeed28db5eb5fa0e6453f4d85de3
export CT2N_TARBALL := 1f467e5bb703f12cbbb09d5cf67ecf4a-converttexttonumber-1-5-0.oxt
-export CURL_SHA256SUM := cdf18794393d8bead915312708a9e5d819c6e9919de14b20d5c8e7987abd9772
-export CURL_TARBALL := curl-7.71.0.tar.xz
+export CURL_SHA256SUM := be42766d5664a739c3974ee3dfbbcbe978a4ccb1fe628bb1d9b59ac79e445fb5
+export CURL_TARBALL := curl-7.78.0.tar.xz
export EBOOK_SHA256SUM := 7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9
export EBOOK_TARBALL := libe-book-0.1.3.tar.xz
export EPOXY_SHA256SUM := 002958c5528321edd53440235d3c44e71b5b1e09b9177e8daf677450b6c4433d
@@ -42,8 +42,8 @@ export EPUBGEN_TARBALL := libepubgen-0.1.1.tar.xz
export ETONYEK_SHA256SUM := e61677e8799ce6e55b25afc11aa5339113f6a49cff031f336e32fa58635b1a4a
export ETONYEK_VERSION_MICRO := 9
export ETONYEK_TARBALL := libetonyek-0.1.$(ETONYEK_VERSION_MICRO).tar.xz
-export EXPAT_SHA256SUM := 9a130948b05a82da34e4171d5f5ae5d321d9630277af02c8fa51e431f6475102
-export EXPAT_TARBALL := expat-2.2.8.tar.bz2
+export EXPAT_SHA256SUM := f2af8fc7cdc63a87920da38cd6d12cb113c3c3a3f437495b1b6541e0cff32579
+export EXPAT_TARBALL := expat-2.4.5.tar.xz
export FIREBIRD_SHA256SUM := 6994be3555e23226630c587444be19d309b25b0fcf1f87df3b4e3f88943e5860
export FIREBIRD_TARBALL := Firebird-3.0.0.32483-0.tar.bz2
export FONTCONFIG_SHA256SUM := 19e5b1bc9d013a52063a44e1307629711f0bfef35b9aca16f9c793971e2eb1e5
@@ -178,8 +178,8 @@ export LIBTOMMATH_SHA256SUM := 083daa92d8ee6f4af96a6143b12d7fc8fe1a547e14f862304
export LIBTOMMATH_TARBALL := ltm-1.0.zip
export XMLSEC_SHA256SUM := 13eec4811ea30e3f0e16a734d1dbf7f9d246a71d540b48d143a07b489f6222d4
export XMLSEC_TARBALL := xmlsec1-1.2.28.tar.gz
-export LIBXML_SHA256SUM := aafee193ffb8fe0c82d4afef6ef91972cbaf5feea100edc2f262750611b4be1f
-export LIBXML_VERSION_MICRO := 10
+export LIBXML_SHA256SUM := c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92
+export LIBXML_VERSION_MICRO := 12
export LIBXML_TARBALL := libxml2-2.9.$(LIBXML_VERSION_MICRO).tar.gz
export LIBXSLT_SHA256SUM := 98b1bd46d6792925ad2dfe9a87452ea2adebf69dcb9919ffd55bf926a7f93f7f
export LIBXSLT_VERSION_MICRO := 34
@@ -203,8 +203,8 @@ export MYTHES_SHA256SUM := 1e81f395d8c851c3e4e75b568e20fa2fa549354e75ab397f9de4b
export MYTHES_TARBALL := a8c2c5b8f09e7ede322d5c602ff6a4b6-mythes-1.2.4.tar.gz
export NEON_SHA256SUM := db0bd8cdec329b48f53a6f00199c92d5ba40b0f015b153718d1b15d3d967fbca
export NEON_TARBALL := neon-0.30.2.tar.gz
-export NSS_SHA256SUM := ec6032d78663c6ef90b4b83eb552dedf721d2bce208cec3bf527b8f637db7e45
-export NSS_TARBALL := nss-3.55-with-nspr-4.27.tar.gz
+export NSS_SHA256SUM := 07a9e5b70f121a62706140d4cacc3006d3efb869da40f3a2bf7a65d37847f4d9
+export NSS_TARBALL := nss-3.73-with-nspr-4.32.tar.gz
export ODFGEN_SHA256SUM := 2c7b21892f84a4c67546f84611eccdad6259875c971e98ddb027da66ea0ac9c2
export ODFGEN_VERSION_MICRO := 6
export ODFGEN_TARBALL := libodfgen-0.1.$(ODFGEN_VERSION_MICRO).tar.bz2
diff --git a/external/curl/ExternalPackage_curl.mk b/external/curl/ExternalPackage_curl.mk
index 8da569e3e0cf..1fb360c85ca9 100644
--- a/external/curl/ExternalPackage_curl.mk
+++ b/external/curl/ExternalPackage_curl.mk
@@ -14,13 +14,13 @@ $(eval $(call gb_ExternalPackage_use_external_project,curl,curl))
ifneq ($(DISABLE_DYNLOADING),TRUE)
ifeq ($(COM),MSC)
-$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).dll,builds/libcurl-vc12-$(if $(filter X86_64,$(CPUNAME)),x64,x86)-$(if $(MSVC_USE_DEBUG_RUNTIME),debug,release)-dll-ipv6-sspi-winssl/bin/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).dll))
+$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).dll,builds/libcurl-vc12-$(if $(filter X86_64,$(CPUNAME)),x64,x86)-$(if $(MSVC_USE_DEBUG_RUNTIME),debug,release)-dll-ipv6-sspi-schannel/bin/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).dll))
else ifeq ($(OS),MACOSX)
$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.4.dylib,lib/.libs/libcurl.4.dylib))
else ifeq ($(OS),AIX)
$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.so,lib/.libs/libcurl.so.4))
else
-$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.so.4,lib/.libs/libcurl.so.4.6.0))
+$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.so.4,lib/.libs/libcurl.so.4.7.0))
endif
endif # $(DISABLE_DYNLOADING)
diff --git a/external/curl/ExternalProject_curl.mk b/external/curl/ExternalProject_curl.mk
index b1029ea779e3..81886b36fbc5 100644
--- a/external/curl/ExternalProject_curl.mk
+++ b/external/curl/ExternalProject_curl.mk
@@ -35,13 +35,13 @@ ifeq ($(SYSTEM_NSS),)
curl_CPPFLAGS += -I$(call gb_UnpackedTarball_get_dir,nss)/dist/public/nss
endif
-# use --with-darwinssl on Mac OS X >10.5 and iOS to get a native UI for SSL certs for CMIS usage
+# use --with-secure-transport on Mac OS X >10.5 and iOS to get a native UI for SSL certs for CMIS usage
# use --with-nss only on platforms other than Mac OS X and iOS
$(call gb_ExternalProject_get_state_target,curl,build):
$(call gb_ExternalProject_run,build,\
./configure \
- $(if $(filter iOS MACOSX,$(OS)),\
- --with-darwinssl,\
+ $(if $(filter IOS MACOSX,$(OS)),\
+ --with-secure-transport,\
$(if $(ENABLE_NSS),--with-nss$(if $(SYSTEM_NSS),,="$(call gb_UnpackedTarball_get_dir,nss)/dist/out"),--without-nss)) \
--without-ssl --without-gnutls --without-polarssl --without-cyassl --without-axtls --without-mbedtls \
--enable-ftp --enable-http --enable-ipv6 \
@@ -49,7 +49,8 @@ $(call gb_ExternalProject_get_state_target,curl,build):
--without-libssh2 --without-metalink --without-nghttp2 \
--without-libssh --without-brotli \
--without-ngtcp2 --without-quiche \
- --disable-ares \
+ --without-zstd --without-hyper --without-gsasl --without-gssapi \
+ --disable-mqtt --disable-ares \
--disable-dict --disable-file --disable-gopher --disable-imap \
--disable-ldap --disable-ldaps --disable-manual --disable-pop3 \
--disable-rtsp --disable-smb --disable-smtp --disable-telnet \
diff --git a/external/curl/UnpackedTarball_curl.mk b/external/curl/UnpackedTarball_curl.mk
index 6171f17cba48..1cdb64c0bca2 100644
--- a/external/curl/UnpackedTarball_curl.mk
+++ b/external/curl/UnpackedTarball_curl.mk
@@ -11,8 +11,6 @@ $(eval $(call gb_UnpackedTarball_UnpackedTarball,curl))
$(eval $(call gb_UnpackedTarball_set_tarball,curl,$(CURL_TARBALL),,curl))
-$(eval $(call gb_UnpackedTarball_update_autoconf_configs,curl))
-
$(eval $(call gb_UnpackedTarball_set_patchlevel,curl,1))
$(eval $(call gb_UnpackedTarball_fix_end_of_line,curl,\
@@ -24,7 +22,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,curl,\
external/curl/curl-msvc-disable-protocols.patch.1 \
external/curl/curl-7.26.0_win-proxy.patch \
external/curl/zlib.patch.0 \
- external/curl/curl-ios.patch.1 \
))
ifeq ($(SYSTEM_NSS),)
diff --git a/external/curl/curl-7.26.0_win-proxy.patch b/external/curl/curl-7.26.0_win-proxy.patch
index 5361433a917b..5bb98fa04741 100644
--- a/external/curl/curl-7.26.0_win-proxy.patch
+++ b/external/curl/curl-7.26.0_win-proxy.patch
@@ -114,7 +114,7 @@
@@ -4663,6 +4739,7 @@
}
if(proxy)
- infof(conn->data, "Uses proxy env variable %s == '%s'\n", envp, proxy);
+ infof(data, "Uses proxy env variable %s == '%s'", envp, proxy);
+#endif /* WIN32 */
return proxy;
diff --git a/external/curl/curl-ios.patch.1 b/external/curl/curl-ios.patch.1
deleted file mode 100644
index 1c8fd8f70566..000000000000
--- a/external/curl/curl-ios.patch.1
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- Mode: Diff -*-
-#
-# We don't want curl's configure script to add a -mmacosx-version-min
-# option when it is for iOS we are building. In that case already $CC
-# contains a -miphoneos-version-min option.
-
---- curl/configure
-+++ curl/configure
-@@ -18976,7 +18976,7 @@
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for *version-min in CFLAGS" >&5
- $as_echo_n "checking for *version-min in CFLAGS... " >&6; }
- min=""
-- if test -z "$(echo $CFLAGS | grep m.*os.*-version-min)"; then
-+ if test -z "$(echo $CC $CFLAGS | grep m.*os.*-version-min)"; then
- min="-mmacosx-version-min=10.8"
- CFLAGS="$CFLAGS $min"
- fi
diff --git a/external/curl/curl-msvc-disable-protocols.patch.1 b/external/curl/curl-msvc-disable-protocols.patch.1
index c8747a5fcc1d..a6d06c69b004 100644
--- a/external/curl/curl-msvc-disable-protocols.patch.1
+++ b/external/curl/curl-msvc-disable-protocols.patch.1
@@ -2,18 +2,19 @@ disable protocols nobody needs in MSVC build
--- curl/lib/config-win32.h.orig 2017-08-09 16:43:29.464000000 +0200
+++ curl/lib/config-win32.h 2017-08-09 16:47:38.549200000 +0200
-@@ -733,4 +733,19 @@
+@@ -733,4 +733,20 @@
# define ENABLE_IPV6 1
#endif
+#define CURL_DISABLE_DICT 1
+#define CURL_DISABLE_FILE 1
-+//#undef CURL_DISABLE_FTP
++#undef CURL_DISABLE_FTP
+#define CURL_DISABLE_GOPHER 1
-+//#undef CURL_DISABLE_HTTP
++#undef CURL_DISABLE_HTTP
+#define CURL_DISABLE_IMAP 1
+#define CURL_DISABLE_LDAP 1
+#define CURL_DISABLE_LDAPS 1
++#define CURL_DISABLE_MQTT 1
+#define CURL_DISABLE_POP3 1
+#define CURL_DISABLE_RTSP 1
+#define CURL_DISABLE_SMB 1
diff --git a/external/curl/zlib.patch.0 b/external/curl/zlib.patch.0
index 189e820d1afa..f4a0ad4b152f 100644
--- a/external/curl/zlib.patch.0
+++ b/external/curl/zlib.patch.0
@@ -54,8 +54,8 @@
clean_LIBS=$LIBS
-ZLIB_LIBS=""
AC_ARG_WITH(zlib,
- AC_HELP_STRING([--with-zlib=PATH],[search for zlib in PATH])
- AC_HELP_STRING([--without-zlib],[disable use of zlib]),
+ AS_HELP_STRING([--with-zlib=PATH],[search for zlib in PATH])
+ AS_HELP_STRING([--without-zlib],[disable use of zlib]),
[OPT_ZLIB="$withval"])
if test "$OPT_ZLIB" = "no" ; then
diff --git a/external/expat/expat-winapi.patch b/external/expat/expat-winapi.patch
index b33c12b83b4c..7eae7d5d6139 100644
--- a/external/expat/expat-winapi.patch
+++ b/external/expat/expat-winapi.patch
@@ -11,3 +11,14 @@
# endif
#endif /* not defined XML_STATIC */
+--- misc/expat-2.1.0/lib/xmlparse.c 2021-05-23 16:56:25.000000000 +0100
++++ misc/build/expat-2.1.0/lib/xmlparse.c 2021-05-25 12:42:11.997173600 +0100
+@@ -64,6 +64,8 @@
+ #endif
+
+ #ifdef _WIN32
++# undef HAVE_GETRANDOM
++# undef HAVE_SYSCALL_GETRANDOM
+ /* force stdlib to define rand_s() */
+ # if ! defined(_CRT_RAND_S)
+ # define _CRT_RAND_S
diff --git a/external/gpgmepp/ExternalProject_gpgmepp.mk b/external/gpgmepp/ExternalProject_gpgmepp.mk
index 452f922750d6..dac2fad1361b 100644
--- a/external/gpgmepp/ExternalProject_gpgmepp.mk
+++ b/external/gpgmepp/ExternalProject_gpgmepp.mk
@@ -40,7 +40,7 @@ $(call gb_ExternalProject_get_state_target,gpgmepp,build): $(call gb_Executable_
$(if $(ENABLE_DEBUG),$(gb_DEBUG_CFLAGS)) \
$(if $(filter $(true),$(gb_SYMBOL)),$(gb_DEBUGINFO_FLAGS))' \
--host=$(gb_ExternalProject_gpgmepp_host) \
- RC='windres -O COFF --target=$(gb_ExternalProject_gpgmepp_target) --preprocessor='\''$(call gb_Executable_get_target,cpp) -+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)'\' \
+ RC='windres -O COFF --target=$(gb_ExternalProject_gpgmepp_target) --preprocessor=$(call gb_Executable_get_target,cpp) --preprocessor-arg=-+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)' \
MAKE=$(MAKE) \
&& $(MAKE) \
)
diff --git a/external/libassuan/ExternalProject_libassuan.mk b/external/libassuan/ExternalProject_libassuan.mk
index 83d79a520988..899c21e4cec9 100644
--- a/external/libassuan/ExternalProject_libassuan.mk
+++ b/external/libassuan/ExternalProject_libassuan.mk
@@ -34,7 +34,7 @@ $(call gb_ExternalProject_get_state_target,libassuan,build): $(call gb_Executabl
GPG_ERROR_CFLAGS="$(GPG_ERROR_CFLAGS)" \
GPG_ERROR_LIBS="$(GPG_ERROR_LIBS)" \
--host=$(gb_ExternalProject_libassuan_host) \
- RC='windres -O COFF --target=$(gb_ExternalProject_libassuan_target) --preprocessor='\''$(call gb_Executable_get_target,cpp) -+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)'\' \
+ RC='windres -O COFF --target=$(gb_ExternalProject_libassuan_target) --preprocessor=$(call gb_Executable_get_target,cpp) --preprocessor-arg=-+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)' \
MAKE=$(MAKE) \
&& $(MAKE) \
)
diff --git a/external/libgpg-error/ExternalProject_libgpg-error.mk b/external/libgpg-error/ExternalProject_libgpg-error.mk
index 1fcd63180e20..e5155aad94c1 100644
--- a/external/libgpg-error/ExternalProject_libgpg-error.mk
+++ b/external/libgpg-error/ExternalProject_libgpg-error.mk
@@ -28,7 +28,7 @@ $(call gb_ExternalProject_get_state_target,libgpg-error,build): $(call gb_Execut
--disable-doc \
--disable-tests \
--host=$(gb_ExternalProject_libgpg-error_host) \
- RC='windres -O COFF --target=$(gb_ExternalProject_libgpg-error_target) --preprocessor='\''$(call gb_Executable_get_target,cpp) -+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)'\' \
+ RC='windres -O COFF --target=$(gb_ExternalProject_libgpg-error_target) --preprocessor=$(call gb_Executable_get_target,cpp) --preprocessor-arg=-+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)' \
&& $(MAKE) \
)
else
diff --git a/external/liblangtag/UnpackedTarball_liblangtag.mk b/external/liblangtag/UnpackedTarball_liblangtag.mk
index cd52b169fa57..66b8051782d0 100644
--- a/external/liblangtag/UnpackedTarball_liblangtag.mk
+++ b/external/liblangtag/UnpackedTarball_liblangtag.mk
@@ -17,6 +17,8 @@ $(eval $(call gb_UnpackedTarball_set_pre_action,liblangtag,\
$(eval $(call gb_UnpackedTarball_update_autoconf_configs,liblangtag))
+$(eval $(call gb_UnpackedTarball_set_patchlevel,liblangtag,0))
+
ifneq ($(OS),MACOSX)
ifneq ($(OS),WNT)
$(eval $(call gb_UnpackedTarball_add_patches,liblangtag,\
@@ -29,6 +31,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,liblangtag, \
$(if $(SYSTEM_LIBXML),,external/liblangtag/langtag-libtool-rpath.patch.0) \
external/liblangtag/clang-cl.patch.0 \
external/liblangtag/langtag-valencia.patch.0 \
+ external/liblangtag/Wformat-overflow.patch \
))
# vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/Wformat-overflow.patch b/external/liblangtag/Wformat-overflow.patch
new file mode 100644
index 000000000000..f2d017e4b395
--- /dev/null
+++ b/external/liblangtag/Wformat-overflow.patch
@@ -0,0 +1,17 @@
+--- liblangtag/lt-script-db.c
++++ liblangtag/lt-script-db.c
+@@ -134,8 +134,12 @@
+ cnode = cnode->next;
+ }
+ if (!subtag) {
+- lt_warning("No subtag node: description = '%s'",
+- desc);
++ if (!desc) {
++ lt_warning("No subtag nor description node");
++ } else {
++ lt_warning("No subtag node: description = '%s'",
++ desc);
++ }
+ goto bail1;
+ }
+ if (!desc) {
diff --git a/external/libxml2/libxml2-config.patch.1 b/external/libxml2/libxml2-config.patch.1
index 8c28fb6a7806..5a2ef1485e92 100644
--- a/external/libxml2/libxml2-config.patch.1
+++ b/external/libxml2/libxml2-config.patch.1
@@ -18,9 +18,9 @@ Hack the xml2-config to return paths into WORKDIR.
+exec_prefix=${WORKDIR}/UnpackedTarball/libxml2
+includedir=${WORKDIR}/UnpackedTarball/libxml2/include
+libdir=${WORKDIR}/UnpackedTarball/libxml2/.libs
+ cflags=
+ libs=
- usage()
- {
@@ -67,7 +72,8 @@
;;
diff --git a/external/libxml2/libxml2-global-symbols.patch b/external/libxml2/libxml2-global-symbols.patch
index 49ee73731562..cfec9c530281 100644
--- a/external/libxml2/libxml2-global-symbols.patch
+++ b/external/libxml2/libxml2-global-symbols.patch
@@ -14,8 +14,8 @@
LIBXML2_2.6.32 {
@@ -2231,3 +2231,43 @@
- xmlHashDefaultDeallocator;
- } LIBXML2_2.9.1;
+ xmlPopOutputCallbacks;
+ } LIBXML2_2.9.8;
+# HACK: export global variable accessor functions (globals.h)
+LIBXML2_GLOBAL_VARIABLES {
diff --git a/external/nss/ExternalProject_nss.mk b/external/nss/ExternalProject_nss.mk
index 05c270e9baed..ef98734f85ad 100644
--- a/external/nss/ExternalProject_nss.mk
+++ b/external/nss/ExternalProject_nss.mk
@@ -16,7 +16,9 @@ $(eval $(call gb_ExternalProject_register_targets,nss,\
))
ifeq ($(OS),WNT)
-$(call gb_ExternalProject_get_state_target,nss,build): $(call gb_ExternalExecutable_get_dependencies,python)
+$(call gb_ExternalProject_get_state_target,nss,build): \
+ $(call gb_ExternalExecutable_get_dependencies,python) \
+ $(SRCDIR)/external/nss/nsinstall.py
$(call gb_ExternalProject_run,build,\
$(if $(MSVC_USE_DEBUG_RUNTIME),USE_DEBUG_RTL=1,BUILD_OPT=1) \
OS_TARGET=WIN95 \
@@ -31,7 +33,9 @@ $(call gb_ExternalProject_get_state_target,nss,build): $(call gb_ExternalExecuta
else # OS!=WNT
# make sure to specify NSPR_CONFIGURE_OPTS as env (before make command), so nss can append it's own defaults
# OTOH specify e.g. CC and NSINSTALL as arguments (after make command), so they will overrule nss makefile values
-$(call gb_ExternalProject_get_state_target,nss,build): $(call gb_ExternalExecutable_get_dependencies,python)
+$(call gb_ExternalProject_get_state_target,nss,build): \
+ $(call gb_ExternalExecutable_get_dependencies,python) \
+ $(SRCDIR)/external/nss/nsinstall.py
$(call gb_ExternalProject_run,build,\
$(if $(filter ANDROID FREEBSD LINUX MACOSX,$(OS)),$(if $(filter X86_64,$(CPUNAME)),USE_64=1)) \
$(if $(filter ANDROID,$(OS)),$(if $(filter AARCH64,$(CPUNAME)),USE_64=1)) \
diff --git a/external/nss/UnpackedTarball_nss.mk b/external/nss/UnpackedTarball_nss.mk
index b6fcd1346b82..8fa1edd530cc 100644
--- a/external/nss/UnpackedTarball_nss.mk
+++ b/external/nss/UnpackedTarball_nss.mk
@@ -24,7 +24,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,nss,\
external/nss/nss.bzmozilla1238154.patch \
external/nss/nss-bz1646594.patch.1 \
external/nss/macos-dlopen.patch.0 \
- external/nss/nss.getopt.patch.0 \
$(if $(filter iOS,$(OS)), \
external/nss/nss-ios.patch) \
$(if $(filter ANDROID,$(OS)), \
diff --git a/external/nss/nsinstall.py b/external/nss/nsinstall.py
index 80e9c1679373..d90a85e6c540 100644
--- a/external/nss/nsinstall.py
+++ b/external/nss/nsinstall.py
@@ -99,17 +99,17 @@ def nsinstall(argv):
if options.D:
if len(args) != 1:
return 1
- if os.path.exists(args[0]):
+ try:
+ if options.m:
+ os.makedirs(args[0], options.m)
+ else:
+ os.makedirs(args[0])
+ except FileExistsError:
if not os.path.isdir(args[0]):
sys.stderr.write('nsinstall: ' + args[0] + ' is not a directory\n')
sys.exit(1)
if options.m:
os.chmod(args[0], options.m)
- sys.exit()
- if options.m:
- os.makedirs(args[0], options.m)
- else:
- os.makedirs(args[0])
return 0
# nsinstall arg1 [...] directory
diff --git a/external/nss/nss-android.patch.1 b/external/nss/nss-android.patch.1
index 9b120d63ab8c..828892533781 100644
--- a/external/nss/nss-android.patch.1
+++ b/external/nss/nss-android.patch.1
@@ -10,9 +10,9 @@ diff -ur nss.org/nspr/build/autoconf/config.sub nss/nspr/build/autoconf/config.s
+if test $1 = "i686-pc-linux-android"; then echo $1; exit; fi
+if test $1 = "x86_64-pc-linux-android"; then echo $1; exit; fi
+
- # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
- # Here we must recognize all the valid KERNEL-OS combinations.
- maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ # Split fields of configuration type
+ # shellcheck disable=SC2162
+ IFS="-" read field1 field2 field3 field4 <<EOF
diff -ur nss.org/nspr/configure nss/nspr/configure
--- nss.org/nspr/configure 2017-09-07 15:29:45.018246359 +0200
+++ nss/nspr/configure 2017-09-07 15:31:47.604075663 +0200
diff --git a/external/nss/nss-ios.patch b/external/nss/nss-ios.patch
index 65115a96e806..da09b8d8edf8 100644
--- a/external/nss/nss-ios.patch
+++ b/external/nss/nss-ios.patch
@@ -193,9 +193,9 @@
+if test $1 = "arm64-apple-darwin"; then echo $1; exit; fi
+if test $1 = "aarch64-apple-darwin"; then echo $1; exit; fi
+
- # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
- # Here we must recognize all the valid KERNEL-OS combinations.
- maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ # Split fields of configuration type
+ # shellcheck disable=SC2162
+ IFS="-" read field1 field2 field3 field4 <<EOF
--- a/a/nspr/config/autoconf.mk.in
+++ a/a/nspr/config/autoconf.mk.in
@@ -67,7 +67,7 @@
diff --git a/external/nss/nss.getopt.patch.0 b/external/nss/nss.getopt.patch.0
deleted file mode 100644
index aeabb33f9b97..000000000000
--- a/external/nss/nss.getopt.patch.0
+++ /dev/null
@@ -1,25 +0,0 @@
-# pr/tests/sel_spd.c:427:20: error: implicit declaration of function 'getopt' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
---- nspr/pr/tests/sel_spd.c
-+++ nspr/pr/tests/sel_spd.c
-@@ -15,6 +15,9 @@
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
-+
-+extern char *optarg;
-+int getopt(int argc, char *const argv[], const char *optstring);
-
- #ifdef DEBUG
- #define PORT_INC_DO +100
---- nspr/pr/tests/testfile.c
-+++ nspr/pr/tests/testfile.c
-@@ -23,6 +23,9 @@
- #include <getopt.h>
- #include <errno.h>
- #endif /* XP_OS2 */
-+
-+extern char *optarg;
-+int getopt(int argc, char *const argv[], const char *optstring);
-
- static int _debug_on = 0;
-
diff --git a/external/openssl/UnpackedTarball_openssl.mk b/external/openssl/UnpackedTarball_openssl.mk
index ad600cce1412..e7fca1116545 100644
--- a/external/openssl/UnpackedTarball_openssl.mk
+++ b/external/openssl/UnpackedTarball_openssl.mk
@@ -22,6 +22,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,openssl,\
external/openssl/openssl-3650-masm.patch.1 \
external/openssl/openssl-fixbuild.patch.1 \
external/openssl/openssl-1.0.2k-cve-2020-1971.patch.1 \
+ external/openssl/ccb0a11145ee72b042d10593a64eaf9e8a55ec12.patch.1 \
))
# vim: set noet sw=4 ts=4:
diff --git a/external/openssl/ccb0a11145ee72b042d10593a64eaf9e8a55ec12.patch.1 b/external/openssl/ccb0a11145ee72b042d10593a64eaf9e8a55ec12.patch.1
new file mode 100644
index 000000000000..cf809750ecfb
--- /dev/null
+++ b/external/openssl/ccb0a11145ee72b042d10593a64eaf9e8a55ec12.patch.1
@@ -0,0 +1,56 @@
+From ccb0a11145ee72b042d10593a64eaf9e8a55ec12 Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt@openssl.org>
+Date: Tue, 17 Aug 2021 14:41:48 +0100
+Subject: [PATCH] Fix a read buffer overrun in X509_CERT_AUX_print()
+
+This is a backport of commit c5dc9ab965f to 1.0.2. That commit fixed
+the same bug but in master/1.1.1 it is in the function X509_aux_print().
+The original commit had the following description:
+
+Fix a read buffer overrun in X509_aux_print().
+
+The ASN1_STRING_get0_data(3) manual explitely cautions the reader
+that the data is not necessarily NUL-terminated, and the function
+X509_alias_set1(3) does not sanitize the data passed into it in any
+way either, so we must assume the return value from X509_alias_get0(3)
+is merely a byte array and not necessarily a string in the sense
+of the C language.
+
+I found this bug while writing manual pages for X509_print_ex(3)
+and related functions. Theo Buehler <tb@openbsd.org> checked my
+patch to fix the same bug in LibreSSL, see
+
+http://cvsweb.openbsd.org/src/lib/libcrypto/asn1/t_x509a.c#rev1.9
+
+As an aside, note that the function still produces incomplete and
+misleading results when the data contains a NUL byte in the middle
+and that error handling is consistently absent throughout, even
+though the function provides an "int" return value obviously intended
+to be 1 for success and 0 for failure, and even though this function
+is called by another function that also wants to return 1 for success
+and 0 for failure and even does so in many of its code paths, though
+not in others. But let's stay focussed. Many things would be nice
+to have in the wide wild world, but a buffer overflow must not be
+allowed to remain in our backyard.
+
+CVE-2021-3712
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+---
+ crypto/asn1/t_x509a.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/asn1/t_x509a.c b/crypto/asn1/t_x509a.c
+index d1b897a469fd..b1bc9d0cd28b 100644
+--- a/crypto/asn1/t_x509a.c
++++ b/crypto/asn1/t_x509a.c
+@@ -104,7 +104,8 @@ int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
+ } else
+ BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+ if (aux->alias)
+- BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data);
++ BIO_printf(out, "%*sAlias: %.*s\n", indent, "", aux->alias->length,
++ aux->alias->data);
+ if (aux->keyid) {
+ BIO_printf(out, "%*sKey Id: ", indent, "");
+ for (i = 0; i < aux->keyid->length; i++)
diff --git a/external/xmlsec/0001-xmlSecX509DataGetNodeContent-don-t-return-0-for-non-.patch.1 b/external/xmlsec/0001-xmlSecX509DataGetNodeContent-don-t-return-0-for-non-.patch.1
new file mode 100644
index 000000000000..51607ca6ee73
--- /dev/null
+++ b/external/xmlsec/0001-xmlSecX509DataGetNodeContent-don-t-return-0-for-non-.patch.1
@@ -0,0 +1,68 @@
+From a39b110cb2c25680259a38b2f397b350151bc6e7 Mon Sep 17 00:00:00 2001
+From: Michael Stahl <michael.stahl@allotropia.de>
+Date: Wed, 7 Apr 2021 16:43:48 +0200
+Subject: [PATCH] xmlSecX509DataGetNodeContent(): don't return 0 for non-empty
+ elements
+
+LibreOffice wants to write the content of KeyInfo itself and thus writes
+X509Certificate element with content.
+
+But then xmlSecMSCngKeyDataX509XmlWrite() writes a duplicate
+X509Certificate element, which then makes a new additional consistency
+check in LO unhappy.
+
+The duplicate is written because xmlSecX509DataGetNodeContent() returns
+0 because it only checks for empty nodes; if there are only non-empty
+nodes a fallback to XMLSEC_X509DATA_DEFAULT occurs in all backends.
+
+Change the return value to be non-0 without changing the signature of
+the function, as it is apparently public.
+
+This doesn't happen in LO in the NSS backend due to another accident,
+where the private key flag isn't set when the X509Certificate is read,
+but otherwise the code is the same.
+---
+ src/x509.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/src/x509.c b/src/x509.c
+index ed8788ae..dac8bd2b 100644
+--- a/src/x509.c
++++ b/src/x509.c
+@@ -60,22 +60,33 @@ xmlSecX509DataGetNodeContent (xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ if(xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs)) {
+ if(xmlSecIsEmptyNode(cur) == 1) {
+ content |= XMLSEC_X509DATA_CERTIFICATE_NODE;
++ } else {
++ /* ensure return value isn't 0 if there are non-empty elements */
++ content |= (XMLSEC_X509DATA_CERTIFICATE_NODE << 16);
+ }
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SubjectName, xmlSecDSigNs)) {
+ if(xmlSecIsEmptyNode(cur) == 1) {
+ content |= XMLSEC_X509DATA_SUBJECTNAME_NODE;
++ } else {
++ content |= (XMLSEC_X509DATA_SUBJECTNAME_NODE << 16);
+ }
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) {
+ if(xmlSecIsEmptyNode(cur) == 1) {
+ content |= XMLSEC_X509DATA_ISSUERSERIAL_NODE;
++ } else {
++ content |= (XMLSEC_X509DATA_ISSUERSERIAL_NODE << 16);
+ }
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SKI, xmlSecDSigNs)) {
+ if(xmlSecIsEmptyNode(cur) == 1) {
+ content |= XMLSEC_X509DATA_SKI_NODE;
++ } else {
++ content |= (XMLSEC_X509DATA_SKI_NODE << 16);
+ }
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509CRL, xmlSecDSigNs)) {
+ if(xmlSecIsEmptyNode(cur) == 1) {
+ content |= XMLSEC_X509DATA_CRL_NODE;
++ } else {
++ content |= (XMLSEC_X509DATA_CRL_NODE << 16);
+ }
+ } else {
+ /* todo: fail on unknown child node? */
+--
+2.30.2
+
diff --git a/external/xmlsec/UnpackedTarball_xmlsec.mk b/external/xmlsec/UnpackedTarball_xmlsec.mk
index 3ad978cdb829..c0591ddcea0d 100644
--- a/external/xmlsec/UnpackedTarball_xmlsec.mk
+++ b/external/xmlsec/UnpackedTarball_xmlsec.mk
@@ -8,6 +8,7 @@
#
xmlsec_patches :=
+xmlsec_patches += 0001-xmlSecX509DataGetNodeContent-don-t-return-0-for-non-.patch.1
$(eval $(call gb_UnpackedTarball_UnpackedTarball,xmlsec))
diff --git a/filter/source/graphicfilter/icgm/bitmap.cxx b/filter/source/graphicfilter/icgm/bitmap.cxx
index f74ba6fb5d5b..c5613be6acf1 100644
--- a/filter/source/graphicfilter/icgm/bitmap.cxx
+++ b/filter/source/graphicfilter/icgm/bitmap.cxx
@@ -271,7 +271,15 @@ bool CGMBitmap::ImplGetDimensions( CGMBitmapDescriptor& rDesc )
rDesc.mbStatus = false;
sal_uInt32 nHeaderSize = 2 + 3 * nPrecision + 3 * mpCGM->ImplGetPointSize();
- rDesc.mnScanSize = ( ( rDesc.mnX * rDesc.mnDstBitsPerPixel + 7 ) >> 3 );
+
+ sal_uInt32 nWidthBits;
+ if (o3tl::checked_multiply(rDesc.mnX, rDesc.mnDstBitsPerPixel, nWidthBits))
+ {
+ rDesc.mbStatus = false;
+ return false;
+ }
+
+ rDesc.mnScanSize = (nWidthBits + 7) >> 3;
sal_uInt32 nScanSize;
nScanSize = rDesc.mnScanSize;
diff --git a/include/svl/sigstruct.hxx b/include/svl/sigstruct.hxx
index ceed929752ab..02b5c11e73a3 100644
--- a/include/svl/sigstruct.hxx
+++ b/include/svl/sigstruct.hxx
@@ -22,6 +22,7 @@
#include <rtl/ustring.hxx>
#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
#include <com/sun/star/xml/crypto/DigestID.hpp>
#include <com/sun/star/uno/Sequence.hxx>
@@ -29,8 +30,6 @@
#include <set>
#include <vector>
-namespace com { namespace sun { namespace star { namespace graphic { class XGraphic; } } } }
-
/*
* type of reference
*/
@@ -89,9 +88,30 @@ struct SignatureInformation
sal_Int32 nSecurityId;
css::xml::crypto::SecurityOperationStatus nStatus;
SignatureReferenceInformations vSignatureReferenceInfors;
- OUString ouX509IssuerName;
- OUString ouX509SerialNumber;
- OUString ouX509Certificate;
+ struct X509CertInfo
+ {
+ OUString X509IssuerName;
+ OUString X509SerialNumber;
+ OUString X509Certificate;
+ /// OOXML certificate SHA-256 digest, empty for ODF except when doing XAdES signature.
+ OUString CertDigest;
+ /// The certificate owner (aka subject).
+ OUString X509Subject;
+ };
+ typedef std::vector<X509CertInfo> X509Data;
+ // note: at parse time, it's unkown which one is the signing certificate;
+ // ImplVerifySignatures() figures it out and puts it at the back
+ std::vector<X509Data> X509Datas;
+
+ X509CertInfo const* GetSigningCertificate() const
+ {
+ if (X509Datas.empty())
+ {
+ return nullptr;
+ }
+ assert(!X509Datas.back().empty());
+ return & X509Datas.back().back();
+ }
OUString ouGpgKeyID;
OUString ouGpgCertificate;
@@ -103,6 +123,9 @@ struct SignatureInformation
// XAdES EncapsulatedX509Certificate values
std::set<OUString> maEncapsulatedX509Certificates;
+ OUString ouSignatureId;
+ // signature may contain multiple time stamps - check they're consistent
+ bool hasInconsistentSigningTime = false;
//We also keep the date and time as string. This is done when this
//structure is created as a result of a XML signature being read.
//When then a signature is added or another removed, then the original
@@ -115,14 +138,12 @@ struct SignatureInformation
//and the converted time is written back, then the string looks different
//and the signature is broken.
OUString ouDateTime;
- OUString ouSignatureId;
- OUString ouPropertyId;
+ /// The Id attribute of the <SignatureProperty> element that contains the <dc:date>.
+ OUString ouDateTimePropertyId;
/// Characters of the <dc:description> element inside the signature.
OUString ouDescription;
/// The Id attribute of the <SignatureProperty> element that contains the <dc:description>.
OUString ouDescriptionPropertyId;
- /// OOXML certificate SHA-256 digest, empty for ODF except when doing XAdES signature.
- OUString ouCertDigest;
/// Valid and invalid signature line images
css::uno::Reference<css::graphic::XGraphic> aValidSignatureImage;
css::uno::Reference<css::graphic::XGraphic> aInvalidSignatureImage;
@@ -137,9 +158,6 @@ struct SignatureInformation
/// For PDF: the byte range doesn't cover the whole document.
bool bPartialDocumentSignature;
- /// The certificate owner (aka subject).
- OUString ouSubject;
-
svl::crypto::SignatureMethodAlgorithm eAlgorithmID;
SignatureInformation( sal_Int32 nId )
diff --git a/include/svx/sdr/table/tablecontroller.hxx b/include/svx/sdr/table/tablecontroller.hxx
index cec83b996c87..9018e2587a2d 100644
--- a/include/svx/sdr/table/tablecontroller.hxx
+++ b/include/svx/sdr/table/tablecontroller.hxx
@@ -58,6 +58,7 @@ public:
SVX_DLLPRIVATE virtual bool DeleteMarked() override;
SVX_DLLPRIVATE virtual void onSelectionHasChanged() override;
+ SVX_DLLPRIVATE virtual void onSelectAll() override;
SVX_DLLPRIVATE virtual void GetState( SfxItemSet& rSet ) override;
SVX_DLLPRIVATE virtual void Execute( SfxRequest& rReq ) override;
diff --git a/include/svx/selectioncontroller.hxx b/include/svx/selectioncontroller.hxx
index 11acdac3cd59..3ce5f7849ec3 100644
--- a/include/svx/selectioncontroller.hxx
+++ b/include/svx/selectioncontroller.hxx
@@ -51,6 +51,8 @@ public:
virtual void onSelectionHasChanged();
+ virtual void onSelectAll();
+
virtual void GetState( SfxItemSet& rSet );
virtual void Execute( SfxRequest& rReq );
diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx
index 6a8f6c8b9605..3f4847609d30 100644
--- a/include/vcl/BitmapTools.hxx
+++ b/include/vcl/BitmapTools.hxx
@@ -45,7 +45,8 @@ public:
assert(nBitCount == 24 || nBitCount == 32);
sal_Int32 nRowSize, nDataSize;
if (o3tl::checked_multiply<sal_Int32>(rSize.getWidth(), nBitCount/8, nRowSize) ||
- o3tl::checked_multiply<sal_Int32>(nRowSize, rSize.getHeight(), nDataSize))
+ o3tl::checked_multiply<sal_Int32>(nRowSize, rSize.getHeight(), nDataSize) ||
+ nDataSize < 0)
{
throw std::bad_alloc();
}
diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx
index 86af82e61fa5..3cb69376a258 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -232,8 +232,12 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper<
static void initializeNamespaceMaps();
void registerNamespaces();
- std::unique_ptr<SvXMLNamespaceMap> processNSAttributes(
+public:
+ static std::unique_ptr<SvXMLNamespaceMap> processNSAttributes(
+ std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,
+ SvXMLImport *const pImport,
const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList);
+private:
void Characters(const OUString& aChars);
css::uno::Reference< css::task::XStatusIndicator > mxStatusIndicator;
diff --git a/include/xmloff/xmlnmspe.hxx b/include/xmloff/xmlnmspe.hxx
index a00628b6b999..a7505a64190d 100644
--- a/include/xmloff/xmlnmspe.hxx
+++ b/include/xmloff/xmlnmspe.hxx
@@ -138,6 +138,16 @@ XML_NAMESPACE( XML_NAMESPACE_FIELD, 100U )
XML_NAMESPACE( XML_NAMESPACE_CSS3TEXT, 103U ) // CSS Text Level 3
XML_NAMESPACE( XML_NAMESPACE_FORMX, 101U ) // form interop extensions
+// OOo extension digital signatures, used in ODF 1.1
+const sal_uInt16 XML_NAMESPACE_DSIG_OOO = 200;
+// ODF 1.2 digital signature namespaces
+const sal_uInt16 XML_NAMESPACE_DSIG = 201;
+const sal_uInt16 XML_NAMESPACE_DS = 202;
+const sal_uInt16 XML_NAMESPACE_XADES132 = 203;
+const sal_uInt16 XML_NAMESPACE_XADES141 = 204;
+// OOXML digital signature extension namespaces, also based on xmldsig-core
+const sal_uInt16 XML_NAMESPACE_MDSSI = 205;
+const sal_uInt16 XML_NAMESPACE_MSODIGSIG = 206;
#endif // INCLUDED_XMLOFF_XMLNMSPE_HXX
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index f572e338715e..6e56bdf4d6b0 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -132,6 +132,19 @@ namespace xmloff { namespace token {
XML_NP_GRDDL,
XML_N_GRDDL,
+ // OOo extension digital signatures, used in ODF 1.1
+ XML_NP_DSIG_OOO,
+ XML_N_DSIG_OOO,
+ // ODF 1.2 digital signatures
+ XML_NP_DSIG,
+ XML_N_DSIG,
+ XML_NP_DS,
+ XML_N_DS,
+ XML_NP_XADES132,
+ XML_N_XADES132,
+ XML_NP_XADES141,
+ XML_N_XADES141,
+
// ODF Enhanced namespaces
XML_NP_OFFICE_EXT,
XML_N_OFFICE_EXT,
diff --git a/instsetoo_native/inc_openoffice/unix/find-requires-x11.sh b/instsetoo_native/inc_openoffice/unix/find-requires-x11.sh
index 0fe0b1d27dde..6808b3631d73 100644
--- a/instsetoo_native/inc_openoffice/unix/find-requires-x11.sh
+++ b/instsetoo_native/inc_openoffice/unix/find-requires-x11.sh
@@ -23,5 +23,7 @@ if [[ "${OS}" == "AIX" ]]; then
echo "libfreetype.a(libfreetype.so.6${mark64})"
else
echo "libfreetype.so.6${mark64}"
- echo "libXinerama.so.1${mark64}"
+ if [[ "${XINERAMA_LINK}" == "dynamic" ]]; then
+ echo "libXinerama.so.1${mark64}"
+ fi
fi
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx
index 619b2a87b13f..9a454c61ba52 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx
@@ -9,6 +9,7 @@
#include <gtk/gtk.h>
+#include <cassert>
#include <cmath>
#include <iostream>
@@ -132,6 +133,10 @@ static gboolean gtv_calc_header_bar_draw_impl(GtkWidget* pWidget, cairo_t* pCair
cairo_rectangle(pCairo, aRectangle.x, aRectangle.height, aRectangle.width, 1);
cairo_fill(pCairo);
}
+ else
+ {
+ assert(false); // should never happen
+ }
gtv_calc_header_bar_draw_text(pCairo, aRectangle, rHeader.m_aText);
nPrevious = rHeader.m_nSize;
diff --git a/lotuswordpro/qa/cppunit/data/pass/ofz20517-1.lwp b/lotuswordpro/qa/cppunit/data/pass/ofz20517-1.lwp
new file mode 100644
index 000000000000..de6dcbf1c5d5
--- /dev/null
+++ b/lotuswordpro/qa/cppunit/data/pass/ofz20517-1.lwp
Binary files differ
diff --git a/lotuswordpro/source/filter/lwprowlayout.cxx b/lotuswordpro/source/filter/lwprowlayout.cxx
index a0a90a417c69..da10c32888f7 100644
--- a/lotuswordpro/source/filter/lwprowlayout.cxx
+++ b/lotuswordpro/source/filter/lwprowlayout.cxx
@@ -191,6 +191,8 @@ void LwpRowLayout::Read()
void LwpRowLayout::ConvertRow(rtl::Reference<XFTable> const & pXFTable,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
{
LwpTableLayout* pTableLayout = GetParentTableLayout();
+ if (!pTableLayout)
+ throw std::runtime_error("missing TableLayout");
LwpTable* pTable = pTableLayout->GetTable();
//calculate the connected cell position
@@ -281,14 +283,15 @@ void LwpRowLayout::RegisterCurRowStyle(XFRow* pXFRow,sal_uInt16 nRowMark)
{
pRowStyle = static_cast<XFRowStyle*>(
pXFStyleManager->FindStyle(pTableLayout->GetDefaultRowStyleName()));
- fHeight += pRowStyle->GetRowHeight();
}
else
{
pRowStyle = static_cast<XFRowStyle*>(
pXFStyleManager->FindStyle(iter->second->GetStyleName()));
- fHeight+=pRowStyle->GetRowHeight();
}
+ if (!pRowStyle)
+ throw std::runtime_error("missing RowStyle");
+ fHeight += pRowStyle->GetRowHeight();
}
if (m_nDirection & 0x0030)
@@ -376,11 +379,13 @@ void LwpRowLayout::ConvertCommonRow(rtl::Reference<XFTable> const & pXFTable, sa
LwpTableLayout* pTableLayout = GetParentTableLayout();
if (!pTableLayout)
return;
+ LwpTable* pTable = pTableLayout->GetTable();
+ if (!pTable)
+ return;
rtl::Reference<XFRow> xRow(new XFRow);
xRow->SetStyleName(m_StyleName);
- LwpTable* pTable = pTableLayout->GetTable();
sal_uInt8 nCellStartCol,nCellEndCol;
for (sal_uInt8 i = nStartCol; i < nEndCol ; i++)
diff --git a/lotuswordpro/source/filter/lwptablelayout.cxx b/lotuswordpro/source/filter/lwptablelayout.cxx
index b595dc152c6a..54e359efc963 100644
--- a/lotuswordpro/source/filter/lwptablelayout.cxx
+++ b/lotuswordpro/source/filter/lwptablelayout.cxx
@@ -877,7 +877,14 @@ sal_uInt16 LwpTableLayout::ConvertHeadingRow(
XFRow* pXFRow = pTmpTable->GetRow(1);
pXFTable->AddHeaderRow(pXFRow);
pTmpTable->RemoveRow(1);
- nContentRow = m_RowsMap[0]->GetCurMaxSpannedRows(0,nCol);
+ auto iter = m_RowsMap.find(0);
+ if (iter == m_RowsMap.end())
+ {
+ SAL_WARN("lwp", "row 0 is unknown");
+ nContentRow = 0;
+ }
+ else
+ nContentRow = iter->second->GetCurMaxSpannedRows(0,nCol);
}
}
return nContentRow;
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 1b7eb5343560..0fa752be89fe 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -111,6 +111,7 @@ public:
void testJumpToLastRowInvalidation();
void testDeleteCellMultilineContent();
void testFunctionDlg();
+ void testSheetViewDataCrash();
CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
CPPUNIT_TEST(testRowColumnHeaders);
@@ -153,6 +154,7 @@ public:
CPPUNIT_TEST(testJumpToLastRowInvalidation);
CPPUNIT_TEST(testDeleteCellMultilineContent);
CPPUNIT_TEST(testFunctionDlg);
+ CPPUNIT_TEST(testSheetViewDataCrash);
CPPUNIT_TEST_SUITE_END();
private:
@@ -2028,6 +2030,47 @@ void ScTiledRenderingTest::testDeleteCellMultilineContent()
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(nullptr, nullptr);
}
+void ScTiledRenderingTest::testSheetViewDataCrash()
+{
+ comphelper::LibreOfficeKit::setActive();
+
+ ScModelObj* pModelObj = createDoc("empty.ods");
+
+ // view #1
+ int nView1 = SfxLokHelper::getView();
+ SfxLokHelper::setView(nView1);
+
+ // Imitate online while creating a new sheet on empty.ods.
+ uno::Sequence<beans::PropertyValue> aArgs(
+ comphelper::InitPropertySequence({
+ { "Name", uno::Any(OUString("NewSheet")) },
+ { "Index", uno::Any(sal_Int32(2)) }
+ }));
+ comphelper::dispatchCommand(".uno:Insert", aArgs);
+ Scheduler::ProcessEventsToIdle();
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::PAGEDOWN | KEY_MOD1);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::PAGEDOWN | KEY_MOD1);
+ Scheduler::ProcessEventsToIdle();
+ ScTabViewShell* pView1 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+ CPPUNIT_ASSERT(pView1);
+
+ // view #2
+ SfxLokHelper::createView();
+ ScTabViewShell* pView2 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+ CPPUNIT_ASSERT(pView2);
+ Scheduler::ProcessEventsToIdle();
+
+ SfxLokHelper::setView(nView1);
+ // Delete a range.
+ pView1->SetCursor(1, 1);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::DOWN | KEY_SHIFT);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::DOWN | KEY_SHIFT);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::DELETE);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::DELETE);
+ // It will crash at this point without the fix.
+ Scheduler::ProcessEventsToIdle();
+}
+
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 38af064a918c..15a57dc42400 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -161,7 +161,8 @@ bool ScDocFunc::AdjustRowHeight( const ScRange& rRange, bool bPaint )
ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
if (pTabViewShell)
{
- pTabViewShell->GetViewData().GetLOKHeightHelper(nTab)->invalidateByIndex(nStartRow);
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKHeightHelper(nTab))
+ pPosHelper->invalidateByIndex(nStartRow);
}
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index d1f57b46dead..c7f7d81a8a9e 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -2260,9 +2260,15 @@ void ScDBFunc::OnLOKShowHideColRow(bool bColumns, SCCOLROW nStart)
if (pTabViewShell)
{
if (bColumns)
- pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex)->invalidateByIndex(nStart);
+ {
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex))
+ pPosHelper->invalidateByIndex(nStart);
+ }
else
- pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex)->invalidateByIndex(nStart);
+ {
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex))
+ pPosHelper->invalidateByIndex(nStart);
+ }
if (pTabViewShell->getPart() == nCurrentTabIndex)
{
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 1c7e36ca484a..39f23fb31f62 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -1996,7 +1996,8 @@ void ScViewData::SetTabNo( SCTAB nNewTab )
ScPositionHelper* ScViewData::GetLOKWidthHelper(SCTAB nTabIndex)
{
- if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
+ if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())) ||
+ !maTabData[nTabIndex])
{
return nullptr;
}
@@ -2005,7 +2006,8 @@ ScPositionHelper* ScViewData::GetLOKWidthHelper(SCTAB nTabIndex)
ScPositionHelper* ScViewData::GetLOKHeightHelper(SCTAB nTabIndex)
{
- if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
+ if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())) ||
+ !maTabData[nTabIndex])
{
return nullptr;
}
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index a0e1185a6d3f..51738b4951af 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -1487,7 +1487,8 @@ void ScViewFunc::OnLOKInsertDeleteColumn(SCCOL nStartCol, long nOffset)
ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
if (pTabViewShell)
{
- pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex)->invalidateByIndex(nStartCol);
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex))
+ pPosHelper->invalidateByIndex(nStartCol);
// if we remove a column the cursor position and the current selection
// in other views could need to be moved on the left by one column.
@@ -1542,7 +1543,8 @@ void ScViewFunc::OnLOKInsertDeleteRow(SCROW nStartRow, long nOffset)
ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
if (pTabViewShell)
{
- pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex)->invalidateByIndex(nStartRow);
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex))
+ pPosHelper->invalidateByIndex(nStartRow);
// if we remove a row the cursor position and the current selection
// in other views could need to be moved up by one row.
@@ -1598,9 +1600,15 @@ void ScViewFunc::OnLOKSetWidthOrHeight(SCCOLROW nStart, bool bWidth)
if (pTabViewShell)
{
if (bWidth)
- pTabViewShell->GetViewData().GetLOKWidthHelper(nCurTab)->invalidateByIndex(nStart);
+ {
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKWidthHelper(nCurTab))
+ pPosHelper->invalidateByIndex(nStart);
+ }
else
- pTabViewShell->GetViewData().GetLOKHeightHelper(nCurTab)->invalidateByIndex(nStart);
+ {
+ if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKHeightHelper(nCurTab))
+ pPosHelper->invalidateByIndex(nStart);
+ }
}
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
diff --git a/sfx2/source/appl/macroloader.cxx b/sfx2/source/appl/macroloader.cxx
index 1c32be75cd90..9edd49bd18a7 100644
--- a/sfx2/source/appl/macroloader.cxx
+++ b/sfx2/source/appl/macroloader.cxx
@@ -75,10 +75,10 @@ css::uno::Sequence<OUString> SAL_CALL SfxMacroLoader::getSupportedServiceNames()
return aSeq;
}
-SfxObjectShell* SfxMacroLoader::GetObjectShell_Impl()
+SfxObjectShell* SfxMacroLoader::GetObjectShell(const Reference <XFrame>& xFrame)
{
SfxObjectShell* pDocShell = nullptr;
- Reference < XFrame > xFrame( m_xFrame.get(), UNO_QUERY );
+
if ( xFrame.is() )
{
SfxFrame* pFrame=nullptr;
@@ -95,6 +95,11 @@ SfxObjectShell* SfxMacroLoader::GetObjectShell_Impl()
return pDocShell;
}
+SfxObjectShell* SfxMacroLoader::GetObjectShell_Impl()
+{
+ Reference < XFrame > xFrame( m_xFrame.get(), UNO_QUERY );
+ return SfxMacroLoader::GetObjectShell(xFrame);
+}
uno::Reference<frame::XDispatch> SAL_CALL SfxMacroLoader::queryDispatch(
const util::URL& aURL ,
diff --git a/sfx2/source/doc/iframe.cxx b/sfx2/source/doc/iframe.cxx
index f6319d58abb3..77d2f17b9970 100644
--- a/sfx2/source/doc/iframe.cxx
+++ b/sfx2/source/doc/iframe.cxx
@@ -39,10 +39,12 @@
#include <svl/ownlist.hxx>
#include <svl/itemprop.hxx>
#include <sfx2/frmdescr.hxx>
+#include <sfx2/objsh.hxx>
#include <sfx2/sfxdlg.hxx>
#include <sfx2/sfxsids.hrc>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/window.hxx>
+#include <macroloader.hxx>
using namespace ::com::sun::star;
@@ -158,6 +160,19 @@ sal_Bool SAL_CALL IFrameObject::load(
{
if ( SvtMiscOptions().IsPluginsEnabled() )
{
+ util::URL aTargetURL;
+ aTargetURL.Complete = maFrmDescr.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( mxContext ) );
+ xTrans->parseStrict( aTargetURL );
+
+ if (INetURLObject(aTargetURL.Complete).GetProtocol() == INetProtocol::Macro)
+ {
+ uno::Reference<frame::XFramesSupplier> xParentFrame = xFrame->getCreator();
+ SfxObjectShell* pDoc = SfxMacroLoader::GetObjectShell(xParentFrame);
+ if (pDoc && !pDoc->AdjustMacroMode())
+ return false;
+ }
+
DBG_ASSERT( !mxFrame.is(), "Frame already existing!" );
VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
VclPtr<IFrameWindow_Impl> pWin = VclPtr<IFrameWindow_Impl>::Create( pParent, maFrmDescr.IsFrameBorderOn() );
@@ -180,11 +195,6 @@ sal_Bool SAL_CALL IFrameObject::load(
if ( xFramesSupplier.is() )
mxFrame->setCreator( xFramesSupplier );
- util::URL aTargetURL;
- aTargetURL.Complete = maFrmDescr.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE );
- uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( mxContext ) );
- xTrans->parseStrict( aTargetURL );
-
uno::Sequence < beans::PropertyValue > aProps(2);
aProps[0].Name = "PluginMode";
aProps[0].Value <<= sal_Int16(2);
diff --git a/sfx2/source/inc/macroloader.hxx b/sfx2/source/inc/macroloader.hxx
index 54decff36a37..8d276423173e 100644
--- a/sfx2/source/inc/macroloader.hxx
+++ b/sfx2/source/inc/macroloader.hxx
@@ -82,6 +82,8 @@ public:
virtual void SAL_CALL addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) override;
virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) override;
+
+ static SfxObjectShell* GetObjectShell(const css::uno::Reference<css::frame::XFrame>& xFrame);
};
#endif
diff --git a/shell/source/unix/exec/shellexec.cxx b/shell/source/unix/exec/shellexec.cxx
index 86c3672162c0..093a8a2ba57f 100644
--- a/shell/source/unix/exec/shellexec.cxx
+++ b/shell/source/unix/exec/shellexec.cxx
@@ -117,6 +117,7 @@ void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aPar
}
#ifdef MACOSX
+ bool dir = false;
if (uri->getScheme().equalsIgnoreAsciiCase("file")) {
OUString pathname;
auto const e1 = osl::FileBase::getSystemPathFromFileURL(aCommand, pathname);
@@ -142,12 +143,15 @@ void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aPar
auto const e3 = errno;
SAL_INFO("shell", "stat(" << pathname8 << ") failed with errno " << e3);
}
- if (e2 != 0 || !S_ISREG(st.st_mode)
- || (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)
+ if (e2 == 0 && S_ISDIR(st.st_mode)) {
+ dir = true;
+ } else if (e2 != 0 || !S_ISREG(st.st_mode)
+ || (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)
{
throw css::lang::IllegalArgumentException(
"XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0);
} else if (pathname.endsWithIgnoreAsciiCase(".class")
+ || pathname.endsWithIgnoreAsciiCase(".fileloc")
|| pathname.endsWithIgnoreAsciiCase(".jar"))
{
dir = true;
@@ -176,7 +180,11 @@ void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aPar
// 2.4 If it does not match an exitsting pathname (relative to CWD):
// Results in "The file /.../foo:bar does not exits." (where "/..." is
// the CWD) on stderr and SystemShellExecuteException.
- aBuffer.append("open --");
+ aBuffer.append("open");
+ if (dir) {
+ aBuffer.append(" -R");
+ }
+ aBuffer.append(" --");
#else
// Just use xdg-open on non-Mac
aBuffer.append("/usr/bin/xdg-open");
diff --git a/solenv/bin/modules/installer/simplepackage.pm b/solenv/bin/modules/installer/simplepackage.pm
index b407a4ff668f..9a2d28a764d3 100644
--- a/solenv/bin/modules/installer/simplepackage.pm
+++ b/solenv/bin/modules/installer/simplepackage.pm
@@ -436,7 +436,7 @@ sub create_package
}
$systemcall = "cd $localtempdir && hdiutil create -megabytes 1500 -srcfolder $folder $archive -ov -fs HFS+ -volname \"$volume_name\" -format UDBZ";
- if (( $ref ne "" ) && ( $$ref ne "" )) {
+ if (( $ref ne "" ) && ( $$ref ne "" ) && system("hdiutil 2>&1 | grep unflatten") == 0) {
$systemcall .= " && hdiutil unflatten $archive && Rez -a $$ref -o $archive && hdiutil flatten $archive";
}
}
diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx
index 617c926201fa..fb5fd7038033 100644
--- a/svl/source/crypto/cryptosign.cxx
+++ b/svl/source/crypto/cryptosign.cxx
@@ -2111,8 +2111,12 @@ bool Signing::Verify(const std::vector<unsigned char>& aData,
aDerCert[i] = pCertificate->derCert.data[i];
OUStringBuffer aBuffer;
comphelper::Base64::encode(aBuffer, aDerCert);
- rInformation.ouX509Certificate = aBuffer.makeStringAndClear();
- rInformation.ouSubject = OUString(pCertificate->subjectName, PL_strlen(pCertificate->subjectName), RTL_TEXTENCODING_UTF8);
+ SignatureInformation::X509Data temp;
+ temp.emplace_back();
+ temp.back().X509Certificate = aBuffer.makeStringAndClear();
+ temp.back().X509Subject = OUString(pCertificate->subjectName, PL_strlen(pCertificate->subjectName), RTL_TEXTENCODING_UTF8);
+ rInformation.X509Datas.clear();
+ rInformation.X509Datas.emplace_back(temp);
}
PRTime nSigningTime;
@@ -2291,8 +2295,12 @@ bool Signing::Verify(const std::vector<unsigned char>& aData,
aDerCert[i] = pSignerCertContext->pbCertEncoded[i];
OUStringBuffer aBuffer;
comphelper::Base64::encode(aBuffer, aDerCert);
- rInformation.ouX509Certificate = aBuffer.makeStringAndClear();
- rInformation.ouSubject = GetSubjectName(pSignerCertContext);
+ SignatureInformation::X509Data temp;
+ temp.emplace_back();
+ temp.back().X509Certificate = aBuffer.makeStringAndClear();
+ temp.back().X509Subject = GetSubjectName(pSignerCertContext);
+ rInformation.X509Datas.clear();
+ rInformation.X509Datas.emplace_back(temp);
}
if (bNonDetached)
diff --git a/svx/source/svdraw/selectioncontroller.cxx b/svx/source/svdraw/selectioncontroller.cxx
index 8cb678d66467..bc31a7543366 100644
--- a/svx/source/svdraw/selectioncontroller.cxx
+++ b/svx/source/svdraw/selectioncontroller.cxx
@@ -47,6 +47,10 @@ void SelectionController::onSelectionHasChanged()
{
}
+void SelectionController::onSelectAll()
+{
+}
+
void SelectionController::GetState( SfxItemSet& /*rSet*/ )
{
}
diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx
index c68bbe443a72..ad6e4beb7cc4 100644
--- a/svx/source/svdraw/svdview.cxx
+++ b/svx/source/svdraw/svdview.cxx
@@ -35,6 +35,7 @@
#include <svdibrow.hxx>
#endif
+#include <svx/sdr/table/tablecontroller.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svdview.hxx>
#include <editeng/editview.hxx>
@@ -1359,7 +1360,33 @@ void SdrView::MarkAll()
#endif
} else if (IsGluePointEditMode()) MarkAllGluePoints();
else if (HasMarkablePoints()) MarkAllPoints();
- else MarkAllObj();
+ else {
+ // check for table
+ bool bMarkAll = true;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ const SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
+ SdrView* pView(dynamic_cast<SdrView*>(this));
+ if (pObj && pView && (pObj->GetObjInventor() == SdrInventor::Default)
+ && (pObj->GetObjIdentifier() == OBJ_TABLE))
+ {
+ mxSelectionController.clear();
+ mxSelectionController = sdr::table::CreateTableController(
+ *pView, static_cast<const sdr::table::SdrTableObj&>(*pObj),
+ mxLastSelectionController);
+
+ if (mxSelectionController.is())
+ {
+ mxLastSelectionController.clear();
+ mxSelectionController->onSelectAll();
+ bMarkAll = false;
+ }
+ }
+ }
+ if ( bMarkAll )
+ MarkAllObj();
+ }
}
void SdrView::UnmarkAll()
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 45d184403c56..18ac30472a7b 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -243,6 +243,7 @@ private:
static sal_Int32 lastRowCount;
static sal_Int32 lastColCount;
static std::vector<sal_Int32> lastColWidths;
+ static bool rowSizeChanged;
};
SdrTableObjImpl* SdrTableObjImpl::lastLayoutTable = nullptr;
@@ -253,6 +254,7 @@ bool SdrTableObjImpl::lastLayoutFitHeight;
WritingMode SdrTableObjImpl::lastLayoutMode;
sal_Int32 SdrTableObjImpl::lastRowCount;
sal_Int32 SdrTableObjImpl::lastColCount;
+bool SdrTableObjImpl::rowSizeChanged = false;
std::vector<sal_Int32> SdrTableObjImpl::lastColWidths;
SdrTableObjImpl::SdrTableObjImpl()
@@ -594,6 +596,7 @@ void SdrTableObjImpl::DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset
Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
Reference< XPropertySet > xRowSet( xRows->getByIndex( (!nEdge)?nEdge:(nEdge-1) ), UNO_QUERY_THROW );
xRowSet->setPropertyValue( sSize, Any( nHeight ) );
+ rowSizeChanged = true;
}
}
else
@@ -798,7 +801,8 @@ void SdrTableObjImpl::LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool
|| lastLayoutMode != writingMode
|| lastRowCount != getRowCount()
|| lastColCount != getColumnCount()
- || lastColWidths != getColumnWidths() )
+ || lastColWidths != getColumnWidths()
+ || rowSizeChanged )
{
lastLayoutTable = this;
lastLayoutInputRectangle = rArea;
@@ -813,6 +817,7 @@ void SdrTableObjImpl::LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool
TableModelNotifyGuard aGuard( mxTable.get() );
mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight );
lastLayoutResultRectangle = rArea;
+ rowSizeChanged = false;
}
else
{
diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx
index 43c74993961b..d7028fe42c0c 100644
--- a/svx/source/table/tablecontroller.cxx
+++ b/svx/source/table/tablecontroller.cxx
@@ -399,13 +399,6 @@ void SvxTableController::onSelectionHasChanged()
const SdrMarkList& rMarkList= mrView.GetMarkedObjectList();
if( rMarkList.GetMarkCount() == 1 )
bSelected = mxTableObj.get() == rMarkList.GetMark(0)->GetMarkedSdrObj();
- /* fdo#46186 Selecting the table means selecting the entire cells */
- if (!hasSelectedCells() && pTableObj)
- {
- maCursorFirstPos = SdrTableObj::getFirstCell();
- maCursorLastPos = pTableObj->getLastCell();
- mbCellSelectionMode=true;
- }
}
if( bSelected )
@@ -417,6 +410,14 @@ void SvxTableController::onSelectionHasChanged()
destroySelectionOverlay();
}
}
+void SvxTableController::onSelectAll()
+{
+ sdr::table::SdrTableObj* pTableObj = mxTableObj.get();
+ if ( pTableObj && !pTableObj->IsTextEditActive())
+ {
+ selectAll();
+ }
+}
void SvxTableController::GetState( SfxItemSet& rSet )
@@ -1385,30 +1386,44 @@ bool SvxTableController::DeleteMarked()
SdrTableObj& rTableObj(*mxTableObj.get());
SdrModel& rModel(rTableObj.getSdrModelFromSdrObject());
const bool bUndo(rModel.IsUndoEnabled());
+ bool bDeleteTable = false;
if (bUndo)
rModel.BegUndo(SvxResId(STR_TABLE_DELETE_CELL_CONTENTS));
CellPos aStart, aEnd;
getSelectedCells( aStart, aEnd );
- for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ const sal_Int32 nRemovedColumns = aEnd.mnCol - aStart.mnCol + 1;
+ const sal_Int32 nRemovedRows = aEnd.mnRow - aStart.mnRow + 1;
+ if( nRemovedColumns == mxTable->getColumnCount() && nRemovedRows == mxTable->getRowCount())
{
- for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ bDeleteTable = true;
+ }
+ else
+ {
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
{
- CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
- if (xCell.is() && xCell->hasText())
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
{
- if (bUndo)
- xCell->AddUndo();
- xCell->SetOutlinerParaObject(nullptr);
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if (xCell.is() && xCell->hasText())
+ {
+ if (bUndo)
+ xCell->AddUndo();
+ xCell->SetOutlinerParaObject(nullptr);
+ }
}
}
}
+ if (bDeleteTable)
+ mrView.DeleteMarkedObj();
+
if (bUndo)
rModel.EndUndo();
- UpdateTableShape();
+ if (!bDeleteTable)
+ UpdateTableShape();
return true;
}
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index e2014a101966..1929880d60a2 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -407,7 +407,8 @@ std::pair<bool, OUString> lcl_MakeParagraphSignatureFieldText(const SignatureDes
valid = valid
&& aInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
- msg = SwResId(STR_SIGNED_BY) + ": " + aInfo.ouSubject + ", ";
+ assert(aInfo.GetSigningCertificate()); // it was valid
+ msg = SwResId(STR_SIGNED_BY) + ": " + aInfo.GetSigningCertificate()->X509Subject + ", ";
msg += aDescr.msDate;
msg += (!aDescr.msUsage.isEmpty() ? (" (" + aDescr.msUsage + "): ") : OUString(": "));
msg += (valid ? SwResId(STR_VALID) : SwResId(STR_INVALID));
diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx
index ee4d46bbc833..46d6a8a4098b 100644
--- a/sw/source/filter/basflt/fltshell.cxx
+++ b/sw/source/filter/basflt/fltshell.cxx
@@ -652,9 +652,8 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
{
SwTextNode const*const pTextNode(
aRegion.End()->nNode.GetNode().GetTextNode());
- assert(pTextNode);
- SwTextField const*const pField(pTextNode->GetFieldTextAttrAt(
- aRegion.End()->nContent.GetIndex() - 1, true));
+ SwTextField const*const pField = pTextNode ? pTextNode->GetFieldTextAttrAt(
+ aRegion.End()->nContent.GetIndex() - 1, true) : nullptr;
if (pField)
{
SwPostItField const*const pPostIt(
diff --git a/sw/source/filter/html/htmlplug.cxx b/sw/source/filter/html/htmlplug.cxx
index b6ccae2ee122..5cb439228e94 100644
--- a/sw/source/filter/html/htmlplug.cxx
+++ b/sw/source/filter/html/htmlplug.cxx
@@ -1087,7 +1087,12 @@ void SwHTMLParser::InsertFloatingFrame()
bool bHasBorder = aFrameDesc.HasFrameBorder();
Size aMargin = aFrameDesc.GetMargin();
- xSet->setPropertyValue("FrameURL", uno::makeAny( aFrameDesc.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ) ) );
+ OUString sHRef = aFrameDesc.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE );
+
+ if (INetURLObject(sHRef).GetProtocol() == INetProtocol::Macro)
+ NotifyMacroEventRead();
+
+ xSet->setPropertyValue("FrameURL", uno::makeAny( sHRef ) );
xSet->setPropertyValue("FrameName", uno::makeAny( aName ) );
if ( eScroll == ScrollingMode::Auto )
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 643601e144e3..e8e0c06db234 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -2331,26 +2331,40 @@ void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
void WW8PLCF::MakeFailedPLCF()
{
nIMax = 0;
- pPLCF_PosArray.reset( new sal_Int32[2] );
+ pPLCF_PosArray.reset( new WW8_CP[2] );
pPLCF_PosArray[0] = pPLCF_PosArray[1] = WW8_CP_MAX;
pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]);
}
-void WW8PLCF::TruncToSortedRange()
+namespace
{
- //Docs state that: ... all Plcs ... are sorted in ascending order.
- //So ensure that here for broken documents.
- for (auto nI = 0; nI < nIMax; ++nI)
+ sal_Int32 TruncToSortedRange(const sal_Int32* pPLCF_PosArray, sal_Int32 nIMax)
{
- if (pPLCF_PosArray[nI] > pPLCF_PosArray[nI+1])
+ //Docs state that: ... all Plcs ... are sorted in ascending order.
+ //So ensure that here for broken documents.
+ for (auto nI = 0; nI < nIMax; ++nI)
{
- SAL_WARN("sw.ww8", "Document has unsorted PLCF, truncated to sorted portion");
- nIMax = nI;
- break;
+ if (pPLCF_PosArray[nI] > pPLCF_PosArray[nI+1])
+ {
+ SAL_WARN("sw.ww8", "Document has unsorted PLCF, truncated to sorted portion");
+ nIMax = nI;
+ break;
+ }
}
+ return nIMax;
}
}
+void WW8PLCFpcd::TruncToSortedRange()
+{
+ nIMax = ::TruncToSortedRange(pPLCF_PosArray.get(), nIMax);
+}
+
+void WW8PLCF::TruncToSortedRange()
+{
+ nIMax = ::TruncToSortedRange(pPLCF_PosArray.get(), nIMax);
+}
+
void WW8PLCF::GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN)
{
OSL_ENSURE( nIMax < ncpN, "Pcl.Fkp: Why is PLCF too big?" );
@@ -2372,7 +2386,7 @@ void WW8PLCF::GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN)
{
size_t nSiz = (4 + nStru) * nIMax + 4;
size_t nElems = ( nSiz + 3 ) / 4;
- pPLCF_PosArray.reset( new sal_Int32[ nElems ] ); // Pointer to Pos-array
+ pPLCF_PosArray.reset( new WW8_CP[ nElems ] ); // Pointer to Pos-array
for (sal_Int32 i = 0; i < ncpN && !failure; ++i)
{
@@ -2506,7 +2520,7 @@ WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
bValid = false;
nPLCF = bValid ? std::min(nRemainingSize, static_cast<std::size_t>(nPLCF)) : nValidMin;
- pPLCF_PosArray.reset( new sal_Int32[ ( nPLCF + 3 ) / 4 ] ); // Pointer to Pos-array
+ pPLCF_PosArray.reset( new WW8_CP[ ( nPLCF + 3 ) / 4 ] ); // Pointer to Pos-array
pPLCF_PosArray[0] = 0;
nPLCF = bValid ? pSt->ReadBytes(pPLCF_PosArray.get(), nPLCF) : nValidMin;
@@ -2520,6 +2534,7 @@ WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
// Pointer to content array
pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]);
+ TruncToSortedRange();
pSt->Seek( nOldPos );
}
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 3eae6d1b30b3..e8f6db496950 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -346,14 +346,16 @@ class WW8PLCFpcd
{
friend class WW8PLCFpcd_Iter;
- std::unique_ptr<sal_Int32[]> pPLCF_PosArray; // pointer to Pos-array and the whole structure
+ std::unique_ptr<WW8_CP[]> pPLCF_PosArray; // pointer to Pos-array and the whole structure
sal_uInt8* pPLCF_Contents; // pointer to content-array-part of Pos-array
- long nIMax;
+ sal_Int32 nIMax;
sal_uInt32 nStru;
WW8PLCFpcd(const WW8PLCFpcd&) = delete;
WW8PLCFpcd& operator=(const WW8PLCFpcd&) = delete;
+ void TruncToSortedRange();
+
public:
WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos, sal_uInt32 nPLCF,
sal_uInt32 nStruct);
diff --git a/sw/source/filter/xml/xmltexti.cxx b/sw/source/filter/xml/xmltexti.cxx
index 02851e8e6a48..ad2e26e7039c 100644
--- a/sw/source/filter/xml/xmltexti.cxx
+++ b/sw/source/filter/xml/xmltexti.cxx
@@ -855,9 +855,14 @@ uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertFloatingFra
uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
if ( xSet.is() )
{
+ OUString sHRef = URIHelper::SmartRel2Abs(
+ INetURLObject( GetXMLImport().GetBaseURL() ), rHRef );
+
+ if (INetURLObject(sHRef).GetProtocol() == INetProtocol::Macro)
+ GetXMLImport().NotifyMacroEventRead();
+
xSet->setPropertyValue("FrameURL",
- makeAny( URIHelper::SmartRel2Abs(
- INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) ) );
+ makeAny( sHRef ) );
xSet->setPropertyValue("FrameName",
makeAny( rName ) );
diff --git a/sw/source/uibase/uiview/uivwimp.cxx b/sw/source/uibase/uiview/uivwimp.cxx
index e7ce5be812ab..2f8b55b00043 100644
--- a/sw/source/uibase/uiview/uivwimp.cxx
+++ b/sw/source/uibase/uiview/uivwimp.cxx
@@ -289,6 +289,8 @@ SwClipboardChangeListener::~SwClipboardChangeListener()
void SAL_CALL SwClipboardChangeListener::disposing( const EventObject& /*rEventObject*/ )
{
+ SolarMutexGuard aGuard;
+ pView = nullptr; // so we don't touch the view if changedContents somehow fires afterwards
}
void SAL_CALL SwClipboardChangeListener::changedContents( const css::datatransfer::clipboard::ClipboardEvent& rEventObject )
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index c47d46422b53..2b8474f5c0cf 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -53,6 +53,7 @@
#include <vcl/weld.hxx>
#include <bitmaps.hlst>
#include <vcl/salvtables.hxx>
+#include <comphelper/lok.hxx>
SalFrame::SalFrame()
: m_pWindow(nullptr)
@@ -3484,7 +3485,7 @@ void SalInstanceWindow::help()
{
//show help for widget with keyboard focus
vcl::Window* pWidget = ImplGetSVData()->mpWinData->mpFocusWin;
- if (!pWidget)
+ if (!pWidget || comphelper::LibreOfficeKit::isActive())
pWidget = m_xWindow;
OString sHelpId = pWidget->GetHelpId();
while (sHelpId.isEmpty())
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 845c397b0eef..d9ce10ae4549 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -1846,7 +1846,7 @@ void HelpButton::Click()
if ( !GetClickHdl() )
{
vcl::Window* pFocusWin = Application::GetFocusWindow();
- if ( !pFocusWin )
+ if ( !pFocusWin || comphelper::LibreOfficeKit::isActive() )
pFocusWin = this;
HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT );
diff --git a/vcl/source/font/fontcharmap.cxx b/vcl/source/font/fontcharmap.cxx
index ade991626dd9..5ddd4a0fd5f1 100644
--- a/vcl/source/font/fontcharmap.cxx
+++ b/vcl/source/font/fontcharmap.cxx
@@ -206,7 +206,7 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
// update the glyphid-array with the glyphs in this range
pStartGlyphs[i] = -static_cast<int>(aGlyphIdArray.size());
const unsigned char* pGlyphIdPtr = pOffsetBase + 2*i + nRangeOffset;
- const size_t nRemainingSize = pEndValidArea - pGlyphIdPtr;
+ const size_t nRemainingSize = pEndValidArea >= pGlyphIdPtr ? pEndValidArea - pGlyphIdPtr : 0;
const size_t nMaxPossibleRecords = nRemainingSize/2;
if (nMaxPossibleRecords == 0) { // no sane font should trigger this
SAL_WARN("vcl.gdi", "More indexes claimed that space available in font!");
@@ -294,7 +294,8 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
static const int NINSIZE = 64;
static const int NOUTSIZE = 64;
- sal_Char cCharsInp[ NINSIZE ];
+ std::vector<char> cCharsInp;
+ cCharsInp.reserve(NINSIZE);
sal_Unicode cCharsOut[ NOUTSIZE ];
sal_UCS4* pCP = pCodePairs;
for( int i = 0; i < nRangeCount; ++i )
@@ -303,25 +304,26 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
sal_UCS4 cEnd = *(pCP++);
while( cMin < cEnd )
{
- int j = 0;
- for(; (cMin < cEnd) && (j < NINSIZE); ++cMin )
+ for (int j = 0; (cMin < cEnd) && (j < NINSIZE); ++cMin, ++j)
{
if( cMin >= 0x0100 )
- cCharsInp[ j++ ] = static_cast<sal_Char>(cMin >> 8);
+ cCharsInp.push_back(static_cast<char>(cMin >> 8));
if( (cMin >= 0x0100) || (cMin < 0x00A0) )
- cCharsInp[ j++ ] = static_cast<sal_Char>(cMin);
+ cCharsInp.push_back(static_cast<char>(cMin));
}
sal_uInt32 nCvtInfo;
sal_Size nSrcCvtBytes;
int nOutLen = rtl_convertTextToUnicode(
aConverter, aCvtContext,
- cCharsInp, j, cCharsOut, NOUTSIZE,
+ cCharsInp.data(), cCharsInp.size(), cCharsOut, NOUTSIZE,
RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
| RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE,
&nCvtInfo, &nSrcCvtBytes );
- for( j = 0; j < nOutLen; ++j )
+ cCharsInp.clear();
+
+ for (int j = 0; j < nOutLen; ++j)
aSupportedCodePoints.insert( cCharsOut[j] );
}
}
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 209179cc9591..db183d7ca1d9 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -1421,7 +1421,7 @@ IMPL_LINK(Dialog, ResponseHdl, Button*, pButton, void)
if (nResponse == RET_HELP)
{
vcl::Window* pFocusWin = Application::GetFocusWindow();
- if (!pFocusWin)
+ if (!pFocusWin || comphelper::LibreOfficeKit::isActive())
pFocusWin = pButton;
HelpEvent aEvt(pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT);
pFocusWin->RequestHelp(aEvt);
diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx
index 47116725856f..663da0ff872c 100644
--- a/vcl/source/window/mouse.cxx
+++ b/vcl/source/window/mouse.cxx
@@ -253,7 +253,7 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags )
bool bAsyncFocusWaiting = false;
vcl::Window *pFrame = pSVData->maFrameData.mpFirstFrame;
- while( pFrame )
+ while( pFrame && pFrame->mpWindowImpl && pFrame->mpWindowImpl->mpFrameData )
{
if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
{
@@ -276,6 +276,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags )
bMustNotGrabFocus = true;
break;
}
+ if (!pParent->mpWindowImpl)
+ break;
pParent = pParent->mpWindowImpl->mpParent;
}
@@ -333,13 +335,16 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags )
else
{
vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
- vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
- pNewOverlapWindow->mpWindowImpl->mbActive = true;
- pNewOverlapWindow->Activate();
- if ( pNewRealWindow != pNewOverlapWindow )
+ if ( pNewOverlapWindow && pNewOverlapWindow->mpWindowImpl )
{
- pNewRealWindow->mpWindowImpl->mbActive = true;
- pNewRealWindow->Activate();
+ vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
+ pNewOverlapWindow->mpWindowImpl->mbActive = true;
+ pNewOverlapWindow->Activate();
+ if ( pNewRealWindow != pNewOverlapWindow && pNewRealWindow && pNewRealWindow->mpWindowImpl )
+ {
+ pNewRealWindow->mpWindowImpl->mbActive = true;
+ pNewRealWindow->Activate();
+ }
}
}
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
index ef8641986555..0d22f446dea7 100644
--- a/vcl/source/window/toolbox.cxx
+++ b/vcl/source/window/toolbox.cxx
@@ -3209,7 +3209,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt )
// and do not highlight when focus is in a different toolbox
bool bDrawHotSpot = true;
vcl::Window *pWin = Application::GetFocusWindow();
- if( pWin && pWin->ImplGetWindowImpl()->mbToolBox && pWin != this )
+ if( pWin && pWin->ImplGetWindowImpl() && pWin->ImplGetWindowImpl()->mbToolBox && pWin != this )
bDrawHotSpot = false;
if ( mbSelection && bDrawHotSpot )
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 10638fa43957..bf270d6f2ffb 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -3236,12 +3236,12 @@ void Window::ReleaseLOKNotifier()
const vcl::ILibreOfficeKitNotifier* Window::GetLOKNotifier() const
{
- return mpWindowImpl->mpLOKNotifier;
+ return mpWindowImpl ? mpWindowImpl->mpLOKNotifier : nullptr;
}
vcl::LOKWindowId Window::GetLOKWindowId() const
{
- return mpWindowImpl->mnLOKWindowId;
+ return mpWindowImpl ? mpWindowImpl->mnLOKWindowId : 0;
}
VclPtr<vcl::Window> Window::GetParentWithLOKNotifier()
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 31620bc6a0ac..4dea82046299 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -814,17 +814,20 @@ static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow )
vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat;
while (pChild)
{
- if (pChild->ImplGetWindowImpl()->mbFloatWin)
+ if (pChild->ImplGetWindowImpl())
{
- if (static_cast<FloatingWindow *>(pChild)->GrabsFocus())
- break;
- }
- else if (pChild->ImplGetWindowImpl()->mbDockWin)
- {
- vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent);
- if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin &&
- static_cast<FloatingWindow *>(pParent)->GrabsFocus())
- break;
+ if (pChild->ImplGetWindowImpl()->mbFloatWin)
+ {
+ if (static_cast<FloatingWindow *>(pChild)->GrabsFocus())
+ break;
+ }
+ else if (pChild->ImplGetWindowImpl()->mbDockWin)
+ {
+ vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent);
+ if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin &&
+ static_cast<FloatingWindow *>(pParent)->GrabsFocus())
+ break;
+ }
}
pChild = pChild->GetParent();
}
@@ -832,7 +835,7 @@ static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow )
if (!pChild)
pChild = pWindow;
- pChild = pChild->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ pChild = pChild->ImplGetWindowImpl() && pChild->ImplGetWindowImpl()->mpFrameData ? pChild->ImplGetWindowImpl()->mpFrameData->mpFocusWin.get() : nullptr;
// no child - then no input
if ( !pChild )
@@ -1740,6 +1743,9 @@ static void ImplActivateFloatingWindows( vcl::Window const * pWindow, bool bActi
IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl, void*, void)
{
+ if (!ImplGetWindowImpl() || !ImplGetWindowImpl()->mpFrameData)
+ return;
+
ImplGetWindowImpl()->mpFrameData->mnFocusId = nullptr;
// If the status has been preserved, because we got back the focus
@@ -1798,22 +1804,27 @@ IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl, void*, void)
{
// transfer the FocusWindow
vcl::Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
- pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
+ if ( pOverlapWindow && pOverlapWindow->ImplGetWindowImpl() )
+ pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
pSVData->mpWinData->mpFocusWin = nullptr;
- if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
+ if ( pFocusWin->ImplGetWindowImpl() && pFocusWin->ImplGetWindowImpl()->mpCursor )
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
// call the Deactivate
vcl::Window* pOldOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
vcl::Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
- pOldOverlapWindow->ImplGetWindowImpl()->mbActive = false;
- pOldOverlapWindow->Deactivate();
- if ( pOldRealWindow != pOldOverlapWindow )
+ if (pOldOverlapWindow && pOldOverlapWindow->ImplGetWindowImpl() &&
+ pOldRealWindow && pOldRealWindow->ImplGetWindowImpl())
{
- pOldRealWindow->ImplGetWindowImpl()->mbActive = false;
- pOldRealWindow->Deactivate();
+ pOldOverlapWindow->ImplGetWindowImpl()->mbActive = false;
+ pOldOverlapWindow->Deactivate();
+ if ( pOldRealWindow != pOldOverlapWindow )
+ {
+ pOldRealWindow->ImplGetWindowImpl()->mbActive = false;
+ pOldRealWindow->Deactivate();
+ }
}
// TrackingMode is ended in ImplHandleLoseFocus
diff --git a/wizards/source/access2base/DoCmd.xba b/wizards/source/access2base/DoCmd.xba
index 588a170dc62f..e479c32a5cd0 100644
--- a/wizards/source/access2base/DoCmd.xba
+++ b/wizards/source/access2base/DoCmd.xba
@@ -2656,7 +2656,7 @@ Private Sub _ShellExecute(sCommand As String)
Dim oShell As Object
Set oShell = createUnoService(&quot;com.sun.star.system.SystemShellExecute&quot;)
- oShell.execute(sCommand, &quot;&quot; , com.sun.star.system.SystemShellExecuteFlags.DEFAULTS)
+ oShell.execute(sCommand, &quot;&quot; , com.sun.star.system.SystemShellExecuteFlags.URIS_ONLY)
End Sub &apos; _ShellExecute V0.8.5
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 0c5437b93ad9..28d5bac8d780 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -650,6 +650,8 @@ void SAL_CALL SvXMLImport::endDocument()
}
std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
+ std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,
+ SvXMLImport *const pImport, // TODO???
const uno::Reference< xml::sax::XAttributeList >& xAttrList)
{
std::unique_ptr<SvXMLNamespaceMap> pRewindMap;
@@ -657,12 +659,13 @@ std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
for( sal_Int16 i=0; i < nAttrCount; i++ )
{
const OUString& rAttrName = xAttrList->getNameByIndex( i );
- if ( rAttrName == "office:version" )
+ if (pImport && rAttrName == "office:version")
{
- mpImpl->aODFVersion = xAttrList->getValueByIndex( i );
+ pImport->mpImpl->aODFVersion = xAttrList->getValueByIndex( i );
// the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
- if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( mpImpl->aODFVersion ) )
+ if (pImport->mpImpl->mStreamName == "content.xml"
+ && !pImport->IsODFVersionConsistent(pImport->mpImpl->aODFVersion))
{
throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
uno::Reference< uno::XInterface >(),
@@ -676,8 +679,8 @@ std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
{
if( !pRewindMap )
{
- pRewindMap = std::move(mpNamespaceMap);
- mpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap));
+ pRewindMap = std::move(rpNamespaceMap);
+ rpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap));
}
const OUString& rAttrValue = xAttrList->getValueByIndex( i );
@@ -685,18 +688,18 @@ std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
? OUString()
: rAttrName.copy( 6 ) );
// Add namespace, but only if it is known.
- sal_uInt16 nKey = mpNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
+ sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
// If namespace is unknown, try to match a name with similar
// TC Id an version
if( XML_NAMESPACE_UNKNOWN == nKey )
{
OUString aTestName( rAttrValue );
if( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
- nKey = mpNamespaceMap->AddIfKnown( aPrefix, aTestName );
+ nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName );
}
// If that namespace is not known, too, add it as unknown
if( XML_NAMESPACE_UNKNOWN == nKey )
- mpNamespaceMap->Add( aPrefix, rAttrValue );
+ rpNamespaceMap->Add( aPrefix, rAttrValue );
}
}
@@ -709,7 +712,8 @@ void SAL_CALL SvXMLImport::startElement( const OUString& rName,
// SAL_INFO("svg", "startElement " << rName);
// Process namespace attributes. This must happen before creating the
// context, because namespace declaration apply to the element name itself.
- std::unique_ptr<SvXMLNamespaceMap> pRewindMap(processNSAttributes(xAttrList));
+ std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
+ processNSAttributes(mpNamespaceMap, this, xAttrList));
// Get element's namespace and local name.
OUString aLocalName;
@@ -882,7 +886,7 @@ void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element,
maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList );
std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
- processNSAttributes( maNamespaceAttrList.get() ));
+ processNSAttributes(mpNamespaceMap, this, maNamespaceAttrList.get()));
assert( dynamic_cast<SvXMLImportContext*>( xContext.get() ) != nullptr );
SvXMLImportContext *pContext = static_cast<SvXMLImportContext*>( xContext.get() );
if (pRewindMap)
@@ -2237,7 +2241,7 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument()
void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
- mrImport->processNSAttributes(xAttrList);
+ SvXMLImport::processNSAttributes(mrImport->mpNamespaceMap, mrImport.get(), xAttrList);
OUString aLocalName;
sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>(
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index c4a59a344b95..00191b9a4792 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -135,6 +135,19 @@ namespace xmloff { namespace token {
TOKEN( "grddl", XML_NP_GRDDL ),
TOKEN( "http://www.w3.org/2003/g/data-view#", XML_N_GRDDL ),
+ // OOo extension digital signatures, used in ODF 1.1
+ TOKEN( "dsigooo", XML_NP_DSIG_OOO ),
+ TOKEN( "http://openoffice.org/2004/documentsignatures", XML_N_DSIG_OOO ),
+ // ODF 1.2 digital signature namespaces
+ TOKEN( "dsig", XML_NP_DSIG ),
+ TOKEN( "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0", XML_N_DSIG ),
+ TOKEN( "ds", XML_NP_DS ),
+ TOKEN( "http://www.w3.org/2000/09/xmldsig#", XML_N_DS ),
+ TOKEN( "xades132", XML_NP_XADES132 ),
+ TOKEN( "http://uri.etsi.org/01903/v1.3.2#", XML_N_XADES132 ),
+ TOKEN( "xades141", XML_NP_XADES141 ),
+ TOKEN( "http://uri.etsi.org/01903/v1.4.1#", XML_N_XADES141 ),
+
// ODF Enhanced namespaces
TOKEN( "officeooo", XML_NP_OFFICE_EXT ),
TOKEN( "http://openoffice.org/2009/office", XML_N_OFFICE_EXT ),
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index 8988e52dd9f1..81aa648837e9 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -85,6 +85,7 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/vector/b2dvector.hxx>
+#include <tools/urlobj.hxx>
#include <o3tl/safeint.hxx>
#include <config_features.h>
@@ -3251,6 +3252,9 @@ void SdXMLFloatingFrameShapeContext::StartElement( const css::uno::Reference< cs
if( !maHref.isEmpty() )
{
+ if (INetURLObject(maHref).GetProtocol() == INetProtocol::Macro)
+ GetImport().NotifyMacroEventRead();
+
xProps->setPropertyValue("FrameURL", Any(maHref) );
}
}
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index b8ae30c6da3e..1321868b7df4 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -70,6 +70,16 @@ xhtml
N_XHTML_DUMMY
grddl
N_GRDDL_DUMMY
+dsigooo
+N_DSIG_OOO_DUMMY
+dsig
+N_DSIG_DUMMY
+ds
+N_DS_DUMMY
+xades132
+N_XADES132_DUMMY
+xades141
+N_XADES141_DUMMY
officeooo
N_OFFICE_EXT_DUMMY
formx
diff --git a/xmlsecurity/inc/biginteger.hxx b/xmlsecurity/inc/biginteger.hxx
index d07ecf45d8af..8b4d8a9143b5 100644
--- a/xmlsecurity/inc/biginteger.hxx
+++ b/xmlsecurity/inc/biginteger.hxx
@@ -31,6 +31,9 @@ namespace xmlsecurity
{
XSECXMLSEC_DLLPUBLIC OUString bigIntegerToNumericString( const css::uno::Sequence< sal_Int8 >& serial );
XSECXMLSEC_DLLPUBLIC css::uno::Sequence< sal_Int8 > numericStringToBigInteger ( const OUString& serialNumber );
+
+XSECXMLSEC_DLLPUBLIC bool EqualDistinguishedNames(OUString const& rName1,
+ OUString const& rName2);
}
#endif
diff --git a/xmlsecurity/inc/xmlsec-wrapper.h b/xmlsecurity/inc/xmlsec-wrapper.h
index c060c8bf23b8..2d06dcfdd549 100644
--- a/xmlsecurity/inc/xmlsec-wrapper.h
+++ b/xmlsecurity/inc/xmlsec-wrapper.h
@@ -43,6 +43,10 @@
#include <xmlsec/nss/app.h>
#include <xmlsec/nss/crypto.h>
#include <xmlsec/nss/pkikeys.h>
+#include <xmlsec/nss/x509.h>
+#endif
+#ifdef XMLSEC_CRYPTO_MSCRYPTO
+#include <xmlsec/mscng/x509.h>
#endif
#endif
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index 02128bb4f6a8..9d6bf7b3c6de 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -37,6 +37,9 @@
#include <com/sun/star/xml/crypto/sax/XSignatureCreationResultListener.hpp>
#include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultListener.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
+
class DateTime;
namespace com {
@@ -95,6 +98,15 @@ public:
// After signing/verifying, get information about signatures
SignatureInformation GetSignatureInformation( sal_Int32 nSecurityId ) const;
SignatureInformations GetSignatureInformations() const;
+ /// ImplVerifySignature calls this to figure out which X509Data is the
+ /// signing certificate and update the internal state with the result.
+ /// @return
+ /// A sequence with the signing certificate at the back on success.
+ /// An empty sequence on failure.
+ std::vector<css::uno::Reference<css::security::XCertificate>>
+ CheckAndUpdateSignatureInformation(
+ css::uno::Reference<css::xml::crypto::XSecurityEnvironment> const& xSecEnv,
+ SignatureInformation const& rInfo);
// See XSecController for documentation
void StartMission(const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext);
diff --git a/xmlsecurity/inc/xsecctl.hxx b/xmlsecurity/inc/xsecctl.hxx
index e84ea1dbe042..1b61be773f7d 100644
--- a/xmlsecurity/inc/xsecctl.hxx
+++ b/xmlsecurity/inc/xsecctl.hxx
@@ -259,6 +259,7 @@ private:
/// Sets algorithm from <SignatureMethod Algorithm="...">.
void setSignatureMethod(svl::crypto::SignatureMethodAlgorithm eAlgorithmID);
void switchGpgSignature();
+ bool haveReferenceForId(OUString const& rId) const;
void addReference(
const OUString& ouUri,
sal_Int32 nDigestID,
@@ -269,18 +270,21 @@ private:
sal_Int32 nDigestID );
void setReferenceCount() const;
- void setX509IssuerName( OUString const & ouX509IssuerName );
- void setX509SerialNumber( OUString const & ouX509SerialNumber );
- void setX509Certificate( OUString const & ouX509Certificate );
+ void setX509Data(
+ std::vector<std::pair<OUString, OUString>> & rX509IssuerSerials,
+ std::vector<OUString> const& rX509Certificates);
+ void setX509CertDigest(
+ OUString const& rCertDigest, sal_Int32 const nReferenceDigestID,
+ OUString const& rX509IssuerName, OUString const& rX509SerialNumber);
+
void setSignatureValue( OUString const & ouSignatureValue );
void setDigestValue( sal_Int32 nDigestID, OUString const & ouDigestValue );
void setGpgKeyID( OUString const & ouKeyID );
void setGpgCertificate( OUString const & ouGpgCert );
void setGpgOwner( OUString const & ouGpgOwner );
- void setDate( OUString const & ouDate );
- void setDescription(const OUString& rDescription);
- void setCertDigest(const OUString& rCertDigest);
+ void setDate(OUString const& rId, OUString const& ouDate);
+ void setDescription(OUString const& rId, OUString const& rDescription);
void setValidSignatureImage(const OUString& rValidSigImg);
void setInvalidSignatureImage(const OUString& rInvalidSigImg);
void setSignatureLineId(const OUString& rSignatureLineId);
@@ -290,7 +294,6 @@ public:
private:
void setId( OUString const & ouId );
- void setPropertyId( OUString const & ouPropertyId );
css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToRead(
sal_Int32 nSecurityId );
@@ -310,6 +313,9 @@ public:
SignatureInformation getSignatureInformation( sal_Int32 nSecurityId ) const;
SignatureInformations getSignatureInformations() const;
+ /// only verify can figure out which X509Data is the signing certificate
+ void UpdateSignatureInformation(sal_Int32 nSecurityId,
+ std::vector<SignatureInformation::X509Data> const& rDatas);
static void exportSignature(
const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
diff --git a/xmlsecurity/qa/unit/signing/data/02_doc_macros_signed_by_attacker_manipulated.odt b/xmlsecurity/qa/unit/signing/data/02_doc_macros_signed_by_attacker_manipulated.odt
new file mode 100644
index 000000000000..d63e4b6b7b72
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/02_doc_macros_signed_by_attacker_manipulated.odt
Binary files differ
diff --git a/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated.odt b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated.odt
new file mode 100644
index 000000000000..0190abb00f23
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated.odt
Binary files differ
diff --git a/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated2.odt b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated2.odt
new file mode 100644
index 000000000000..f4b4198f94a6
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated2.odt
Binary files differ
diff --git a/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated_triple.odt b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated_triple.odt
new file mode 100644
index 000000000000..558bdee47e59
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_attacker_manipulated_triple.odt
Binary files differ
diff --git a/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_trusted_person_manipulated.odt b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_trusted_person_manipulated.odt
new file mode 100644
index 000000000000..4136b32e5610
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/02_doc_signed_by_trusted_person_manipulated.odt
Binary files differ
diff --git a/xmlsecurity/qa/unit/signing/data/signed_with_x509certificate_chain.odt b/xmlsecurity/qa/unit/signing/data/signed_with_x509certificate_chain.odt
new file mode 100644
index 000000000000..5e519dd8b7e7
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/signed_with_x509certificate_chain.odt
Binary files differ
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index 5ed480ba819d..729baf586312 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -24,6 +24,7 @@
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
+#include <com/sun/star/security/CertificateValidity.hpp>
#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
@@ -80,6 +81,12 @@ public:
void testODFBroken();
/// Document has a signature stream, but no actual signatures.
void testODFNo();
+ void testODFUnsignedTimestamp();
+ void testODFX509CertificateChain();
+ void testODFDoubleX509Data();
+ void testODFTripleX509Data();
+ void testODFMacroDoubleX509Data();
+ void testODFDoubleX509Certificate();
/// Test a typical OOXML where a number of (but not all) streams are signed.
void testOOXMLPartial();
/// Test a typical broken OOXML signature where one stream is corrupted.
@@ -133,6 +140,12 @@ public:
CPPUNIT_TEST(testODFBroken);
CPPUNIT_TEST(testODFNo);
CPPUNIT_TEST(testODFBroken);
+ CPPUNIT_TEST(testODFUnsignedTimestamp);
+ CPPUNIT_TEST(testODFX509CertificateChain);
+ CPPUNIT_TEST(testODFDoubleX509Data);
+ CPPUNIT_TEST(testODFTripleX509Data);
+ CPPUNIT_TEST(testODFMacroDoubleX509Data);
+ CPPUNIT_TEST(testODFDoubleX509Certificate);
CPPUNIT_TEST(testOOXMLPartial);
CPPUNIT_TEST(testOOXMLBroken);
CPPUNIT_TEST(testOOXMLDescription);
@@ -635,6 +648,128 @@ void SigningTest::testODFNo()
static_cast<int>(pObjectShell->GetDocumentSignatureState()));
}
+// document has one signed timestamp and one unsigned timestamp
+void SigningTest::testODFUnsignedTimestamp()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "02_doc_signed_by_trusted_person_manipulated.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ CPPUNIT_ASSERT_MESSAGE(
+ (OString::number(/*o3tl::underlyingEnumValue(*/ (int)nActual /*)*/).getStr()),
+ (nActual == SignatureState::NOTVALIDATED || nActual == SignatureState::OK));
+ uno::Sequence<security::DocumentSignatureInformation> const infos(
+ pObjectShell->GetDocumentSignatureInformation(false));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), infos.getLength());
+ // was: 66666666
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(20210126), infos[0].SignatureDate);
+ // was: 0
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(18183742), infos[0].SignatureTime);
+}
+
+void SigningTest::testODFX509CertificateChain()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "signed_with_x509certificate_chain.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ CPPUNIT_ASSERT_MESSAGE(
+ (OString::number(/*o3tl::underlyingEnumValue(*/ (int)nActual /*)*/).getStr()),
+ (nActual == SignatureState::NOTVALIDATED || nActual == SignatureState::OK));
+ uno::Sequence<security::DocumentSignatureInformation> const infos(
+ pObjectShell->GetDocumentSignatureInformation(false));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), infos.getLength());
+ // check that the signing certificate was picked, not one of the 2 CA ones
+ CPPUNIT_ASSERT_EQUAL(security::CertificateValidity::VALID, infos[0].CertificateStatus);
+ CPPUNIT_ASSERT(infos[0].Signer.is());
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("CN=Xmlsecurity RSA Test example Alice,O=Xmlsecurity RSA Test,ST=England,C=UK"),
+ infos[0].Signer->getSubjectName());
+}
+
+void SigningTest::testODFDoubleX509Data()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "02_doc_signed_by_attacker_manipulated.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ CPPUNIT_ASSERT_MESSAGE(
+ (OString::number(/*o3tl::underlyingEnumValue(*/ (int)nActual /*)*/).getStr()),
+ (nActual == SignatureState::NOTVALIDATED || nActual == SignatureState::OK));
+ uno::Sequence<security::DocumentSignatureInformation> const infos(
+ pObjectShell->GetDocumentSignatureInformation(false));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), infos.getLength());
+ CPPUNIT_ASSERT_EQUAL(security::CertificateValidity::INVALID, infos[0].CertificateStatus);
+ CPPUNIT_ASSERT(!infos[0].Signer.is());
+}
+
+void SigningTest::testODFTripleX509Data()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "02_doc_signed_by_attacker_manipulated_triple.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ // here, libxmlsec will pick the 1st X509Data but signing key is the 2nd
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ (OString::number(/*o3tl::underlyingEnumValue(*/ (int)nActual /*)*/).getStr()),
+ SignatureState::BROKEN, nActual);
+ uno::Sequence<security::DocumentSignatureInformation> const infos(
+ pObjectShell->GetDocumentSignatureInformation(false));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), infos.getLength());
+ CPPUNIT_ASSERT_EQUAL(security::CertificateValidity::INVALID, infos[0].CertificateStatus);
+ CPPUNIT_ASSERT(!infos[0].Signer.is());
+}
+
+void SigningTest::testODFMacroDoubleX509Data()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "02_doc_macros_signed_by_attacker_manipulated.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ SignatureState nActual = pObjectShell->GetScriptingSignatureState();
+ CPPUNIT_ASSERT_MESSAGE(
+ (OString::number(/*o3tl::underlyingEnumValue(*/ (int)nActual /*)*/).getStr()),
+ (nActual == SignatureState::NOTVALIDATED || nActual == SignatureState::OK));
+ uno::Sequence<security::DocumentSignatureInformation> const infos(
+ pObjectShell->GetDocumentSignatureInformation(true));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), infos.getLength());
+ CPPUNIT_ASSERT_EQUAL(security::CertificateValidity::INVALID, infos[0].CertificateStatus);
+ CPPUNIT_ASSERT(!infos[0].Signer.is());
+}
+
+void SigningTest::testODFDoubleX509Certificate()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "02_doc_signed_by_attacker_manipulated2.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ CPPUNIT_ASSERT_MESSAGE(
+ (OString::number(/*o3tl::underlyingEnumValue(*/ (int)nActual /*)*/).getStr()),
+ (nActual == SignatureState::NOTVALIDATED || nActual == SignatureState::OK));
+ uno::Sequence<security::DocumentSignatureInformation> const infos(
+ pObjectShell->GetDocumentSignatureInformation(false));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), infos.getLength());
+ CPPUNIT_ASSERT_EQUAL(security::CertificateValidity::INVALID, infos[0].CertificateStatus);
+ CPPUNIT_ASSERT(!infos[0].Signer.is());
+}
+
void SigningTest::testOOXMLPartial()
{
createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY) + "partial.docx");
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index c67d893b0624..fdd08892d24a 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -499,27 +499,36 @@ DocumentDigitalSignatures::ImplVerifySignatures(
const SignatureInformation& rInfo = aSignInfos[n];
css::security::DocumentSignatureInformation& rSigInfo = arInfos[n];
- if (rInfo.ouGpgCertificate.isEmpty()) // X.509
+ if (!rInfo.X509Datas.empty()) // X.509
{
- if (!rInfo.ouX509Certificate.isEmpty())
- rSigInfo.Signer = xSecEnv->createCertificateFromAscii( rInfo.ouX509Certificate ) ;
- if (!rSigInfo.Signer.is())
- rSigInfo.Signer = xSecEnv->getCertificate( rInfo.ouX509IssuerName,
- xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
-
+ std::vector<uno::Reference<security::XCertificate>> certs(
+ rSignatureHelper.CheckAndUpdateSignatureInformation(
+ xSecEnv, rInfo));
+ if (certs.empty())
+ {
+ rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
+ }
+ else
+ {
+ rSigInfo.Signer = certs.back();
+ // get only intermediates
+ certs.pop_back();
// On Windows checking the certificate path is buggy. It does name matching (issuer, subject name)
// to find the parent certificate. It does not take into account that there can be several certificates
// with the same subject name.
-
- try {
- rSigInfo.CertificateStatus = xSecEnv->verifyCertificate(rSigInfo.Signer,
- Sequence<Reference<css::security::XCertificate> >());
- } catch (SecurityException& ) {
- OSL_FAIL("Verification of certificate failed");
- rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
+ try
+ {
+ rSigInfo.CertificateStatus = xSecEnv->verifyCertificate(
+ rSigInfo.Signer, comphelper::containerToSequence(certs));
+ }
+ catch (SecurityException&)
+ {
+ SAL_WARN("xmlsecurity.comp", "Verification of certificate failed");
+ rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
+ }
}
}
- else if (xGpgSecEnv.is()) // GPG
+ else if (!rInfo.ouGpgCertificate.isEmpty() && xGpgSecEnv.is()) // GPG
{
// TODO not ideal to retrieve cert by keyID, might
// collide, or PGPKeyID format might change - can't we
@@ -604,11 +613,15 @@ void DocumentDigitalSignatures::showCertificate(
}
sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
- const Reference< css::security::XCertificate >& Author )
+ const Reference<css::security::XCertificate>& xAuthor)
{
+ if (!xAuthor.is())
+ {
+ return false;
+ }
bool bFound = false;
- OUString sSerialNum = xmlsecurity::bigIntegerToNumericString( Author->getSerialNumber() );
+ OUString sSerialNum = xmlsecurity::bigIntegerToNumericString(xAuthor->getSerialNumber());
Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = SvtSecurityOptions().GetTrustedAuthors();
const SvtSecurityOptions::Certificate* pAuthors = aTrustedAuthors.getConstArray();
@@ -616,7 +629,8 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
for ( ; pAuthors != pAuthorsEnd; ++pAuthors )
{
SvtSecurityOptions::Certificate aAuthor = *pAuthors;
- if ( ( aAuthor[0] == Author->getIssuerName() ) && ( aAuthor[1] == sSerialNum ) )
+ if (xmlsecurity::EqualDistinguishedNames(aAuthor[0], xAuthor->getIssuerName())
+ && (aAuthor[1] == sSerialNum))
{
bFound = true;
break;
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 2280c77bbfb1..fbaf5a10ef14 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -593,7 +593,7 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
if (!rInfo.ouGpgCertificate.isEmpty())
aType = "OpenPGP";
// XML based: XAdES or not.
- else if (!rInfo.ouCertDigest.isEmpty())
+ else if (rInfo.GetSigningCertificate() && !rInfo.GetSigningCertificate()->CertDigest.isEmpty())
aType = "XAdES";
else
aType = "XML-DSig";
@@ -691,8 +691,8 @@ uno::Reference<security::XCertificate> DigitalSignaturesDialog::getCertificate(c
uno::Reference<security::XCertificate> xCert;
//First we try to get the certificate which is embedded in the XML Signature
- if (xSecEnv.is() && !rInfo.ouX509Certificate.isEmpty())
- xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
+ if (xSecEnv.is() && rInfo.GetSigningCertificate() && !rInfo.GetSigningCertificate()->X509Certificate.isEmpty())
+ xCert = xSecEnv->createCertificateFromAscii(rInfo.GetSigningCertificate()->X509Certificate);
else {
//There must be an embedded certificate because we use it to get the
//issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
@@ -704,9 +704,12 @@ uno::Reference<security::XCertificate> DigitalSignaturesDialog::getCertificate(c
}
//In case there is no embedded certificate we try to get it from a local store
- if (!xCert.is() && xSecEnv.is())
- xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
- if (!xCert.is() && xGpgSecEnv.is())
+ if (!xCert.is() && xSecEnv.is() && rInfo.GetSigningCertificate())
+ {
+ xCert = xSecEnv->getCertificate(rInfo.GetSigningCertificate()->X509IssuerName,
+ xmlsecurity::numericStringToBigInteger(rInfo.GetSigningCertificate()->X509SerialNumber));
+ }
+ if (!xCert.is() && xGpgSecEnv.is() && !rInfo.ouGpgKeyID.isEmpty())
xCert = xGpgSecEnv->getCertificate( rInfo.ouGpgKeyID, xmlsecurity::numericStringToBigInteger("") );
SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Certificate not found and can't be created!" );
diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx
index 1dda0be4d7f5..47e788b759bb 100644
--- a/xmlsecurity/source/helper/documentsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx
@@ -512,6 +512,29 @@ void DocumentSignatureHelper::writeDigestMethod(
xDocumentHandler->endElement("DigestMethod");
}
+static void WriteXadesCert(
+ uno::Reference<xml::sax::XDocumentHandler> const& xDocumentHandler,
+ SignatureInformation::X509CertInfo const& rCertInfo)
+{
+ xDocumentHandler->startElement("xd:Cert", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ xDocumentHandler->startElement("xd:CertDigest", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ DocumentSignatureHelper::writeDigestMethod(xDocumentHandler);
+ xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ assert(!rCertInfo.CertDigest.isEmpty());
+ xDocumentHandler->characters(rCertInfo.CertDigest);
+ xDocumentHandler->endElement("DigestValue");
+ xDocumentHandler->endElement("xd:CertDigest");
+ xDocumentHandler->startElement("xd:IssuerSerial", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ xDocumentHandler->startElement("X509IssuerName", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ xDocumentHandler->characters(rCertInfo.X509IssuerName);
+ xDocumentHandler->endElement("X509IssuerName");
+ xDocumentHandler->startElement("X509SerialNumber", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ xDocumentHandler->characters(rCertInfo.X509SerialNumber);
+ xDocumentHandler->endElement("X509SerialNumber");
+ xDocumentHandler->endElement("xd:IssuerSerial");
+ xDocumentHandler->endElement("xd:Cert");
+}
+
void DocumentSignatureHelper::writeSignedProperties(
const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
const SignatureInformation& signatureInfo,
@@ -528,26 +551,26 @@ void DocumentSignatureHelper::writeSignedProperties(
xDocumentHandler->characters(sDate);
xDocumentHandler->endElement("xd:SigningTime");
xDocumentHandler->startElement("xd:SigningCertificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- xDocumentHandler->startElement("xd:Cert", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- xDocumentHandler->startElement("xd:CertDigest", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- writeDigestMethod(xDocumentHandler);
-
- xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- // TODO: this is empty for gpg signatures currently
- //assert(!signatureInfo.ouCertDigest.isEmpty());
- xDocumentHandler->characters(signatureInfo.ouCertDigest);
- xDocumentHandler->endElement("DigestValue");
-
- xDocumentHandler->endElement("xd:CertDigest");
- xDocumentHandler->startElement("xd:IssuerSerial", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- xDocumentHandler->startElement("X509IssuerName", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- xDocumentHandler->characters(signatureInfo.ouX509IssuerName);
- xDocumentHandler->endElement("X509IssuerName");
- xDocumentHandler->startElement("X509SerialNumber", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- xDocumentHandler->characters(signatureInfo.ouX509SerialNumber);
- xDocumentHandler->endElement("X509SerialNumber");
- xDocumentHandler->endElement("xd:IssuerSerial");
- xDocumentHandler->endElement("xd:Cert");
+ assert(signatureInfo.GetSigningCertificate() || !signatureInfo.ouGpgKeyID.isEmpty());
+ if (signatureInfo.GetSigningCertificate())
+ {
+ // how should this deal with multiple X509Data elements?
+ // for now, let's write all of the certificates ...
+ for (auto const& rData : signatureInfo.X509Datas)
+ {
+ for (auto const& it : rData)
+ {
+ WriteXadesCert(xDocumentHandler, it);
+ }
+ }
+ }
+ else
+ {
+ // for PGP, write empty mandatory X509IssuerName, X509SerialNumber
+ SignatureInformation::X509CertInfo temp;
+ temp.CertDigest = signatureInfo.ouGpgKeyID;
+ WriteXadesCert(xDocumentHandler, temp);
+ }
xDocumentHandler->endElement("xd:SigningCertificate");
xDocumentHandler->startElement("xd:SignaturePolicyIdentifier", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
xDocumentHandler->startElement("xd:SignaturePolicyImplied", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 5da6459779f7..ce3beef82a89 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -591,6 +591,18 @@ void DocumentSignatureManager::read(bool bUseTempStream, bool bCacheLastSignatur
bCacheLastSignature);
maSignatureHelper.EndMission();
+ // this parses the XML independently from ImplVerifySignatures() - check
+ // certificates here too ...
+ for (auto const& it : maSignatureHelper.GetSignatureInformations())
+ {
+ if (!it.X509Datas.empty())
+ {
+ uno::Reference<xml::crypto::XSecurityEnvironment> const xSecEnv(
+ getSecurityEnvironment());
+ maSignatureHelper.CheckAndUpdateSignatureInformation(xSecEnv, it);
+ }
+ }
+
maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
}
else
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 42a4df0a7792..141ae49176ed 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -193,12 +193,23 @@ void OOXMLSecExporter::Impl::writeSignatureValue()
void OOXMLSecExporter::Impl::writeKeyInfo()
{
- m_xDocumentHandler->startElement("KeyInfo", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- m_xDocumentHandler->startElement("X509Data", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- m_xDocumentHandler->startElement("X509Certificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- m_xDocumentHandler->characters(m_rInformation.ouX509Certificate);
- m_xDocumentHandler->endElement("X509Certificate");
- m_xDocumentHandler->endElement("X509Data");
+ m_xDocumentHandler->startElement(
+ "KeyInfo", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ assert(m_rInformation.GetSigningCertificate());
+ for (auto const& rData : m_rInformation.X509Datas)
+ {
+ m_xDocumentHandler->startElement(
+ "X509Data", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ for (auto const& it : rData)
+ {
+ m_xDocumentHandler->startElement(
+ "X509Certificate",
+ uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+ m_xDocumentHandler->characters(it.X509Certificate);
+ m_xDocumentHandler->endElement("X509Certificate");
+ }
+ m_xDocumentHandler->endElement("X509Data");
+ }
m_xDocumentHandler->endElement("KeyInfo");
}
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx
index 457ef66bf24b..50fe150419a2 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx
@@ -12,30 +12,1240 @@
#include <xmlsignaturehelper.hxx>
#include <sal/log.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmlimp.hxx>
+
+#include <com/sun/star/xml/sax/SAXException.hpp>
+
+#include <sal/log.hxx>
+
using namespace com::sun::star;
+class OOXMLSecParser::Context
+{
+ protected:
+ friend class OOXMLSecParser;
+ OOXMLSecParser & m_rParser;
+ private:
+ std::unique_ptr<SvXMLNamespaceMap> m_pOldNamespaceMap;
+
+ public:
+ Context(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : m_rParser(rParser)
+ , m_pOldNamespaceMap(std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual ~Context() = default;
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/)
+ {
+ }
+
+ virtual void EndElement()
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/);
+
+ virtual void Characters(OUString const& /*rChars*/)
+ {
+ }
+};
+
+// it's possible that an unsupported element has an Id attribute and a
+// ds:Reference digesting it - probably this means XSecController needs to know
+// about it. (For known elements, the Id attribute is only processed according
+// to the schema.)
+class OOXMLSecParser::UnknownContext
+ : public OOXMLSecParser::Context
+{
+ public:
+ UnknownContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+};
+
+auto OOXMLSecParser::Context::CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/)
+-> std::unique_ptr<Context>
+{
+ // default: create new base context
+ return std::make_unique<UnknownContext>(m_rParser, std::move(pOldNamespaceMap));
+}
+
+/**
+note: anything in ds:Object should be trusted *only* if there is a ds:Reference
+ to it so it is signed (exception: the xades:EncapsulatedX509Certificate).
+ ds:SignedInfo precedes all ds:Object.
+
+ There may be multiple ds:Signature for purpose of counter-signatures
+ but the way XAdES describes these, only the ds:SignatureValue element
+ would be referenced, so requiring a ds:Reference for anything in
+ ds:Object shouldn't cause issues.
+ */
+class OOXMLSecParser::ReferencedContextImpl
+ : public OOXMLSecParser::Context
+{
+ protected:
+ bool m_isReferenced;
+
+ public:
+ ReferencedContextImpl(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_isReferenced(isReferenced)
+ {
+ }
+
+ OUString CheckIdAttrReferenced(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
+ {
+ OUString const id(m_rParser.HandleIdAttr(xAttrs));
+ if (!id.isEmpty() && m_rParser.m_pXSecController->haveReferenceForId(id))
+ {
+ m_isReferenced = true;
+ }
+ return id;
+ }
+};
+
+class OOXMLSecParser::DsX509CertificateContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsX509CertificateContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::DsX509SerialNumberContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsX509SerialNumberContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::DsX509IssuerNameContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsX509IssuerNameContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::DsX509IssuerSerialContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rX509IssuerName;
+ OUString & m_rX509SerialNumber;
+
+ public:
+ DsX509IssuerSerialContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rIssuerName, OUString & rSerialNumber)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rX509IssuerName(rIssuerName)
+ , m_rX509SerialNumber(rSerialNumber)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerName")
+ {
+ return std::make_unique<DsX509IssuerNameContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509IssuerName);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber")
+ {
+ return std::make_unique<DsX509SerialNumberContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509SerialNumber);
+ }
+ // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+/// can't be sure what is supposed to happen here because the spec is clear as mud
+class OOXMLSecParser::DsX509DataContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ // sigh... "No ordering is implied by the above constraints."
+ // so store the ball of mud in vectors and try to figure it out later.
+ std::vector<std::pair<OUString, OUString>> m_X509IssuerSerials;
+ std::vector<OUString> m_X509Certificates;
+
+ public:
+ DsX509DataContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setX509Data(m_X509IssuerSerials, m_X509Certificates);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerSerial")
+ {
+ m_X509IssuerSerials.emplace_back();
+ return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerSerials.back().first, m_X509IssuerSerials.back().second);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509Certificate")
+ {
+ m_X509Certificates.emplace_back();
+ return std::make_unique<DsX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_X509Certificates.back());
+ }
+ // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsKeyInfoContext
+ : public OOXMLSecParser::Context
+{
+ public:
+ DsKeyInfoContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509Data")
+ {
+ return std::make_unique<DsX509DataContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing: ds:PGPData
+ // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, ds:SPKIData, ds:MgmtData
+ // (old code would read ds:Transform inside ds:RetrievalMethod but
+ // presumably that was a bug)
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+
+};
+
+class OOXMLSecParser::DsSignatureValueContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString m_Value;
+
+ public:
+ DsSignatureValueContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setSignatureValue(m_Value);
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class OOXMLSecParser::DsDigestValueContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsDigestValueContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override
+ {
+ m_rValue.clear();
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::DsDigestMethodContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ sal_Int32 & m_rReferenceDigestID;
+
+ public:
+ DsDigestMethodContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_Int32 & rReferenceDigestID)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rReferenceDigestID(rReferenceDigestID)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+
+ SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
+ if (!ouAlgorithm.isEmpty())
+ {
+ SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1
+ && ouAlgorithm != ALGO_XMLDSIGSHA256
+ && ouAlgorithm != ALGO_XMLDSIGSHA512,
+ "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512");
+ if (ouAlgorithm == ALGO_XMLDSIGSHA1)
+ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA1;
+ else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
+ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA256;
+ else if (ouAlgorithm == ALGO_XMLDSIGSHA512)
+ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA512;
+ else
+ m_rReferenceDigestID = 0;
+ }
+ }
+};
+
+class OOXMLSecParser::DsTransformContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ bool & m_rIsC14N;
+
+ public:
+ DsTransformContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool & rIsC14N)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rIsC14N(rIsC14N)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString aAlgorithm = xAttrs->getValueByName("Algorithm");
+
+ if (aAlgorithm == ALGO_RELATIONSHIP)
+ {
+ m_rIsC14N = true;
+ }
+ }
+};
+
+class OOXMLSecParser::DsTransformsContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ bool & m_rIsC14N;
+
+ public:
+ DsTransformsContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool & rIsC14N)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rIsC14N(rIsC14N)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Transform")
+ {
+ return std::make_unique<DsTransformContext>(m_rParser, std::move(pOldNamespaceMap), m_rIsC14N);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsReferenceContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString m_URI;
+ OUString m_Type;
+ OUString m_DigestValue;
+ bool m_IsC14N = false;
+ // Relevant for ODF. The digest algorithm selected by the DigestMethod
+ // element's Algorithm attribute. @see css::xml::crypto::DigestID.
+ sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256;
+
+ public:
+ DsReferenceContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+
+ m_URI = xAttrs->getValueByName("URI");
+ SAL_WARN_IF(m_URI.isEmpty(), "xmlsecurity.helper", "URI is empty");
+ // Remember the type of this reference.
+ m_Type = xAttrs->getValueByName("Type");
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_URI.startsWith("#"))
+ {
+ /*
+ * remove the first character '#' from the attribute value
+ */
+ m_rParser.m_pXSecController->addReference(m_URI.copy(1), m_nReferenceDigestID, m_Type);
+ }
+ else
+ {
+ if (m_IsC14N) // this is determined by nested ds:Transform
+ {
+ m_rParser.m_pXSecController->addStreamReference(m_URI, false, m_nReferenceDigestID);
+ }
+ else
+ /*
+ * it must be an octet stream
+ */
+ {
+ m_rParser.m_pXSecController->addStreamReference(m_URI, true, m_nReferenceDigestID);
+ }
+ }
+
+ m_rParser.m_pXSecController->setDigestValue(m_nReferenceDigestID, m_DigestValue);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Transforms")
+ {
+ return std::make_unique<DsTransformsContext>(m_rParser, std::move(pOldNamespaceMap), m_IsC14N);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+ {
+ return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_nReferenceDigestID);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+ {
+ return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_DigestValue);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsSignatureMethodContext
+ : public OOXMLSecParser::Context
+{
+ public:
+ DsSignatureMethodContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+ if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
+ || ouAlgorithm == ALGO_ECDSASHA512)
+ {
+ m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
+ }
+ }
+};
+
+class OOXMLSecParser::DsSignedInfoContext
+ : public OOXMLSecParser::Context
+{
+ public:
+ DsSignedInfoContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setReferenceCount();
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureMethod")
+ {
+ return std::make_unique<DsSignatureMethodContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
+ {
+ return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing: ds:CanonicalizationMethod
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::XadesCertDigestContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rDigestValue;
+ sal_Int32 & m_rReferenceDigestID;
+
+ public:
+ XadesCertDigestContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rDigestValue, sal_Int32 & rReferenceDigestID)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rDigestValue(rDigestValue)
+ , m_rReferenceDigestID(rReferenceDigestID)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+ {
+ return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_rReferenceDigestID);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+ {
+ return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rDigestValue);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::XadesCertContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ private:
+ sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
+ OUString m_CertDigest;
+ OUString m_X509IssuerName;
+ OUString m_X509SerialNumber;
+
+ public:
+ XadesCertContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setX509CertDigest(m_CertDigest, m_nReferenceDigestID, m_X509IssuerName, m_X509SerialNumber);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned xades:Cert");
+ }
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertDigest")
+ {
+ return std::make_unique<XadesCertDigestContext>(m_rParser, std::move(pOldNamespaceMap), m_CertDigest, m_nReferenceDigestID);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "IssuerSerial")
+ {
+ return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerName, m_X509SerialNumber);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::XadesSigningCertificateContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ public:
+ XadesSigningCertificateContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "Cert")
+ {
+ return std::make_unique<XadesCertContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::XadesSigningTimeContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ private:
+ OUString m_Value;
+
+ public:
+ XadesSigningTimeContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setDate("", m_Value);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SigningTime");
+ }
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class OOXMLSecParser::XadesSignedSignaturePropertiesContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ public:
+ XadesSignedSignaturePropertiesContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningTime")
+ {
+ return std::make_unique<XadesSigningTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningCertificate")
+ {
+ return std::make_unique<XadesSigningCertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ // missing: xades:SignaturePolicyIdentifier, xades:SignatureProductionPlace, xades:SignerRole
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::XadesSignedPropertiesContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ public:
+ XadesSignedPropertiesContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedSignatureProperties")
+ {
+ return std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ // missing: xades:SignedDataObjectProperties
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::XadesQualifyingPropertiesContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ public:
+ XadesQualifyingPropertiesContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedProperties")
+ {
+ return std::make_unique<XadesSignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ // missing: xades:UnsignedSignatureProperties
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::MsodigsigSetupIDContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ MsodigsigSetupIDContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::MsodigsigSignatureCommentsContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ MsodigsigSignatureCommentsContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::MsodigsigSignatureInfoV1Context
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ private:
+ OUString m_SetupID;
+ OUString m_SignatureComments;
+
+ public:
+ MsodigsigSignatureInfoV1Context(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SetupID")
+ {
+ return std::make_unique<MsodigsigSetupIDContext>(m_rParser, std::move(pOldNamespaceMap), m_SetupID);
+ }
+ if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SignatureComments")
+ {
+ return std::make_unique<MsodigsigSignatureCommentsContext>(m_rParser, std::move(pOldNamespaceMap), m_SignatureComments);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_isReferenced)
+ {
+ if (!m_SetupID.isEmpty())
+ {
+ m_rParser.m_pXSecController->setSignatureLineId(m_SetupID);
+ }
+ if (!m_SignatureComments.isEmpty())
+ {
+ m_rParser.m_pXSecController->setDescription("", m_SignatureComments);
+
+ }
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureInfoV1");
+ }
+ }
+};
+
+class OOXMLSecParser::MdssiValueContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ MdssiValueContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class OOXMLSecParser::MdssiSignatureTimeContext
+ : public OOXMLSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ MdssiSignatureTimeContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_MDSSI && rName == "Value")
+ {
+ return std::make_unique<MdssiValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rValue);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+
+class OOXMLSecParser::DsSignaturePropertyContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ private:
+ enum class SignatureProperty { Unknown, Date, Info };
+ SignatureProperty m_Property = SignatureProperty::Unknown;
+ OUString m_Id;
+ OUString m_Value;
+
+ public:
+ DsSignaturePropertyContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_Id = CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_isReferenced)
+ {
+ switch (m_Property)
+ {
+ case SignatureProperty::Unknown:
+ SAL_INFO("xmlsecurity.helper", "Unknown property in ds:Object ignored");
+ break;
+ case SignatureProperty::Info:
+ break; // handled by child context
+ case SignatureProperty::Date:
+ m_rParser.m_pXSecController->setDate(m_Id, m_Value);
+ break;
+ }
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureProperty");
+ }
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_MDSSI && rName == "SignatureTime")
+ {
+ m_Property = SignatureProperty::Date;
+ return std::make_unique<MdssiSignatureTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_Value);
+ }
+ if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SignatureInfoV1")
+ {
+ return std::make_unique<MsodigsigSignatureInfoV1Context>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsSignaturePropertiesContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ public:
+ DsSignaturePropertiesContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperty")
+ {
+ return std::make_unique<DsSignaturePropertyContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsManifestContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ public:
+ DsManifestContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+#if 0
+ ???
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setReferenceCount();
+ }
+#endif
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
+ {
+ return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing: ds:CanonicalizationMethod
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsObjectContext
+ : public OOXMLSecParser::ReferencedContextImpl
+{
+ enum class Mode { Default, ValidSignatureLineImage, InvalidSignatureLineImage };
+ Mode m_Mode = Mode::Default;
+ OUString m_Value;
+
+ public:
+ DsObjectContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ // init with "false" here - the Signature element can't be referenced by its child
+ : OOXMLSecParser::ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), false)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString const id(CheckIdAttrReferenced(xAttrs));
+ if (id == "idValidSigLnImg")
+ {
+ m_Mode = Mode::ValidSignatureLineImage;
+ }
+ else if (id == "idInvalidSigLnImg")
+ {
+ m_Mode = Mode::InvalidSignatureLineImage;
+ }
+ }
+
+ virtual void EndElement() override
+ {
+ switch (m_Mode)
+ {
+ case Mode::ValidSignatureLineImage:
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setValidSignatureImage(m_Value);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineValidImage");
+ }
+ break;
+ case Mode::InvalidSignatureLineImage:
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setInvalidSignatureImage(m_Value);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineInvalidImage");
+ }
+ break;
+ case Mode::Default:
+ break;
+ }
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperties")
+ {
+ return std::make_unique<DsSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "QualifyingProperties")
+ {
+ return std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Manifest")
+ {
+ return std::make_unique<DsManifestContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class OOXMLSecParser::DsSignatureContext
+ : public OOXMLSecParser::Context
+{
+ public:
+ DsSignatureContext(OOXMLSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs));
+ m_rParser.m_rXMLSignatureHelper.StartVerifySignatureElement();
+ m_rParser.m_pXSecController->addSignature();
+ if (!ouIdAttr.isEmpty())
+ {
+ m_rParser.m_pXSecController->setId( ouIdAttr );
+ }
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignedInfo")
+ {
+ return std::make_unique<DsSignedInfoContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureValue")
+ {
+ return std::make_unique<DsSignatureValueContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "KeyInfo")
+ {
+ return std::make_unique<DsKeyInfoContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Object")
+ {
+ return std::make_unique<DsObjectContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+
OOXMLSecParser::OOXMLSecParser(XMLSignatureHelper& rXMLSignatureHelper, XSecController* pXSecController)
- : m_pXSecController(pXSecController)
- ,m_bInDigestValue(false)
- ,m_bInSignatureValue(false)
- ,m_bInX509Certificate(false)
- ,m_bInMdssiValue(false)
- ,m_bInSignatureComments(false)
- ,m_bInX509IssuerName(false)
- ,m_bInX509SerialNumber(false)
- ,m_bInCertDigest(false)
- ,m_bInValidSignatureImage(false)
- ,m_bInInvalidSignatureImage(false)
- ,m_bInSignatureLineId(false)
- ,m_bReferenceUnresolved(false)
+ : m_pNamespaceMap(new SvXMLNamespaceMap)
+ , m_pXSecController(pXSecController)
,m_rXMLSignatureHelper(rXMLSignatureHelper)
{
+ using namespace xmloff::token;
+ m_pNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
+ m_pNamespaceMap->Add( "_ds", GetXMLToken(XML_N_DS), XML_NAMESPACE_DS );
+ m_pNamespaceMap->Add( "_xades132", GetXMLToken(XML_N_XADES132), XML_NAMESPACE_XADES132);
+ m_pNamespaceMap->Add( "_xades141", GetXMLToken(XML_N_XADES141), XML_NAMESPACE_XADES141);
+ m_pNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
+ m_pNamespaceMap->Add( "_mdssi", NS_MDSSI, XML_NAMESPACE_MDSSI );
+ m_pNamespaceMap->Add( "_msodigsig", "http://schemas.microsoft.com/office/2006/digsig", XML_NAMESPACE_MSODIGSIG );
+ m_pNamespaceMap->Add( "_office_libo",
+ GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
}
OOXMLSecParser::~OOXMLSecParser()
{
}
+OUString OOXMLSecParser::HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
+{
+ OUString const aId = xAttrs->getValueByName("Id");
+ if (!aId.isEmpty())
+ {
+ m_pXSecController->collectToVerify(aId);
+ }
+ return aId;
+}
+
void SAL_CALL OOXMLSecParser::startDocument()
{
if (m_xNextHandler.is())
@@ -50,217 +1260,69 @@ void SAL_CALL OOXMLSecParser::endDocument()
void SAL_CALL OOXMLSecParser::startElement(const OUString& rName, const uno::Reference<xml::sax::XAttributeList>& xAttribs)
{
- OUString aId = xAttribs->getValueByName("Id");
- if (!aId.isEmpty())
- m_pXSecController->collectToVerify(aId);
+ assert(m_pNamespaceMap);
+ std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
+ SvXMLImport::processNSAttributes(m_pNamespaceMap, nullptr, xAttribs));
- if (rName == "Signature")
- {
- m_rXMLSignatureHelper.StartVerifySignatureElement();
- m_pXSecController->addSignature();
- if (!aId.isEmpty())
- m_pXSecController->setId(aId);
- }
- else if (rName == "SignatureMethod")
- {
- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
- if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
- || ouAlgorithm == ALGO_ECDSASHA512)
- m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
- }
- else if (rName == "Reference")
- {
- OUString aURI = xAttribs->getValueByName("URI");
- if (aURI.startsWith("#"))
- m_pXSecController->addReference(aURI.copy(1), xml::crypto::DigestID::SHA1, OUString());
- else
- {
- m_aReferenceURI = aURI;
- m_bReferenceUnresolved = true;
- }
- }
- else if (rName == "Transform")
- {
- if (m_bReferenceUnresolved)
- {
- OUString aAlgorithm = xAttribs->getValueByName("Algorithm");
- if (aAlgorithm == ALGO_RELATIONSHIP)
- {
- m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/false, /*nDigestID=*/xml::crypto::DigestID::SHA256);
- m_bReferenceUnresolved = false;
- }
- }
- }
- else if (rName == "DigestValue" && !m_bInCertDigest)
- {
- m_aDigestValue.clear();
- m_bInDigestValue = true;
- }
- else if (rName == "SignatureValue")
- {
- m_aSignatureValue.clear();
- m_bInSignatureValue = true;
- }
- else if (rName == "X509Certificate")
- {
- m_aX509Certificate.clear();
- m_bInX509Certificate = true;
- }
- else if (rName == "mdssi:Value")
- {
- m_aMdssiValue.clear();
- m_bInMdssiValue = true;
- }
- else if (rName == "SignatureComments")
- {
- m_aSignatureComments.clear();
- m_bInSignatureComments = true;
- }
- else if (rName == "X509IssuerName")
- {
- m_aX509IssuerName.clear();
- m_bInX509IssuerName = true;
- }
- else if (rName == "X509SerialNumber")
- {
- m_aX509SerialNumber.clear();
- m_bInX509SerialNumber = true;
- }
- else if (rName == "xd:CertDigest")
- {
- m_aCertDigest.clear();
- m_bInCertDigest = true;
- }
- else if (rName == "Object")
+ OUString localName;
+ sal_uInt16 const nPrefix(m_pNamespaceMap->GetKeyByAttrName(rName, &localName));
+
+ std::unique_ptr<Context> pContext;
+
+ if (m_ContextStack.empty())
{
- OUString sId = xAttribs->getValueByName("Id");
- if (sId == "idValidSigLnImg")
- {
- m_aValidSignatureImage.clear();
- m_bInValidSignatureImage = true;
- }
- else if (sId == "idInvalidSigLnImg")
+ if (nPrefix == XML_NAMESPACE_DS
+ && localName == "Signature")
{
- m_aInvalidSignatureImage.clear();
- m_bInInvalidSignatureImage = true;
+ pContext.reset(new DsSignatureContext(*this, std::move(pRewindMap)));
}
else
{
- SAL_INFO("xmlsecurity.ooxml", "Unknown 'Object' child element: " << rName);
+ throw css::xml::sax::SAXException(
+ "xmlsecurity: unexpected root element", nullptr,
+ css::uno::Any());
}
}
- else if (rName == "SetupID")
- {
- m_aSignatureLineId.clear();
- m_bInSignatureLineId = true;
- }
else
{
- SAL_INFO("xmlsecurity.ooxml", "Unknown xml element: " << rName);
+ pContext = m_ContextStack.top()->CreateChildContext(
+ std::move(pRewindMap), nPrefix, localName);
}
+ m_ContextStack.push(std::move(pContext));
+ assert(!pRewindMap);
+
+ m_ContextStack.top()->StartElement(xAttribs);
+
if (m_xNextHandler.is())
+ {
m_xNextHandler->startElement(rName, xAttribs);
+ }
+
}
void SAL_CALL OOXMLSecParser::endElement(const OUString& rName)
{
- if (rName == "SignedInfo")
- m_pXSecController->setReferenceCount();
- else if (rName == "Reference")
- {
- if (m_bReferenceUnresolved)
- {
- // No transform algorithm found, assume binary.
- m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/true, /*nDigestID=*/xml::crypto::DigestID::SHA256);
- m_bReferenceUnresolved = false;
- }
- m_pXSecController->setDigestValue(xml::crypto::DigestID::SHA256, m_aDigestValue);
- }
- else if (rName == "DigestValue" && !m_bInCertDigest)
- m_bInDigestValue = false;
- else if (rName == "SignatureValue")
- {
- m_pXSecController->setSignatureValue(m_aSignatureValue);
- m_bInSignatureValue = false;
- }
- else if (rName == "X509Certificate")
- {
- m_pXSecController->setX509Certificate(m_aX509Certificate);
- m_bInX509Certificate = false;
- }
- else if (rName == "mdssi:Value")
- {
- m_pXSecController->setDate(m_aMdssiValue);
- m_bInMdssiValue = false;
- }
- else if (rName == "SignatureComments")
- {
- m_pXSecController->setDescription(m_aSignatureComments);
- m_bInSignatureComments = false;
- }
- else if (rName == "X509IssuerName")
- {
- m_pXSecController->setX509IssuerName(m_aX509IssuerName);
- m_bInX509IssuerName = false;
- }
- else if (rName == "X509SerialNumber")
- {
- m_pXSecController->setX509SerialNumber(m_aX509SerialNumber);
- m_bInX509SerialNumber = false;
- }
- else if (rName == "xd:CertDigest")
- {
- m_pXSecController->setCertDigest(m_aCertDigest);
- m_bInCertDigest = false;
- }
- else if (rName == "Object")
+ assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+
+ m_ContextStack.top()->EndElement();
+
+ if (m_xNextHandler.is())
{
- if (m_bInValidSignatureImage)
- {
- m_pXSecController->setValidSignatureImage(m_aValidSignatureImage);
- m_bInValidSignatureImage = false;
- }
- else if (m_bInInvalidSignatureImage)
- {
- m_pXSecController->setInvalidSignatureImage(m_aInvalidSignatureImage);
- m_bInInvalidSignatureImage = false;
- }
+ m_xNextHandler->endElement(rName);
}
- else if (rName == "SetupID")
+
+ if (m_ContextStack.top()->m_pOldNamespaceMap)
{
- m_pXSecController->setSignatureLineId(m_aSignatureLineId);
- m_bInSignatureLineId = false;
+ m_pNamespaceMap = std::move(m_ContextStack.top()->m_pOldNamespaceMap);
}
-
- if (m_xNextHandler.is())
- m_xNextHandler->endElement(rName);
+ m_ContextStack.pop();
}
void SAL_CALL OOXMLSecParser::characters(const OUString& rChars)
{
- if (m_bInDigestValue && !m_bInCertDigest)
- m_aDigestValue += rChars;
- else if (m_bInSignatureValue)
- m_aSignatureValue += rChars;
- else if (m_bInX509Certificate)
- m_aX509Certificate += rChars;
- else if (m_bInMdssiValue)
- m_aMdssiValue += rChars;
- else if (m_bInSignatureComments)
- m_aSignatureComments += rChars;
- else if (m_bInX509IssuerName)
- m_aX509IssuerName += rChars;
- else if (m_bInX509SerialNumber)
- m_aX509SerialNumber += rChars;
- else if (m_bInCertDigest)
- m_aCertDigest += rChars;
- else if (m_bInValidSignatureImage)
- m_aValidSignatureImage += rChars;
- else if (m_bInInvalidSignatureImage)
- m_aInvalidSignatureImage += rChars;
- else if (m_bInSignatureLineId)
- m_aSignatureLineId += rChars;
+ assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+ m_ContextStack.top()->Characters(rChars);
if (m_xNextHandler.is())
m_xNextHandler->characters(rChars);
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.hxx b/xmlsecurity/source/helper/ooxmlsecparser.hxx
index b425e4c32a0f..88e87fd1c39c 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.hxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.hxx
@@ -19,6 +19,11 @@
#include <xsecctl.hxx>
+#include <xmloff/nmspmap.hxx>
+
+#include <stack>
+
+
/// Parses an OOXML digital signature.
class OOXMLSecParser: public cppu::WeakImplHelper
<
@@ -26,38 +31,62 @@ class OOXMLSecParser: public cppu::WeakImplHelper
css::lang::XInitialization
>
{
+public:
+ class Context;
+private:
+ class UnknownContext;
+ class ReferencedContextImpl;
+ class DsX509CertificateContext;
+ class DsX509SerialNumberContext;
+ class DsX509IssuerNameContext;
+ class DsX509IssuerSerialContext;
+ class DsX509DataContext;
+ class DsKeyInfoContext;
+ class DsSignatureValueContext;
+ class DsDigestValueContext;
+ class DsDigestMethodContext;
+ class DsTransformContext;
+ class DsTransformsContext;
+ class DsReferenceContext;
+ class DsSignatureMethodContext;
+ class DsSignedInfoContext;
+ class XadesEncapsulatedX509CertificateContext;
+ class XadesCertificateValuesContext;
+ class XadesUnsignedSignaturePropertiesContext;
+ class XadesUnsignedPropertiesContext;
+ class XadesCertDigestContext;
+ class XadesCertContext;
+ class XadesSigningCertificateContext;
+ class XadesSigningTimeContext;
+ class XadesSignedSignaturePropertiesContext;
+ class XadesSignedPropertiesContext;
+ class XadesQualifyingPropertiesContext;
+ class MdssiValueContext;
+ class MdssiSignatureTimeContext;
+ class MsodigsigSetupIDContext;
+ class MsodigsigSignatureCommentsContext;
+ class MsodigsigSignatureInfoV1Context;
+ class DsSignaturePropertyContext;
+ class DsSignaturePropertiesContext;
+ class DsManifestContext;
+ class DsObjectContext;
+ class DsSignatureContext;
+ class DsigSignaturesContext;
+
+ std::stack<std::unique_ptr<Context>> m_ContextStack;
+ std::unique_ptr<SvXMLNamespaceMap> m_pNamespaceMap;
+
XSecController* m_pXSecController;
css::uno::Reference<css::xml::sax::XDocumentHandler> m_xNextHandler;
- bool m_bInDigestValue;
- OUString m_aDigestValue;
- bool m_bInSignatureValue;
- OUString m_aSignatureValue;
- bool m_bInX509Certificate;
- OUString m_aX509Certificate;
- bool m_bInMdssiValue;
- OUString m_aMdssiValue;
- bool m_bInSignatureComments;
- OUString m_aSignatureComments;
- bool m_bInX509IssuerName;
- OUString m_aX509IssuerName;
- bool m_bInX509SerialNumber;
- OUString m_aX509SerialNumber;
- bool m_bInCertDigest;
- OUString m_aCertDigest;
- bool m_bInValidSignatureImage;
- OUString m_aValidSignatureImage;
- bool m_bInInvalidSignatureImage;
- OUString m_aInvalidSignatureImage;
- bool m_bInSignatureLineId;
- OUString m_aSignatureLineId;
-
/// Last seen <Reference URI="...">.
OUString m_aReferenceURI;
/// Already called addStreamReference() for this reference.
bool m_bReferenceUnresolved;
XMLSignatureHelper& m_rXMLSignatureHelper;
+ OUString HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs);
+
public:
explicit OOXMLSecParser(XMLSignatureHelper& rXMLSignatureHelper, XSecController* pXSecController);
virtual ~OOXMLSecParser() override;
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
index 2aea01128869..d00021c9b633 100644
--- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
@@ -86,8 +86,12 @@ PDFSignatureHelper::GetDocumentSignatureInformations(
security::DocumentSignatureInformation& rExternal = aRet[i];
rExternal.SignatureIsValid
= rInternal.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
- if (!rInternal.ouX509Certificate.isEmpty())
- rExternal.Signer = xSecEnv->createCertificateFromAscii(rInternal.ouX509Certificate);
+ if (rInternal.GetSigningCertificate()
+ && !rInternal.GetSigningCertificate()->X509Certificate.isEmpty())
+ {
+ rExternal.Signer = xSecEnv->createCertificateFromAscii(
+ rInternal.GetSigningCertificate()->X509Certificate);
+ }
rExternal.PartialDocumentSignature = rInternal.bPartialDocumentSignature;
// Verify certificate.
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index db80016f84e0..495a230d9277 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -21,6 +21,7 @@
#include <xmlsignaturehelper.hxx>
#include <documentsignaturehelper.hxx>
#include <xsecctl.hxx>
+#include <biginteger.hxx>
#include <xmlsignaturehelper2.hxx>
@@ -49,6 +50,8 @@
#include <tools/diagnose_ex.h>
#include <sal/log.hxx>
+#include <boost/optional.hpp>
+
#define NS_DOCUMENTSIGNATURES "http://openoffice.org/2004/documentsignatures"
#define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
#define OOXML_SIGNATURE_ORIGIN "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
@@ -409,6 +412,7 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorageStream(const css::uno::Ref
catch(const uno::Exception&)
{
DBG_UNHANDLED_EXCEPTION("xmlsecurity.helper");
+ mbError = true;
}
mpXSecController->releaseSignatureReader();
@@ -555,4 +559,162 @@ void XMLSignatureHelper::CreateAndWriteOOXMLSignature(const uno::Reference<embed
xSaxWriter->endDocument();
}
+/** check this constraint from xmldsig-core 4.5.4:
+
+ All certificates appearing in an X509Data element MUST relate to the
+ validation key by either containing it or being part of a certification
+ chain that terminates in a certificate containing the validation key.
+ */
+static auto CheckX509Data(
+ uno::Reference<xml::crypto::XSecurityEnvironment> const& xSecEnv,
+ std::vector<SignatureInformation::X509CertInfo> const& rX509CertInfos,
+ std::vector<uno::Reference<security::XCertificate>> & rCerts,
+ std::vector<SignatureInformation::X509CertInfo> & rSorted) -> bool
+{
+ assert(rCerts.empty());
+ assert(rSorted.empty());
+ if (rX509CertInfos.empty())
+ {
+ SAL_WARN("xmlsecurity.comp", "no X509Data");
+ return false;
+ }
+ std::vector<uno::Reference<security::XCertificate>> certs;
+ for (SignatureInformation::X509CertInfo const& it : rX509CertInfos)
+ {
+ if (!it.X509Certificate.isEmpty())
+ {
+ certs.emplace_back(xSecEnv->createCertificateFromAscii(it.X509Certificate));
+ }
+ else
+ {
+ certs.emplace_back(xSecEnv->getCertificate(
+ it.X509IssuerName,
+ xmlsecurity::numericStringToBigInteger(it.X509SerialNumber)));
+ }
+ if (!certs.back().is())
+ {
+ SAL_WARN("xmlsecurity.comp", "X509Data cannot be parsed");
+ return false;
+ }
+ }
+
+ // first, search one whose issuer isn't in the list, or a self-signed one
+ boost::optional<size_t> start;
+ for (size_t i = 0; i < certs.size(); ++i)
+ {
+ for (size_t j = 0; ; ++j)
+ {
+ if (j == certs.size())
+ {
+ if (start)
+ {
+ SAL_WARN("xmlsecurity.comp", "X509Data do not form a chain: certificate has no issuer but already have start of chain: " << certs[i]->getSubjectName());
+ return false;
+ }
+ start = i; // issuer isn't in the list
+ break;
+ }
+ if (xmlsecurity::EqualDistinguishedNames(certs[i]->getIssuerName(), certs[j]->getSubjectName()))
+ {
+ if (i == j) // self signed
+ {
+ if (start)
+ {
+ SAL_WARN("xmlsecurity.comp", "X509Data do not form a chain: certificate is self-signed but already have start of chain: " << certs[i]->getSubjectName());
+ return false;
+ }
+ start = i;
+ }
+ break;
+ }
+ }
+ }
+ std::vector<size_t> chain;
+ if (!start)
+ {
+ // this can only be a cycle?
+ SAL_WARN("xmlsecurity.comp", "X509Data do not form a chain: cycle detected");
+ return false;
+ }
+ chain.emplace_back(*start);
+
+ // second, check that there is a chain, no tree or cycle...
+ for (size_t i = 0; i < certs.size(); ++i)
+ {
+ assert(chain.size() == i + 1);
+ for (size_t j = 0; j < certs.size(); ++j)
+ {
+ if (chain[i] != j)
+ {
+ if (xmlsecurity::EqualDistinguishedNames(
+ certs[chain[i]]->getSubjectName(), certs[j]->getIssuerName()))
+ {
+ if (chain.size() != i + 1) // already found issuee?
+ {
+ SAL_WARN("xmlsecurity.comp", "X509Data do not form a chain: certificate issued 2 others: " << certs[chain[i]]->getSubjectName());
+ return false;
+ }
+ chain.emplace_back(j);
+ }
+ }
+ }
+ if (i == certs.size() - 1)
+ { // last one: must be a leaf
+ if (chain.size() != i + 1)
+ {
+ SAL_WARN("xmlsecurity.comp", "X509Data do not form a chain: certificate in cycle: " << certs[chain[i]]->getSubjectName());
+ return false;
+ }
+ }
+ else if (chain.size() != i + 2)
+ { // not issuer of another?
+ SAL_WARN("xmlsecurity.comp", "X509Data do not form a chain: certificate issued 0 others: " << certs[chain[i]]->getSubjectName());
+ return false;
+ }
+ }
+
+ // success
+ assert(chain.size() == rX509CertInfos.size());
+ for (auto const& it : chain)
+ {
+ rSorted.emplace_back(rX509CertInfos[it]);
+ rCerts.emplace_back(certs[it]);
+ }
+ return true;
+}
+
+std::vector<uno::Reference<security::XCertificate>>
+XMLSignatureHelper::CheckAndUpdateSignatureInformation(
+ uno::Reference<xml::crypto::XSecurityEnvironment> const& xSecEnv,
+ SignatureInformation const& rInfo)
+{
+ // if the check fails, it's not possible to determine which X509Data
+ // contained the signing certificate - the UI cannot display something
+ // useful in this case, so prevent anything misleading by clearing the
+ // X509Datas.
+
+ std::vector<uno::Reference<security::XCertificate>> certs;
+ std::vector<SignatureInformation::X509Data> datas;
+ // TODO: for now, just merge all X509Datas together for checking...
+ // (this will probably break round-trip of signature with multiple X509Data,
+ // no idea if that is a problem)
+ SignatureInformation::X509Data temp;
+ SignatureInformation::X509Data tempResult;
+ for (auto const& rData : rInfo.X509Datas)
+ {
+ for (auto const& it : rData)
+ {
+ temp.emplace_back(it);
+ }
+ }
+ if (CheckX509Data(xSecEnv, temp, certs, tempResult))
+ {
+ datas.emplace_back(tempResult);
+ }
+
+ // rInfo is a copy, update the original
+ mpXSecController->UpdateSignatureInformation(rInfo.nSecurityId, datas);
+ return certs;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx
index 5fdc45c2c8c0..e87c8cafee56 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -46,10 +46,6 @@
#include "ooxmlsecexporter.hxx"
#include <xmlsignaturehelper2.hxx>
-namespace cssu = com::sun::star::uno;
-namespace cssl = com::sun::star::lang;
-namespace cssxc = com::sun::star::xml::crypto;
-namespace cssxs = com::sun::star::xml::sax;
using namespace com::sun::star;
namespace
@@ -58,11 +54,11 @@ OUString getDigestURI(sal_Int32 nID)
{
switch( nID )
{
- case cssxc::DigestID::SHA1:
+ case css::xml::crypto::DigestID::SHA1:
return OUString(ALGO_XMLDSIGSHA1);
- case cssxc::DigestID::SHA256:
+ case css::xml::crypto::DigestID::SHA256:
return OUString(ALGO_XMLDSIGSHA256);
- case cssxc::DigestID::SHA512:
+ case css::xml::crypto::DigestID::SHA512:
return OUString(ALGO_XMLDSIGSHA512);
default:
return OUString(ALGO_XMLDSIGSHA1);
@@ -76,13 +72,13 @@ OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_I
{
switch (nDigestID)
{
- case cssxc::DigestID::SHA1:
+ case css::xml::crypto::DigestID::SHA1:
aRet = ALGO_ECDSASHA1;
break;
- case cssxc::DigestID::SHA256:
+ case css::xml::crypto::DigestID::SHA256:
aRet = ALGO_ECDSASHA256;
break;
- case cssxc::DigestID::SHA512:
+ case css::xml::crypto::DigestID::SHA512:
aRet = ALGO_ECDSASHA512;
break;
default:
@@ -95,11 +91,11 @@ OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_I
switch (nDigestID)
{
- case cssxc::DigestID::SHA1:
+ case css::xml::crypto::DigestID::SHA1:
return OUString(ALGO_RSASHA1);
- case cssxc::DigestID::SHA256:
+ case css::xml::crypto::DigestID::SHA256:
return OUString(ALGO_RSASHA256);
- case cssxc::DigestID::SHA512:
+ case css::xml::crypto::DigestID::SHA512:
return OUString(ALGO_RSASHA512);
default:
return OUString(ALGO_RSASHA1);
@@ -107,7 +103,7 @@ OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_I
}
}
-XSecController::XSecController( const cssu::Reference<cssu::XComponentContext>& rxCtx )
+XSecController::XSecController( const css::uno::Reference<css::uno::XComponentContext>& rxCtx )
: mxCtx(rxCtx)
, m_nNextSecurityId(1)
, m_bIsPreviousNodeInitializable(false)
@@ -182,15 +178,15 @@ void XSecController::createXSecComponent( )
m_xXMLDocumentWrapper = nullptr;
m_xSAXEventKeeper = nullptr;
- cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
+ css::uno::Reference< css::lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
#if HAVE_FEATURE_GPGME
- uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, cssu::UNO_QUERY );
+ uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, css::uno::UNO_QUERY );
if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
m_xXMLSignature.set(new XMLSignature_GpgImpl());
else // xmlsec or mscrypt
#endif
- m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), cssu::UNO_QUERY);
+ m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), css::uno::UNO_QUERY);
bool bSuccess = m_xXMLSignature.is();
if ( bSuccess )
@@ -210,11 +206,11 @@ void XSecController::createXSecComponent( )
* SAXEventKeeper created successfully.
*/
{
- cssu::Sequence <cssu::Any> arg(1);
+ css::uno::Sequence <css::uno::Any> arg(1);
arg[0] <<= uno::Reference<xml::wrapper::XXMLDocumentWrapper>(m_xXMLDocumentWrapper.get());
m_xSAXEventKeeper->initialize(arg);
- cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >
+ css::uno::Reference< css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener >
xStatusChangeListener = this;
m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
@@ -277,7 +273,7 @@ bool XSecController::chainOn()
*/
m_xSAXEventKeeper->setNextHandler( nullptr );
- cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), cssu::UNO_QUERY);
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), css::uno::UNO_QUERY);
/*
* connects the previous document handler on the SAX chain
@@ -286,17 +282,17 @@ bool XSecController::chainOn()
{
if ( m_bIsPreviousNodeInitializable )
{
- cssu::Reference< cssl::XInitialization > xInitialization
- (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
+ css::uno::Reference< css::lang::XInitialization > xInitialization
+ (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
- cssu::Sequence<cssu::Any> aArgs( 1 );
+ css::uno::Sequence<css::uno::Any> aArgs( 1 );
aArgs[0] <<= xSEKHandler;
xInitialization->initialize(aArgs);
}
else
{
- cssu::Reference< cssxs::XParser > xParser
- (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
+ css::uno::Reference< css::xml::sax::XParser > xParser
+ (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
xParser->setDocumentHandler( xSEKHandler );
}
}
@@ -332,16 +328,16 @@ void XSecController::chainOff()
{
if ( m_bIsPreviousNodeInitializable )
{
- cssu::Reference< cssl::XInitialization > xInitialization
- (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
+ css::uno::Reference< css::lang::XInitialization > xInitialization
+ (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
- cssu::Sequence<cssu::Any> aArgs( 1 );
+ css::uno::Sequence<css::uno::Any> aArgs( 1 );
aArgs[0] <<= uno::Reference<xml::sax::XDocumentHandler>();
xInitialization->initialize(aArgs);
}
else
{
- cssu::Reference< cssxs::XParser > xParser(m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
+ css::uno::Reference< css::xml::sax::XParser > xParser(m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
xParser->setDocumentHandler(uno::Reference<xml::sax::XDocumentHandler>());
}
}
@@ -398,7 +394,7 @@ void XSecController::initializeSAXChain()
chainOff();
}
-cssu::Reference< css::io::XInputStream >
+css::uno::Reference< css::io::XInputStream >
XSecController::getObjectInputStream( const OUString& objectURL )
/****** XSecController/getObjectInputStream ************************************
*
@@ -415,7 +411,7 @@ cssu::Reference< css::io::XInputStream >
* xInputStream - the XInputStream interface
******************************************************************************/
{
- cssu::Reference< css::io::XInputStream > xObjectInputStream;
+ css::uno::Reference< css::io::XInputStream > xObjectInputStream;
SAL_WARN_IF( !m_xUriBinding.is(), "xmlsecurity.helper", "Need XUriBinding!" );
@@ -435,7 +431,7 @@ sal_Int32 XSecController::getNewSecurityId( )
return nId;
}
-void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const cssu::Reference< cssxc::XXMLSecurityContext >& xSecurityContext )
+void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext >& xSecurityContext )
/****** XSecController/startMission *******************************************
*
* NAME
@@ -461,7 +457,7 @@ void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBi
m_bVerifyCurrentSignature = false;
}
-void XSecController::setSAXChainConnector(const cssu::Reference< cssl::XInitialization >& xInitialization)
+void XSecController::setSAXChainConnector(const css::uno::Reference< css::lang::XInitialization >& xInitialization)
/****** XSecController/setSAXChainConnector ***********************************
*
* NAME
@@ -512,8 +508,8 @@ void XSecController::endMission()
* ResolvedListener only exist when the security components are created.
*/
{
- cssu::Reference< cssxc::sax::XMissionTaker > xMissionTaker
- ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, cssu::UNO_QUERY );
+ css::uno::Reference< css::xml::crypto::sax::XMissionTaker > xMissionTaker
+ ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, css::uno::UNO_QUERY );
/*
* asks the SignatureCreator/SignatureVerifier to release
@@ -572,7 +568,7 @@ void writeUnsignedProperties(
}
void XSecController::exportSignature(
- const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
+ const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
const SignatureInformation& signatureInfo,
bool bXAdESCompliantIfODF )
/****** XSecController/exportSignature ****************************************
@@ -606,19 +602,19 @@ void XSecController::exportSignature(
signatureInfo.ouSignatureId);
}
- xDocumentHandler->startElement( "Signature", cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+ xDocumentHandler->startElement( "Signature", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
{
/* Write SignedInfo element */
xDocumentHandler->startElement(
"SignedInfo",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
{
/* Write CanonicalizationMethod element */
pAttributeList = new SvXMLAttributeList();
pAttributeList->AddAttribute(
"Algorithm",
ALGO_C14N);
- xDocumentHandler->startElement( "CanonicalizationMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
+ xDocumentHandler->startElement( "CanonicalizationMethod", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
xDocumentHandler->endElement( "CanonicalizationMethod" );
/* Write SignatureMethod element */
@@ -632,7 +628,7 @@ void XSecController::exportSignature(
pAttributeList->AddAttribute(
"Algorithm",
getSignatureURI(signatureInfo.eAlgorithmID, vReferenceInfors[0].nDigestID));
- xDocumentHandler->startElement( "SignatureMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
+ xDocumentHandler->startElement( "SignatureMethod", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
xDocumentHandler->endElement( "SignatureMethod" );
/* Write Reference element */
@@ -671,7 +667,7 @@ void XSecController::exportSignature(
}
}
- xDocumentHandler->startElement( "Reference", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
+ xDocumentHandler->startElement( "Reference", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
{
/* Write Transforms element */
if (refInfor.nType == SignatureReferenceType::XMLSTREAM)
@@ -681,7 +677,7 @@ void XSecController::exportSignature(
{
xDocumentHandler->startElement(
"Transforms",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
{
pAttributeList = new SvXMLAttributeList();
pAttributeList->AddAttribute(
@@ -689,7 +685,7 @@ void XSecController::exportSignature(
ALGO_C14N);
xDocumentHandler->startElement(
"Transform",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
xDocumentHandler->endElement( "Transform" );
}
xDocumentHandler->endElement( "Transforms" );
@@ -702,13 +698,13 @@ void XSecController::exportSignature(
getDigestURI(refInfor.nDigestID));
xDocumentHandler->startElement(
"DigestMethod",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
xDocumentHandler->endElement( "DigestMethod" );
/* Write DigestValue element */
xDocumentHandler->startElement(
"DigestValue",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
xDocumentHandler->characters( refInfor.ouDigestValue );
xDocumentHandler->endElement( "DigestValue" );
}
@@ -720,14 +716,14 @@ void XSecController::exportSignature(
/* Write SignatureValue element */
xDocumentHandler->startElement(
"SignatureValue",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
xDocumentHandler->characters( signatureInfo.ouSignatureValue );
xDocumentHandler->endElement( "SignatureValue" );
/* Write KeyInfo element */
xDocumentHandler->startElement(
"KeyInfo",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
{
// GPG or X509 key?
if (!signatureInfo.ouGpgCertificate.isEmpty())
@@ -737,13 +733,13 @@ void XSecController::exportSignature(
/* Write PGPData element */
xDocumentHandler->startElement(
"PGPData",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
{
/* Write keyid element */
xDocumentHandler->startElement(
"PGPKeyID",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouCertDigest );
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters(signatureInfo.ouGpgKeyID);
xDocumentHandler->endElement( "PGPKeyID" );
/* Write PGPKeyPacket element */
@@ -751,7 +747,7 @@ void XSecController::exportSignature(
{
xDocumentHandler->startElement(
"PGPKeyPacket",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
xDocumentHandler->endElement( "PGPKeyPacket" );
}
@@ -759,7 +755,7 @@ void XSecController::exportSignature(
/* Write PGPOwner element */
xDocumentHandler->startElement(
"loext:PGPOwner",
- cssu::Reference< cssxs::XAttributeList >(new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList >(new SvXMLAttributeList()));
xDocumentHandler->characters( signatureInfo.ouGpgOwner );
xDocumentHandler->endElement( "loext:PGPOwner" );
}
@@ -767,43 +763,50 @@ void XSecController::exportSignature(
}
else
{
- /* Write X509Data element */
- xDocumentHandler->startElement(
- "X509Data",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ assert(signatureInfo.GetSigningCertificate());
+ for (auto const& rData : signatureInfo.X509Datas)
{
- /* Write X509IssuerSerial element */
+ /* Write X509Data element */
xDocumentHandler->startElement(
- "X509IssuerSerial",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- {
- /* Write X509IssuerName element */
- xDocumentHandler->startElement(
- "X509IssuerName",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouX509IssuerName );
- xDocumentHandler->endElement( "X509IssuerName" );
-
- /* Write X509SerialNumber element */
- xDocumentHandler->startElement(
- "X509SerialNumber",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouX509SerialNumber );
- xDocumentHandler->endElement( "X509SerialNumber" );
- }
- xDocumentHandler->endElement( "X509IssuerSerial" );
-
- /* Write X509Certificate element */
- if (!signatureInfo.ouX509Certificate.isEmpty())
+ "X509Data",
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
{
- xDocumentHandler->startElement(
- "X509Certificate",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouX509Certificate );
- xDocumentHandler->endElement( "X509Certificate" );
+ for (auto const& it : rData)
+ {
+ /* Write X509IssuerSerial element */
+ xDocumentHandler->startElement(
+ "X509IssuerSerial",
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
+ {
+ /* Write X509IssuerName element */
+ xDocumentHandler->startElement(
+ "X509IssuerName",
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters(it.X509IssuerName);
+ xDocumentHandler->endElement( "X509IssuerName" );
+
+ /* Write X509SerialNumber element */
+ xDocumentHandler->startElement(
+ "X509SerialNumber",
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters(it.X509SerialNumber);
+ xDocumentHandler->endElement( "X509SerialNumber" );
+ }
+ xDocumentHandler->endElement( "X509IssuerSerial" );
+
+ /* Write X509Certificate element */
+ if (!it.X509Certificate.isEmpty())
+ {
+ xDocumentHandler->startElement(
+ "X509Certificate",
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters(it.X509Certificate);
+ xDocumentHandler->endElement( "X509Certificate" );
+ }
+ }
}
+ xDocumentHandler->endElement( "X509Data" );
}
- xDocumentHandler->endElement( "X509Data" );
}
}
xDocumentHandler->endElement( "KeyInfo" );
@@ -813,24 +816,24 @@ void XSecController::exportSignature(
/* Write Object element */
xDocumentHandler->startElement(
"Object",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
{
/* Write SignatureProperties element */
xDocumentHandler->startElement(
"SignatureProperties",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
{
/* Write SignatureProperty element */
pAttributeList = new SvXMLAttributeList();
pAttributeList->AddAttribute(
"Id",
- signatureInfo.ouPropertyId);
+ signatureInfo.ouDateTimePropertyId);
pAttributeList->AddAttribute(
"Target",
"#" + signatureInfo.ouSignatureId);
xDocumentHandler->startElement(
"SignatureProperty",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
{
/* Write timestamp element */
@@ -841,7 +844,7 @@ void XSecController::exportSignature(
xDocumentHandler->startElement(
"dc:date",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
OUStringBuffer buffer;
//If the xml signature was already contained in the document,
@@ -899,13 +902,13 @@ void XSecController::exportSignature(
pAttributeList->AddAttribute("xmlns:xd", NS_XD);
xDocumentHandler->startElement(
"Object",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
{
pAttributeList = new SvXMLAttributeList();
pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
xDocumentHandler->startElement(
"xd:QualifyingProperties",
- cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+ css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate, true);
writeUnsignedProperties(xDocumentHandler, signatureInfo);
xDocumentHandler->endElement( "xd:QualifyingProperties" );
@@ -922,6 +925,15 @@ void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>&
aExporter.writeSignature();
}
+void XSecController::UpdateSignatureInformation(sal_Int32 const nSecurityId,
+ std::vector<SignatureInformation::X509Data> const& rDatas)
+{
+ SignatureInformation aInf( 0 );
+ int const nIndex = findSignatureInfor(nSecurityId);
+ assert(nIndex != -1); // nothing should touch this between parsing and verify
+ m_vInternalSignatureInformations[nIndex].signatureInfor.X509Datas = rDatas;
+}
+
SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const
{
SignatureInformation aInf( 0 );
diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx
index 532ba07a0298..1c8bf28ab287 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -20,136 +20,476 @@
#include "xsecparser.hxx"
#include <xmlsignaturehelper.hxx>
+
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmlimp.hxx>
+
#include <com/sun/star/xml/sax/SAXException.hpp>
#include <cppuhelper/exc_hlp.hxx>
#include <sal/log.hxx>
#include <string.h>
-namespace cssu = com::sun::star::uno;
-namespace cssxc = com::sun::star::xml::crypto;
-namespace cssxs = com::sun::star::xml::sax;
-
-XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper,
- XSecController* pXSecController)
- : m_bInX509IssuerName(false)
- , m_bInX509SerialNumber(false)
- , m_bInX509Certificate(false)
- , m_bInGpgCertificate(false)
- , m_bInGpgKeyID(false)
- , m_bInGpgOwner(false)
- , m_bInCertDigest(false)
- , m_bInEncapsulatedX509Certificate(false)
- , m_bInSigningTime(false)
- , m_bInDigestValue(false)
- , m_bInSignatureValue(false)
- , m_bInDate(false)
- , m_bInDescription(false)
- , m_bInSignatureLineId(false)
- , m_bInSignatureLineValidImage(false)
- , m_bInSignatureLineInvalidImage(false)
- , m_pXSecController(pXSecController)
- , m_bReferenceUnresolved(false)
- , m_nReferenceDigestID(cssxc::DigestID::SHA1)
- , m_rXMLSignatureHelper(rXMLSignatureHelper)
+class XSecParser::Context
{
-}
+ protected:
+ friend class XSecParser;
+ XSecParser & m_rParser;
+ private:
+ std::unique_ptr<SvXMLNamespaceMap> m_pOldNamespaceMap;
+
+ public:
+ Context(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : m_rParser(rParser)
+ , m_pOldNamespaceMap(std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual ~Context() = default;
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/)
+ {
+ }
+
+ virtual void EndElement()
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/);
-OUString XSecParser::getIdAttr(const cssu::Reference< cssxs::XAttributeList >& xAttribs )
+ virtual void Characters(OUString const& /*rChars*/)
+ {
+ }
+};
+
+// it's possible that an unsupported element has an Id attribute and a
+// ds:Reference digesting it - probably this means XSecController needs to know
+// about it. (For known elements, the Id attribute is only processed according
+// to the schema.)
+class XSecParser::UnknownContext
+ : public XSecParser::Context
{
- OUString ouIdAttr = xAttribs->getValueByName("id");
+ public:
+ UnknownContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
- if (ouIdAttr.isEmpty())
- {
- ouIdAttr = xAttribs->getValueByName("Id");
- }
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+};
- return ouIdAttr;
+auto XSecParser::Context::CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/)
+-> std::unique_ptr<Context>
+{
+ // default: create new base context
+ return std::make_unique<UnknownContext>(m_rParser, std::move(pOldNamespaceMap));
}
-/*
- * XDocumentHandler
+/**
+note: anything in ds:Object should be trusted *only* if there is a ds:Reference
+ to it so it is signed (exception: the xades:EncapsulatedX509Certificate).
+ ds:SignedInfo precedes all ds:Object.
+
+ There may be multiple ds:Signature for purpose of counter-signatures
+ but the way XAdES describes these, only the ds:SignatureValue element
+ would be referenced, so requiring a ds:Reference for anything in
+ ds:Object shouldn't cause issues.
*/
-void SAL_CALL XSecParser::startDocument( )
+class XSecParser::ReferencedContextImpl
+ : public XSecParser::Context
{
- m_bInX509IssuerName = false;
- m_bInX509SerialNumber = false;
- m_bInX509Certificate = false;
- m_bInGpgCertificate = false;
- m_bInGpgKeyID = false;
- m_bInGpgOwner = false;
- m_bInSignatureValue = false;
- m_bInDigestValue = false;
- m_bInDate = false;
- m_bInDescription = false;
+ protected:
+ bool m_isReferenced;
- if (m_xNextHandler.is())
- {
- m_xNextHandler->startDocument();
- }
-}
+ public:
+ ReferencedContextImpl(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_isReferenced(isReferenced)
+ {
+ }
-void SAL_CALL XSecParser::endDocument( )
+ OUString CheckIdAttrReferenced(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
+ {
+ OUString const id(m_rParser.HandleIdAttr(xAttrs));
+ if (!id.isEmpty() && m_rParser.m_pXSecController->haveReferenceForId(id))
+ {
+ m_isReferenced = true;
+ }
+ return id;
+ }
+};
+
+class XSecParser::LoPGPOwnerContext
+ : public XSecParser::Context
{
- if (m_xNextHandler.is())
- {
- m_xNextHandler->endDocument();
- }
-}
+ private:
+ OUString m_Value;
-void SAL_CALL XSecParser::startElement(
- const OUString& aName,
- const cssu::Reference< cssxs::XAttributeList >& xAttribs )
+ public:
+ LoPGPOwnerContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setGpgOwner(m_Value);
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class XSecParser::DsPGPKeyPacketContext
+ : public XSecParser::Context
{
- try
- {
- OUString ouIdAttr = getIdAttr(xAttribs);
- if (!ouIdAttr.isEmpty())
+ private:
+ OUString m_Value;
+
+ public:
+ DsPGPKeyPacketContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- m_pXSecController->collectToVerify( ouIdAttr );
}
- if ( aName == "Signature" )
+ virtual void EndElement() override
{
- m_rXMLSignatureHelper.StartVerifySignatureElement();
- m_pXSecController->addSignature();
- if (!ouIdAttr.isEmpty())
+ m_rParser.m_pXSecController->setGpgCertificate(m_Value);
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class XSecParser::DsPGPKeyIDContext
+ : public XSecParser::Context
+{
+ private:
+ OUString m_Value;
+
+ public:
+ DsPGPKeyIDContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setGpgKeyID(m_Value);
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class XSecParser::DsPGPDataContext
+ : public XSecParser::Context
+{
+ public:
+ DsPGPDataContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override
+ {
+ m_rParser.m_pXSecController->switchGpgSignature();
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "PGPKeyID")
+ {
+ return std::make_unique<DsPGPKeyIDContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "PGPKeyPacket")
{
- m_pXSecController->setId( ouIdAttr );
+ return std::make_unique<DsPGPKeyPacketContext>(m_rParser, std::move(pOldNamespaceMap));
}
+ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "PGPOwner")
+ {
+ return std::make_unique<LoPGPOwnerContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "SignatureMethod")
+};
+
+class XSecParser::DsX509CertificateContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsX509CertificateContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
{
- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
- if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
- || ouAlgorithm == ALGO_ECDSASHA512)
- m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
}
- else if ( aName == "Reference" )
+
+ virtual void Characters(OUString const& rChars) override
{
- OUString ouUri = xAttribs->getValueByName("URI");
- SAL_WARN_IF( ouUri.isEmpty(), "xmlsecurity.helper", "URI is empty" );
- // Remember the type of this reference.
- OUString ouType = xAttribs->getValueByName("Type");
- if (ouUri.startsWith("#"))
+ m_rValue += rChars;
+ }
+};
+
+class XSecParser::DsX509SerialNumberContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsX509SerialNumberContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class XSecParser::DsX509IssuerNameContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsX509IssuerNameContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class XSecParser::DsX509IssuerSerialContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rX509IssuerName;
+ OUString & m_rX509SerialNumber;
+
+ public:
+ DsX509IssuerSerialContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rIssuerName, OUString & rSerialNumber)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rX509IssuerName(rIssuerName)
+ , m_rX509SerialNumber(rSerialNumber)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerName")
{
- /*
- * remove the first character '#' from the attribute value
- */
- m_pXSecController->addReference( ouUri.copy(1), m_nReferenceDigestID, ouType );
+ return std::make_unique<DsX509IssuerNameContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509IssuerName);
}
- else
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber")
{
- /*
- * remember the uri
- */
- m_currentReferenceURI = ouUri;
- m_bReferenceUnresolved = true;
+ return std::make_unique<DsX509SerialNumberContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509SerialNumber);
+ }
+ // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+/// can't be sure what is supposed to happen here because the spec is clear as mud
+class XSecParser::DsX509DataContext
+ : public XSecParser::Context
+{
+ private:
+ // sigh... "No ordering is implied by the above constraints."
+ // so store the ball of mud in vectors and try to figure it out later.
+ std::vector<std::pair<OUString, OUString>> m_X509IssuerSerials;
+ std::vector<OUString> m_X509Certificates;
+
+ public:
+ DsX509DataContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setX509Data(m_X509IssuerSerials, m_X509Certificates);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerSerial")
+ {
+ m_X509IssuerSerials.emplace_back();
+ return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerSerials.back().first, m_X509IssuerSerials.back().second);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509Certificate")
+ {
+ m_X509Certificates.emplace_back();
+ return std::make_unique<DsX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_X509Certificates.back());
+ }
+ // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::DsKeyInfoContext
+ : public XSecParser::Context
+{
+ public:
+ DsKeyInfoContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "X509Data")
+ {
+ return std::make_unique<DsX509DataContext>(m_rParser, std::move(pOldNamespaceMap));
}
+ if (nNamespace == XML_NAMESPACE_DS && rName == "PGPData")
+ {
+ return std::make_unique<DsPGPDataContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, ds:SPKIData, ds:MgmtData
+ // (old code would read ds:Transform inside ds:RetrievalMethod but
+ // presumably that was a bug)
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+
+};
+
+class XSecParser::DsSignatureValueContext
+ : public XSecParser::Context
+{
+ private:
+ OUString m_Value;
+
+ public:
+ DsSignatureValueContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+ }
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->setSignatureValue(m_Value);
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class XSecParser::DsDigestValueContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DsDigestValueContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override
+ {
+ m_rValue.clear();
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
}
- else if (aName == "DigestMethod")
+};
+
+class XSecParser::DsDigestMethodContext
+ : public XSecParser::Context
+{
+ private:
+ sal_Int32 & m_rReferenceDigestID;
+
+ public:
+ DsDigestMethodContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_Int32 & rReferenceDigestID)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rReferenceDigestID(rReferenceDigestID)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
+ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
if (!ouAlgorithm.isEmpty())
@@ -159,342 +499,1102 @@ void SAL_CALL XSecParser::startElement(
&& ouAlgorithm != ALGO_XMLDSIGSHA512,
"xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512");
if (ouAlgorithm == ALGO_XMLDSIGSHA1)
- m_nReferenceDigestID = cssxc::DigestID::SHA1;
+ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA1;
else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
- m_nReferenceDigestID = cssxc::DigestID::SHA256;
+ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA256;
else if (ouAlgorithm == ALGO_XMLDSIGSHA512)
- m_nReferenceDigestID = cssxc::DigestID::SHA512;
+ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA512;
else
- m_nReferenceDigestID = 0;
+ m_rReferenceDigestID = 0;
}
}
- else if (aName == "Transform")
+};
+
+class XSecParser::DsTransformContext
+ : public XSecParser::Context
+{
+ private:
+ bool & m_rIsC14N;
+
+ public:
+ DsTransformContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool & rIsC14N)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rIsC14N(rIsC14N)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+
+ if (ouAlgorithm == ALGO_C14N)
+ /*
+ * a xml stream
+ */
+ {
+ m_rIsC14N = true;
+ }
+ }
+};
+
+class XSecParser::DsTransformsContext
+ : public XSecParser::Context
+{
+ private:
+ bool & m_rIsC14N;
+
+ public:
+ DsTransformsContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool & rIsC14N)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rIsC14N(rIsC14N)
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- if ( m_bReferenceUnresolved )
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Transform")
{
- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
+ return std::make_unique<DsTransformContext>(m_rParser, std::move(pOldNamespaceMap), m_rIsC14N);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
- if (ouAlgorithm == ALGO_C14N)
- /*
- * a xml stream
- */
+class XSecParser::DsReferenceContext
+ : public XSecParser::Context
+{
+ private:
+ OUString m_URI;
+ OUString m_Type;
+ OUString m_DigestValue;
+ bool m_IsC14N = false;
+ // Relevant for ODF. The digest algorithm selected by the DigestMethod
+ // element's Algorithm attribute. @see css::xml::crypto::DigestID.
+ sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
+
+ public:
+ DsReferenceContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_rParser.HandleIdAttr(xAttrs);
+
+ m_URI = xAttrs->getValueByName("URI");
+ SAL_WARN_IF(m_URI.isEmpty(), "xmlsecurity.helper", "URI is empty");
+ // Remember the type of this reference.
+ m_Type = xAttrs->getValueByName("Type");
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_URI.startsWith("#"))
+ {
+ /*
+ * remove the first character '#' from the attribute value
+ */
+ m_rParser.m_pXSecController->addReference(m_URI.copy(1), m_nReferenceDigestID, m_Type);
+ }
+ else
+ {
+ if (m_IsC14N) // this is determined by nested ds:Transform
{
- m_pXSecController->addStreamReference( m_currentReferenceURI, false, m_nReferenceDigestID );
- m_bReferenceUnresolved = false;
+ m_rParser.m_pXSecController->addStreamReference(m_URI, false, m_nReferenceDigestID);
+ }
+ else
+ /*
+ * it must be an octet stream
+ */
+ {
+ m_rParser.m_pXSecController->addStreamReference(m_URI, true, m_nReferenceDigestID);
}
}
+
+ m_rParser.m_pXSecController->setDigestValue(m_nReferenceDigestID, m_DigestValue);
}
- else if (aName == "X509IssuerName")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_ouX509IssuerName.clear();
- m_bInX509IssuerName = true;
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Transforms")
+ {
+ return std::make_unique<DsTransformsContext>(m_rParser, std::move(pOldNamespaceMap), m_IsC14N);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+ {
+ return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_nReferenceDigestID);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+ {
+ return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_DigestValue);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "X509SerialNumber")
+};
+
+class XSecParser::DsSignatureMethodContext
+ : public XSecParser::Context
+{
+ public:
+ DsSignatureMethodContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- m_ouX509SerialNumber.clear();
- m_bInX509SerialNumber = true;
}
- else if (aName == "X509Certificate")
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- m_ouX509Certificate.clear();
- m_bInX509Certificate = true;
+ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+ if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
+ || ouAlgorithm == ALGO_ECDSASHA512)
+ {
+ m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
+ }
}
- else if (aName == "PGPData")
+};
+
+class XSecParser::DsSignedInfoContext
+ : public XSecParser::Context
+{
+ public:
+ DsSignedInfoContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- m_pXSecController->switchGpgSignature();
}
- else if (aName == "PGPKeyID")
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- m_ouGpgKeyID.clear();
- m_bInGpgKeyID = true;
+ m_rParser.HandleIdAttr(xAttrs);
}
- else if (aName == "PGPKeyPacket")
+
+ virtual void EndElement() override
{
- m_ouGpgCertificate.clear();
- m_bInGpgCertificate = true;
+ m_rParser.m_pXSecController->setReferenceCount();
}
- else if (aName == "loext:PGPOwner")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_ouGpgOwner.clear();
- m_bInGpgOwner = true;
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureMethod")
+ {
+ return std::make_unique<DsSignatureMethodContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
+ {
+ return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing: ds:CanonicalizationMethod
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "SignatureValue")
+};
+
+class XSecParser::XadesEncapsulatedX509CertificateContext
+ : public XSecParser::Context
+{
+ private:
+ OUString m_Value;
+
+ public:
+ XadesEncapsulatedX509CertificateContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- m_ouSignatureValue.clear();
- m_bInSignatureValue = true;
}
- else if (aName == "DigestValue" && !m_bInCertDigest)
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- m_ouDigestValue.clear();
- m_bInDigestValue = true;
+ m_rParser.HandleIdAttr(xAttrs);
}
- else if (aName == "xd:CertDigest")
+
+ virtual void EndElement() override
+ {
+ m_rParser.m_pXSecController->addEncapsulatedX509Certificate(m_Value);
+ }
+
+ virtual void Characters(OUString const& rChars) override
{
- m_ouCertDigest.clear();
- m_bInCertDigest = true;
+ m_Value += rChars;
}
- // FIXME: Existing code here in xmlsecurity uses "xd" as the namespace prefix for XAdES,
- // while the sample document attached to tdf#76142 uses "xades". So accept either here. Of
- // course this is idiotic and wrong, the right thing would be to use a proper way to parse
- // XML that would handle namespaces correctly. I have no idea how substantial re-plumbing of
- // this code that would require.
- else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate")
+};
+
+class XSecParser::XadesCertificateValuesContext
+ : public XSecParser::Context
+{
+ public:
+ XadesCertificateValuesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- m_ouEncapsulatedX509Certificate.clear();
- m_bInEncapsulatedX509Certificate = true;
}
- else if (aName == "xd:SigningTime" || aName == "xades:SigningTime")
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- m_ouDate.clear();
- m_bInSigningTime = true;
+ m_rParser.HandleIdAttr(xAttrs);
}
- else if ( aName == "SignatureProperty" )
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- if (!ouIdAttr.isEmpty())
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "EncapsulatedX509Certificate")
{
- m_pXSecController->setPropertyId( ouIdAttr );
+ return std::make_unique<XadesEncapsulatedX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap));
}
+ // missing: xades:OtherCertificate
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "dc:date")
+};
+
+class XSecParser::XadesUnsignedSignaturePropertiesContext
+ : public XSecParser::Context
+{
+ public:
+ XadesUnsignedSignaturePropertiesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- if (m_ouDate.isEmpty())
- m_bInDate = true;
}
- else if (aName == "dc:description")
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- m_ouDescription.clear();
- m_bInDescription = true;
+ m_rParser.HandleIdAttr(xAttrs);
}
- else if (aName == "loext:SignatureLineId")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_ouSignatureLineId.clear();
- m_bInSignatureLineId = true;
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertificateValues")
+ {
+ return std::make_unique<XadesCertificateValuesContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing:
+ // xades:CounterSignature
+ // ^ old code would read a ds:Signature inside it?
+ // xades:SignatureTimeStamp
+ // xades:CompleteCertificateRefs
+ // xades:CompleteRevocationRefs
+ // xades:AttributeCertificateRefs
+ // xades:AttributeRevocationRefs
+ // xades:SigAndRefsTimeStamp
+ // xades:RefsOnlyTimeStamp
+ // xades:RevocationValues
+ // xades:AttrAuthoritiesCertValues
+ // ^ old code: was equivalent to CertificateValues ???
+ // xades:AttributeRevocationValues
+ // xades:ArchiveTimeStamp
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "loext:SignatureLineValidImage")
+};
+
+class XSecParser::XadesUnsignedPropertiesContext
+ : public XSecParser::Context
+{
+ public:
+ XadesUnsignedPropertiesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
{
- m_ouSignatureLineValidImage.clear();
- m_bInSignatureLineValidImage = true;
}
- else if (aName == "loext:SignatureLineInvalidImage")
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
{
- m_ouSignatureLineInvalidImage.clear();
- m_bInSignatureLineInvalidImage = true;
+ m_rParser.HandleIdAttr(xAttrs);
}
- if (m_xNextHandler.is())
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_xNextHandler->startElement(aName, xAttribs);
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "UnsignedSignatureProperties")
+ {
+ return std::make_unique<XadesUnsignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ // missing: xades:UnsignedDataObjectProperties
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- }
- catch (cssu::Exception& )
- {//getCaughtException MUST be the first line in the catch block
- cssu::Any exc = cppu::getCaughtException();
- throw cssxs::SAXException(
- "xmlsecurity: Exception in XSecParser::startElement",
- nullptr, exc);
- }
- catch (...)
- {
- throw cssxs::SAXException(
- "xmlsecurity: unexpected exception in XSecParser::startElement", nullptr,
- cssu::Any());
- }
-}
+};
-void SAL_CALL XSecParser::endElement( const OUString& aName )
+class XSecParser::LoSignatureLineIdContext
+ : public XSecParser::ReferencedContextImpl
{
- try
- {
- if (aName == "DigestValue" && !m_bInCertDigest)
+ private:
+ OUString m_Value;
+
+ public:
+ LoSignatureLineIdContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_bInDigestValue = false;
}
- else if ( aName == "Reference" )
+
+ virtual void EndElement() override
{
- if ( m_bReferenceUnresolved )
- /*
- * it must be a octet stream
- */
+ if (m_isReferenced)
{
- m_pXSecController->addStreamReference( m_currentReferenceURI, true, m_nReferenceDigestID );
- m_bReferenceUnresolved = false;
+ m_rParser.m_pXSecController->setSignatureLineId(m_Value);
}
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineId");
+ }
+ }
- m_pXSecController->setDigestValue( m_nReferenceDigestID, m_ouDigestValue );
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
}
- else if ( aName == "SignedInfo" )
+};
+
+class XSecParser::LoSignatureLineValidImageContext
+ : public XSecParser::ReferencedContextImpl
+{
+ private:
+ OUString m_Value;
+
+ public:
+ LoSignatureLineValidImageContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_pXSecController->setReferenceCount();
}
- else if ( aName == "SignatureValue" )
+
+ virtual void EndElement() override
{
- m_pXSecController->setSignatureValue( m_ouSignatureValue );
- m_bInSignatureValue = false;
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setValidSignatureImage(m_Value);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineValidImage");
+ }
}
- else if (aName == "X509IssuerName")
+
+ virtual void Characters(OUString const& rChars) override
{
- m_pXSecController->setX509IssuerName( m_ouX509IssuerName );
- m_bInX509IssuerName = false;
+ m_Value += rChars;
}
- else if (aName == "X509SerialNumber")
+};
+
+class XSecParser::LoSignatureLineInvalidImageContext
+ : public XSecParser::ReferencedContextImpl
+{
+ private:
+ OUString m_Value;
+
+ public:
+ LoSignatureLineInvalidImageContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_pXSecController->setX509SerialNumber( m_ouX509SerialNumber );
- m_bInX509SerialNumber = false;
}
- else if (aName == "X509Certificate")
+
+ virtual void EndElement() override
{
- m_pXSecController->setX509Certificate( m_ouX509Certificate );
- m_bInX509Certificate = false;
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setInvalidSignatureImage(m_Value);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineInvalidImage");
+ }
}
- else if (aName == "PGPKeyID")
+
+ virtual void Characters(OUString const& rChars) override
{
- m_pXSecController->setGpgKeyID( m_ouGpgKeyID );
- m_bInGpgKeyID = false;
+ m_Value += rChars;
}
- else if (aName == "PGPKeyPacket")
+};
+
+class XSecParser::LoSignatureLineContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ LoSignatureLineContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_pXSecController->setGpgCertificate( m_ouGpgCertificate );
- m_bInGpgCertificate = false;
}
- else if (aName == "loext:PGPOwner")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_pXSecController->setGpgOwner( m_ouGpgOwner );
- m_bInGpgOwner = false;
+ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLineId")
+ {
+ return std::make_unique<LoSignatureLineIdContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLineValidImage")
+ {
+ return std::make_unique<LoSignatureLineValidImageContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLineInvalidImage")
+ {
+ return std::make_unique<LoSignatureLineInvalidImageContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "xd:CertDigest")
+};
+
+class XSecParser::XadesCertDigestContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rDigestValue;
+ sal_Int32 & m_rReferenceDigestID;
+
+ public:
+ XadesCertDigestContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rDigestValue, sal_Int32 & rReferenceDigestID)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rDigestValue(rDigestValue)
+ , m_rReferenceDigestID(rReferenceDigestID)
{
- m_pXSecController->setCertDigest( m_ouCertDigest );
- m_bInCertDigest = false;
}
- else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_pXSecController->addEncapsulatedX509Certificate( m_ouEncapsulatedX509Certificate );
- m_bInEncapsulatedX509Certificate = false;
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+ {
+ return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_rReferenceDigestID);
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+ {
+ return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rDigestValue);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "xd:SigningTime" || aName == "xades:SigningTime")
+};
+
+class XSecParser::XadesCertContext
+ : public XSecParser::ReferencedContextImpl
+{
+ private:
+ sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
+ OUString m_CertDigest;
+ OUString m_X509IssuerName;
+ OUString m_X509SerialNumber;
+
+ public:
+ XadesCertContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_pXSecController->setDate( m_ouDate );
- m_bInSigningTime = false;
}
- else if (aName == "dc:date")
+
+ virtual void EndElement() override
{
- if (m_bInDate)
+ if (m_isReferenced)
{
- m_pXSecController->setDate( m_ouDate );
- m_bInDate = false;
+ m_rParser.m_pXSecController->setX509CertDigest(m_CertDigest, m_nReferenceDigestID, m_X509IssuerName, m_X509SerialNumber);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned xades:Cert");
}
}
- else if (aName == "dc:description")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_pXSecController->setDescription( m_ouDescription );
- m_bInDescription = false;
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertDigest")
+ {
+ return std::make_unique<XadesCertDigestContext>(m_rParser, std::move(pOldNamespaceMap), m_CertDigest, m_nReferenceDigestID);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "IssuerSerial")
+ {
+ return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerName, m_X509SerialNumber);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "loext:SignatureLineId")
+};
+
+class XSecParser::XadesSigningCertificateContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ XadesSigningCertificateContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_pXSecController->setSignatureLineId( m_ouSignatureLineId );
- m_bInSignatureLineId = false;
}
- else if (aName == "loext:SignatureLineValidImage")
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
{
- m_pXSecController->setValidSignatureImage( m_ouSignatureLineValidImage );
- m_bInSignatureLineValidImage = false;
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "Cert")
+ {
+ return std::make_unique<XadesCertContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
}
- else if (aName == "loext:SignatureLineInvalidImage")
+};
+
+class XSecParser::XadesSigningTimeContext
+ : public XSecParser::ReferencedContextImpl
+{
+ private:
+ OUString m_Value;
+
+ public:
+ XadesSigningTimeContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
{
- m_pXSecController->setInvalidSignatureImage( m_ouSignatureLineInvalidImage );
- m_bInSignatureLineInvalidImage = false;
}
- if (m_xNextHandler.is())
+ virtual void EndElement() override
{
- m_xNextHandler->endElement(aName);
+ if (m_isReferenced)
+ {
+ m_rParser.m_pXSecController->setDate("", m_Value);
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SigningTime");
+ }
}
- }
- catch (cssu::Exception& )
- {//getCaughtException MUST be the first line in the catch block
- cssu::Any exc = cppu::getCaughtException();
- throw cssxs::SAXException(
- "xmlsecurity: Exception in XSecParser::endElement",
- nullptr, exc);
- }
- catch (...)
- {
- throw cssxs::SAXException(
- "xmlsecurity: unexpected exception in XSecParser::endElement", nullptr,
- cssu::Any());
- }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_Value += rChars;
+ }
+};
+
+class XSecParser::XadesSignedSignaturePropertiesContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ XadesSignedSignaturePropertiesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningTime")
+ {
+ return std::make_unique<XadesSigningTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningCertificate")
+ {
+ return std::make_unique<XadesSigningCertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLine")
+ {
+ return std::make_unique<LoSignatureLineContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ // missing: xades:SignaturePolicyIdentifier, xades:SignatureProductionPlace, xades:SignerRole
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::XadesSignedPropertiesContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ XadesSignedPropertiesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedSignatureProperties")
+ {
+ return std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ // missing: xades:SignedDataObjectProperties
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::XadesQualifyingPropertiesContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ XadesQualifyingPropertiesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedProperties")
+ {
+ return std::make_unique<XadesSignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "UnsignedProperties")
+ {
+ return std::make_unique<XadesUnsignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::DcDateContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DcDateContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class XSecParser::DcDescriptionContext
+ : public XSecParser::Context
+{
+ private:
+ OUString & m_rValue;
+
+ public:
+ DcDescriptionContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ OUString & rValue)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ , m_rValue(rValue)
+ {
+ }
+
+ virtual void Characters(OUString const& rChars) override
+ {
+ m_rValue += rChars;
+ }
+};
+
+class XSecParser::DsSignaturePropertyContext
+ : public XSecParser::ReferencedContextImpl
+{
+ private:
+ enum class SignatureProperty { Unknown, Date, Description };
+ SignatureProperty m_Property = SignatureProperty::Unknown;
+ OUString m_Id;
+ OUString m_Value;
+
+ public:
+ DsSignaturePropertyContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ m_Id = CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual void EndElement() override
+ {
+ if (m_isReferenced)
+ {
+ switch (m_Property)
+ {
+ case SignatureProperty::Unknown:
+ SAL_INFO("xmlsecurity.helper", "Unknown property in ds:Object ignored");
+ break;
+ case SignatureProperty::Date:
+ m_rParser.m_pXSecController->setDate(m_Id, m_Value);
+ break;
+ case SignatureProperty::Description:
+ m_rParser.m_pXSecController->setDescription(m_Id, m_Value);
+ break;
+ }
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureProperty");
+ }
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DC && rName == "date")
+ {
+ m_Property = SignatureProperty::Date;
+ return std::make_unique<DcDateContext>(m_rParser, std::move(pOldNamespaceMap), m_Value);
+ }
+ if (nNamespace == XML_NAMESPACE_DC && rName == "description")
+ {
+ m_Property = SignatureProperty::Description;
+ return std::make_unique<DcDescriptionContext>(m_rParser, std::move(pOldNamespaceMap), m_Value);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::DsSignaturePropertiesContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ DsSignaturePropertiesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ bool const isReferenced)
+ : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperty")
+ {
+ return std::make_unique<DsSignaturePropertyContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::DsObjectContext
+ : public XSecParser::ReferencedContextImpl
+{
+ public:
+ DsObjectContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ // init with "false" here - the Signature element can't be referenced by its child
+ : XSecParser::ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), false)
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ CheckIdAttrReferenced(xAttrs);
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperties")
+ {
+ return std::make_unique<DsSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "QualifyingProperties")
+ {
+ return std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+ }
+ // missing: ds:Manifest
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::DsSignatureContext
+ : public XSecParser::Context
+{
+ public:
+ DsSignatureContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual void StartElement(
+ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+ {
+ OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs));
+ m_rParser.m_rXMLSignatureHelper.StartVerifySignatureElement();
+ m_rParser.m_pXSecController->addSignature();
+ if (!ouIdAttr.isEmpty())
+ {
+ m_rParser.m_pXSecController->setId( ouIdAttr );
+ }
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignedInfo")
+ {
+ return std::make_unique<DsSignedInfoContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureValue")
+ {
+ return std::make_unique<DsSignatureValueContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "KeyInfo")
+ {
+ return std::make_unique<DsKeyInfoContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Object")
+ {
+ return std::make_unique<DsObjectContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+class XSecParser::DsigSignaturesContext
+ : public XSecParser::Context
+{
+ public:
+ DsigSignaturesContext(XSecParser & rParser,
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+ : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+ {
+ }
+
+ virtual std::unique_ptr<Context> CreateChildContext(
+ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+ sal_uInt16 const nNamespace, OUString const& rName) override
+ {
+ if (nNamespace == XML_NAMESPACE_DS && rName == "Signature")
+ {
+ return std::make_unique<DsSignatureContext>(m_rParser, std::move(pOldNamespaceMap));
+ }
+ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+ }
+};
+
+
+XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper,
+ XSecController* pXSecController)
+ : m_pNamespaceMap(new SvXMLNamespaceMap)
+ , m_pXSecController(pXSecController)
+ , m_rXMLSignatureHelper(rXMLSignatureHelper)
+{
+ using namespace xmloff::token;
+ m_pNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
+ m_pNamespaceMap->Add( "_dsig_ooo", GetXMLToken(XML_N_DSIG_OOO), XML_NAMESPACE_DSIG_OOO );
+ m_pNamespaceMap->Add( "_dsig", GetXMLToken(XML_N_DSIG), XML_NAMESPACE_DSIG );
+ m_pNamespaceMap->Add( "_ds", GetXMLToken(XML_N_DS), XML_NAMESPACE_DS );
+ m_pNamespaceMap->Add( "_xades132", GetXMLToken(XML_N_XADES132), XML_NAMESPACE_XADES132);
+ m_pNamespaceMap->Add( "_xades141", GetXMLToken(XML_N_XADES141), XML_NAMESPACE_XADES141);
+ m_pNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
+ m_pNamespaceMap->Add( "_office_libo",
+ GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
}
-void SAL_CALL XSecParser::characters( const OUString& aChars )
+OUString XSecParser::HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
{
- if (m_bInX509IssuerName)
- {
- m_ouX509IssuerName += aChars;
- }
- else if (m_bInX509SerialNumber)
- {
- m_ouX509SerialNumber += aChars;
- }
- else if (m_bInX509Certificate)
+ OUString ouIdAttr = getIdAttr(xAttrs);
+ if (!ouIdAttr.isEmpty())
{
- m_ouX509Certificate += aChars;
+ m_pXSecController->collectToVerify( ouIdAttr );
}
- else if (m_bInGpgCertificate)
- {
- m_ouGpgCertificate += aChars;
- }
- else if (m_bInGpgKeyID)
+ return ouIdAttr;
+}
+
+OUString XSecParser::getIdAttr(const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
+{
+ OUString ouIdAttr = xAttribs->getValueByName("id");
+
+ if (ouIdAttr.isEmpty())
{
- m_ouGpgKeyID += aChars;
+ ouIdAttr = xAttribs->getValueByName("Id");
}
- else if (m_bInGpgOwner)
+
+ return ouIdAttr;
+}
+
+/*
+ * XDocumentHandler
+ */
+void SAL_CALL XSecParser::startDocument( )
+{
+ if (m_xNextHandler.is())
{
- m_ouGpgOwner += aChars;
+ m_xNextHandler->startDocument();
}
- else if (m_bInSignatureValue)
+}
+
+void SAL_CALL XSecParser::endDocument( )
+{
+ if (m_xNextHandler.is())
{
- m_ouSignatureValue += aChars;
+ m_xNextHandler->endDocument();
}
- else if (m_bInDigestValue && !m_bInCertDigest)
+}
+
+void SAL_CALL XSecParser::startElement(
+ const OUString& rName,
+ const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
+{
+ assert(m_pNamespaceMap);
+ std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
+ SvXMLImport::processNSAttributes(m_pNamespaceMap, nullptr, xAttribs));
+
+ OUString localName;
+ sal_uInt16 const nPrefix(m_pNamespaceMap->GetKeyByAttrName(rName, &localName));
+
+ std::unique_ptr<Context> pContext;
+
+ if (m_ContextStack.empty())
{
- m_ouDigestValue += aChars;
+ if ((nPrefix == XML_NAMESPACE_DSIG || nPrefix == XML_NAMESPACE_DSIG_OOO)
+ && localName == "document-signatures")
+ {
+ pContext.reset(new DsigSignaturesContext(*this, std::move(pRewindMap)));
+ }
+ else
+ {
+ throw css::xml::sax::SAXException(
+ "xmlsecurity: unexpected root element", nullptr,
+ css::uno::Any());
+ }
}
- else if (m_bInDate)
+ else
{
- m_ouDate += aChars;
+ pContext = m_ContextStack.top()->CreateChildContext(
+ std::move(pRewindMap), nPrefix, localName);
}
- else if (m_bInDescription)
+
+ m_ContextStack.push(std::move(pContext));
+ assert(!pRewindMap);
+
+ try
{
- m_ouDescription += aChars;
+ m_ContextStack.top()->StartElement(xAttribs);
+
+ if (m_xNextHandler.is())
+ {
+ m_xNextHandler->startElement(rName, xAttribs);
+ }
}
- else if (m_bInCertDigest)
- {
- m_ouCertDigest += aChars;
+ catch (css::uno::Exception& )
+ {//getCaughtException MUST be the first line in the catch block
+ css::uno::Any exc = cppu::getCaughtException();
+ throw css::xml::sax::SAXException(
+ "xmlsecurity: Exception in XSecParser::startElement",
+ nullptr, exc);
}
- else if (m_bInEncapsulatedX509Certificate)
+ catch (...)
{
- m_ouEncapsulatedX509Certificate += aChars;
+ throw css::xml::sax::SAXException(
+ "xmlsecurity: unexpected exception in XSecParser::startElement", nullptr,
+ css::uno::Any());
}
- else if (m_bInSigningTime)
+}
+
+void SAL_CALL XSecParser::endElement(const OUString& rName)
+{
+ assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+
+ try
{
- m_ouDate += aChars;
+ m_ContextStack.top()->EndElement();
+
+ if (m_xNextHandler.is())
+ {
+ m_xNextHandler->endElement(rName);
+ }
}
- else if (m_bInSignatureLineId)
- {
- m_ouSignatureLineId += aChars;
+ catch (css::uno::Exception& )
+ {//getCaughtException MUST be the first line in the catch block
+ css::uno::Any exc = cppu::getCaughtException();
+ throw css::xml::sax::SAXException(
+ "xmlsecurity: Exception in XSecParser::endElement",
+ nullptr, exc);
}
- else if (m_bInSignatureLineValidImage)
+ catch (...)
{
- m_ouSignatureLineValidImage += aChars;
+ throw css::xml::sax::SAXException(
+ "xmlsecurity: unexpected exception in XSecParser::endElement", nullptr,
+ css::uno::Any());
}
- else if (m_bInSignatureLineInvalidImage)
+
+ if (m_ContextStack.top()->m_pOldNamespaceMap)
{
- m_ouSignatureLineInvalidImage += aChars;
+ m_pNamespaceMap = std::move(m_ContextStack.top()->m_pOldNamespaceMap);
}
+ m_ContextStack.pop();
+}
+
+void SAL_CALL XSecParser::characters(const OUString& rChars)
+{
+ assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+ m_ContextStack.top()->Characters(rChars);
if (m_xNextHandler.is())
{
- m_xNextHandler->characters(aChars);
+ m_xNextHandler->characters(rChars);
}
}
@@ -514,7 +1614,7 @@ void SAL_CALL XSecParser::processingInstruction( const OUString& aTarget, const
}
}
-void SAL_CALL XSecParser::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
+void SAL_CALL XSecParser::setDocumentLocator( const css::uno::Reference< css::xml::sax::XLocator >& xLocator )
{
if (m_xNextHandler.is())
{
@@ -526,7 +1626,7 @@ void SAL_CALL XSecParser::setDocumentLocator( const cssu::Reference< cssxs::XLoc
* XInitialization
*/
void SAL_CALL XSecParser::initialize(
- const cssu::Sequence< cssu::Any >& aArguments )
+ const css::uno::Sequence< css::uno::Any >& aArguments )
{
aArguments[0] >>= m_xNextHandler;
}
diff --git a/xmlsecurity/source/helper/xsecparser.hxx b/xmlsecurity/source/helper/xsecparser.hxx
index 42b63975ecb9..1b0d3f08eeab 100644
--- a/xmlsecurity/source/helper/xsecparser.hxx
+++ b/xmlsecurity/source/helper/xsecparser.hxx
@@ -29,6 +29,10 @@
#include <cppuhelper/implbase.hxx>
+#include <xmloff/nmspmap.hxx>
+
+#include <stack>
+
class XSecParser: public cppu::WeakImplHelper
<
css::xml::sax::XDocumentHandler,
@@ -49,47 +53,54 @@ class XSecParser: public cppu::WeakImplHelper
******************************************************************************/
{
friend class XSecController;
+public:
+ class Context;
private:
- /*
- * the following members are used to reserve the signature information,
- * including X509IssuerName, X509SerialNumber, and X509Certificate,etc.
- */
- OUString m_ouX509IssuerName;
- OUString m_ouX509SerialNumber;
- OUString m_ouX509Certificate;
- OUString m_ouGpgCertificate;
- OUString m_ouGpgKeyID;
- OUString m_ouGpgOwner;
- OUString m_ouCertDigest;
- OUString m_ouEncapsulatedX509Certificate;
- OUString m_ouDigestValue;
- OUString m_ouSignatureValue;
- OUString m_ouDate;
- /// Characters of a <dc:description> element, as just read from XML.
- OUString m_ouDescription;
- OUString m_ouSignatureLineId;
- OUString m_ouSignatureLineValidImage;
- OUString m_ouSignatureLineInvalidImage;
-
- /*
- * whether inside a particular element
- */
- bool m_bInX509IssuerName;
- bool m_bInX509SerialNumber;
- bool m_bInX509Certificate;
- bool m_bInGpgCertificate;
- bool m_bInGpgKeyID;
- bool m_bInGpgOwner;
- bool m_bInCertDigest;
- bool m_bInEncapsulatedX509Certificate;
- bool m_bInSigningTime;
- bool m_bInDigestValue;
- bool m_bInSignatureValue;
- bool m_bInDate;
- bool m_bInDescription;
- bool m_bInSignatureLineId;
- bool m_bInSignatureLineValidImage;
- bool m_bInSignatureLineInvalidImage;
+ class UnknownContext;
+ class ReferencedContextImpl;
+ class LoPGPOwnerContext;
+ class DsPGPKeyPacketContext;
+ class DsPGPKeyIDContext;
+ class DsPGPDataContext;
+ class DsX509CertificateContext;
+ class DsX509SerialNumberContext;
+ class DsX509IssuerNameContext;
+ class DsX509IssuerSerialContext;
+ class DsX509DataContext;
+ class DsKeyInfoContext;
+ class DsSignatureValueContext;
+ class DsDigestValueContext;
+ class DsDigestMethodContext;
+ class DsTransformContext;
+ class DsTransformsContext;
+ class DsReferenceContext;
+ class DsSignatureMethodContext;
+ class DsSignedInfoContext;
+ class XadesEncapsulatedX509CertificateContext;
+ class XadesCertificateValuesContext;
+ class XadesUnsignedSignaturePropertiesContext;
+ class XadesUnsignedPropertiesContext;
+ class LoSignatureLineIdContext;
+ class LoSignatureLineValidImageContext;
+ class LoSignatureLineInvalidImageContext;
+ class LoSignatureLineContext;
+ class XadesCertDigestContext;
+ class XadesCertContext;
+ class XadesSigningCertificateContext;
+ class XadesSigningTimeContext;
+ class XadesSignedSignaturePropertiesContext;
+ class XadesSignedPropertiesContext;
+ class XadesQualifyingPropertiesContext;
+ class DcDateContext;
+ class DcDescriptionContext;
+ class DsSignaturePropertyContext;
+ class DsSignaturePropertiesContext;
+ class DsObjectContext;
+ class DsSignatureContext;
+ class DsigSignaturesContext;
+
+ std::stack<std::unique_ptr<Context>> m_ContextStack;
+ std::unique_ptr<SvXMLNamespaceMap> m_pNamespaceMap;
/*
* the XSecController collaborating with XSecParser
@@ -102,22 +113,9 @@ private:
css::uno::Reference<
css::xml::sax::XDocumentHandler > m_xNextHandler;
- /*
- * this string is used to remember the current handled reference's URI,
- *
- * because it can be decided whether a stream reference is xml based or binary based
- * only after the Transforms element is read in, so we have to reserve the reference's
- * URI when the startElement event is met.
- */
- OUString m_currentReferenceURI;
- bool m_bReferenceUnresolved;
-
- // Relevant for ODF. The digest algorithm selected by the current DigestMethod element's
- // Algorithm attribute in the current Reference element. From css::xml::crypto::DigestID.
- sal_Int32 m_nReferenceDigestID;
XMLSignatureHelper& m_rXMLSignatureHelper;
-private:
+ OUString HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs);
static OUString getIdAttr(const css::uno::Reference<
css::xml::sax::XAttributeList >& xAttribs );
diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx
index d8089b1773b3..fd6d5c9c8f24 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -38,10 +38,6 @@
using namespace css;
using namespace css::uno;
using namespace css::graphic;
-namespace cssu = com::sun::star::uno;
-namespace cssl = com::sun::star::lang;
-namespace cssxc = com::sun::star::xml::crypto;
-namespace cssxs = com::sun::star::xml::sax;
/* protected: for signature generation */
OUString XSecController::createId()
@@ -59,7 +55,7 @@ OUString XSecController::createId()
return OUString::createFromAscii(str);
}
-cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite(
+css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite(
InternalSignatureInformation& internalSignatureInfor,
sal_Int32 nStorageFormat,
bool bXAdESCompliantIfODF)
@@ -70,13 +66,13 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
sal_Int32 nIdOfSignatureElementCollector;
nIdOfSignatureElementCollector =
- m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY, true );
+ m_xSAXEventKeeper->addSecurityElementCollector( css::xml::crypto::sax::ElementMarkPriority_AFTERMODIFY, true );
m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
rtl::Reference<SignatureCreatorImpl> xSignatureCreator(new SignatureCreatorImpl);
- cssu::Sequence<cssu::Any> args(5);
+ css::uno::Sequence<css::uno::Any> args(5);
args[0] <<= OUString::number(nSecurityId);
args[1] <<= uno::Reference<xml::crypto::sax::XSecuritySAXEventKeeper>(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), uno::UNO_QUERY);
args[2] <<= OUString::number(nIdOfSignatureElementCollector);
@@ -121,7 +117,7 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
{
const SignatureReferenceInformation& refInfor = vReferenceInfors[i];
- cssu::Reference< css::io::XInputStream > xInputStream
+ css::uno::Reference< css::io::XInputStream > xInputStream
= getObjectInputStream( refInfor.ouURI );
if (xInputStream.is())
@@ -132,13 +128,13 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
// use sha512 for gpg signing unconditionally
const sal_Int32 digestID = !internalSignatureInfor.signatureInfor.ouGpgCertificate.isEmpty()?
- cssxc::DigestID::SHA512 : (bXAdESCompliantIfODF ? cssxc::DigestID::SHA256 : cssxc::DigestID::SHA1);
+ css::xml::crypto::DigestID::SHA512 : (bXAdESCompliantIfODF ? css::xml::crypto::DigestID::SHA256 : css::xml::crypto::DigestID::SHA1);
if (nStorageFormat != embed::StorageFormats::OFOPXML)
{
internalSignatureInfor.signatureInfor.ouSignatureId = createId();
- internalSignatureInfor.signatureInfor.ouPropertyId = createId();
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouPropertyId, -1, OUString() );
+ internalSignatureInfor.signatureInfor.ouDateTimePropertyId = createId();
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouDateTimePropertyId, -1, OUString() );
size++;
if (bXAdESCompliantIfODF)
@@ -183,7 +179,7 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
void XSecController::signAStream( sal_Int32 securityId, const OUString& uri, bool isBinary, bool bXAdESCompliantIfODF)
{
const SignatureReferenceType type = isBinary ? SignatureReferenceType::BINARYSTREAM : SignatureReferenceType::XMLSTREAM;
- sal_Int32 digestID = bXAdESCompliantIfODF ? cssxc::DigestID::SHA256 : cssxc::DigestID::SHA1;
+ sal_Int32 digestID = bXAdESCompliantIfODF ? css::xml::crypto::DigestID::SHA256 : css::xml::crypto::DigestID::SHA1;
int index = findSignatureInfor( securityId );
@@ -197,11 +193,12 @@ void XSecController::signAStream( sal_Int32 securityId, const OUString& uri, boo
{
// use sha512 for gpg signing unconditionally
if (!m_vInternalSignatureInformations[index].signatureInfor.ouGpgCertificate.isEmpty())
- digestID = cssxc::DigestID::SHA512;
+ digestID = css::xml::crypto::DigestID::SHA512;
m_vInternalSignatureInformations[index].addReference(type, digestID, uri, -1, OUString());
}
}
+// note: this is called when creating a new signature from scratch
void XSecController::setX509Certificate(
sal_Int32 nSecurityId,
const OUString& ouX509IssuerName,
@@ -215,10 +212,13 @@ void XSecController::setX509Certificate(
if ( index == -1 )
{
InternalSignatureInformation isi(nSecurityId, nullptr);
- isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
- isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
- isi.signatureInfor.ouX509Certificate = ouX509Cert;
- isi.signatureInfor.ouCertDigest = ouX509CertDigest;
+ isi.signatureInfor.X509Datas.clear();
+ isi.signatureInfor.X509Datas.emplace_back();
+ isi.signatureInfor.X509Datas.back().emplace_back();
+ isi.signatureInfor.X509Datas.back().back().X509IssuerName = ouX509IssuerName;
+ isi.signatureInfor.X509Datas.back().back().X509SerialNumber = ouX509SerialNumber;
+ isi.signatureInfor.X509Datas.back().back().X509Certificate = ouX509Cert;
+ isi.signatureInfor.X509Datas.back().back().CertDigest = ouX509CertDigest;
isi.signatureInfor.eAlgorithmID = eAlgorithmID;
m_vInternalSignatureInformations.push_back( isi );
}
@@ -226,16 +226,19 @@ void XSecController::setX509Certificate(
{
SignatureInformation &si
= m_vInternalSignatureInformations[index].signatureInfor;
- si.ouX509IssuerName = ouX509IssuerName;
- si.ouX509SerialNumber = ouX509SerialNumber;
- si.ouX509Certificate = ouX509Cert;
- si.ouCertDigest = ouX509CertDigest;
+ si.X509Datas.clear();
+ si.X509Datas.emplace_back();
+ si.X509Datas.back().emplace_back();
+ si.X509Datas.back().back().X509IssuerName = ouX509IssuerName;
+ si.X509Datas.back().back().X509SerialNumber = ouX509SerialNumber;
+ si.X509Datas.back().back().X509Certificate = ouX509Cert;
+ si.X509Datas.back().back().CertDigest = ouX509CertDigest;
}
}
void XSecController::setGpgCertificate(
sal_Int32 nSecurityId,
- const OUString& ouCertDigest,
+ const OUString& ouKeyDigest,
const OUString& ouCert,
const OUString& ouOwner)
{
@@ -246,16 +249,17 @@ void XSecController::setGpgCertificate(
InternalSignatureInformation isi(nSecurityId, nullptr);
isi.signatureInfor.ouGpgCertificate = ouCert;
isi.signatureInfor.ouGpgOwner = ouOwner;
- isi.signatureInfor.ouCertDigest = ouCertDigest;
+ isi.signatureInfor.ouGpgKeyID = ouKeyDigest;
m_vInternalSignatureInformations.push_back( isi );
}
else
{
SignatureInformation &si
= m_vInternalSignatureInformations[index].signatureInfor;
+ si.X509Datas.clear(); // it is a PGP signature now
si.ouGpgCertificate = ouCert;
si.ouGpgOwner = ouOwner;
- si.ouCertDigest = ouCertDigest;
+ si.ouGpgKeyID = ouKeyDigest;
}
}
@@ -352,7 +356,7 @@ void XSecController::setSignatureLineInvalidGraphic(
}
bool XSecController::WriteSignature(
- const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
+ const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
bool bXAdESCompliantIfODF )
{
bool rc = false;
@@ -378,7 +382,7 @@ bool XSecController::WriteSignature(
/*
* export the signature template
*/
- cssu::Reference<cssxs::XDocumentHandler> xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()),cssu::UNO_QUERY);
+ css::uno::Reference<css::xml::sax::XDocumentHandler> xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()),css::uno::UNO_QUERY);
int i;
int sigNum = m_vInternalSignatureInformations.size();
@@ -399,7 +403,7 @@ bool XSecController::WriteSignature(
rc = true;
}
- catch( cssu::Exception& )
+ catch( css::uno::Exception& )
{
}
@@ -427,7 +431,7 @@ bool XSecController::WriteOOXMLSignature(const uno::Reference<embed::XStorage>&
try
{
// Export the signature template.
- cssu::Reference<xml::sax::XDocumentHandler> xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), uno::UNO_QUERY);
+ css::uno::Reference<xml::sax::XDocumentHandler> xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), uno::UNO_QUERY);
for (InternalSignatureInformation & rInformation : m_vInternalSignatureInformations)
{
diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index 305e5aa28128..eca94d82c768 100644
--- a/xmlsecurity/source/helper/xsecverify.cxx
+++ b/xmlsecurity/source/helper/xsecverify.cxx
@@ -22,6 +22,7 @@
#include <xsecctl.hxx>
#include "xsecparser.hxx"
#include "ooxmlsecparser.hxx"
+#include <biginteger.hxx>
#include <framework/signatureverifierimpl.hxx>
#include <framework/saxeventkeeperimpl.hxx>
#include <gpg/xmlsignature_gpgimpl.hxx>
@@ -47,13 +48,9 @@
using namespace css;
using namespace css::uno;
using namespace css::beans;
-namespace cssu = com::sun::star::uno;
-namespace cssl = com::sun::star::lang;
-namespace cssxc = com::sun::star::xml::crypto;
-namespace cssxs = com::sun::star::xml::sax;
/* protected: for signature verify */
-cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
+css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
sal_Int32 nSecurityId)
{
if ( m_eStatusOfSecurityComponents != InitializationState::INITIALIZED )
@@ -62,10 +59,10 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
}
sal_Int32 nIdOfSignatureElementCollector;
- cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
+ css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > xReferenceResolvedListener;
nIdOfSignatureElementCollector =
- m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, false);
+ m_xSAXEventKeeper->addSecurityElementCollector( css::xml::crypto::sax::ElementMarkPriority_BEFOREMODIFY, false);
m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
@@ -74,9 +71,9 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
*/
xReferenceResolvedListener = new SignatureVerifierImpl;
- cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
+ css::uno::Reference<css::lang::XInitialization> xInitialization(xReferenceResolvedListener, css::uno::UNO_QUERY);
- cssu::Sequence<cssu::Any> args(5);
+ css::uno::Sequence<css::uno::Any> args(5);
args[0] <<= OUString::number(nSecurityId);
args[1] <<= uno::Reference<xml::crypto::sax::XSecuritySAXEventKeeper>(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), uno::UNO_QUERY);
args[2] <<= OUString::number(nIdOfSignatureElementCollector);
@@ -84,8 +81,8 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
args[4] <<= m_xXMLSignature;
xInitialization->initialize(args);
- cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster >
- signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
+ css::uno::Reference< css::xml::crypto::sax::XSignatureVerifyResultBroadcaster >
+ signatureVerifyResultBroadcaster(xReferenceResolvedListener, css::uno::UNO_QUERY);
signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this );
@@ -93,7 +90,7 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
nIdOfSignatureElementCollector,
xReferenceResolvedListener);
- cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
+ css::uno::Reference<css::xml::crypto::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, css::uno::UNO_QUERY);
keyCollector->setKeyId(0);
return xReferenceResolvedListener;
@@ -101,7 +98,7 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
void XSecController::addSignature()
{
- cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
+ css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > xReferenceResolvedListener;
sal_Int32 nSignatureId = 0;
@@ -148,6 +145,25 @@ void XSecController::switchGpgSignature()
#endif
}
+bool XSecController::haveReferenceForId(OUString const& rId) const
+{
+ if (m_vInternalSignatureInformations.empty())
+ {
+ SAL_INFO("xmlsecurity.helper","XSecController::haveReferenceForId: no signature");
+ return false;
+ }
+ InternalSignatureInformation const& rIsi(m_vInternalSignatureInformations.back());
+ for (SignatureReferenceInformation const& rSri : rIsi.signatureInfor.vSignatureReferenceInfors)
+ {
+ if (rSri.nType == SignatureReferenceType::SAMEDOCUMENT
+ && rSri.ouURI == rId) // ouUri has # stripped
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
void XSecController::addReference( const OUString& ouUri, sal_Int32 nDigestID, const OUString& ouType )
{
if (m_vInternalSignatureInformations.empty())
@@ -178,13 +194,13 @@ void XSecController::addStreamReference(
/*
* get the input stream
*/
- cssu::Reference< css::io::XInputStream > xObjectInputStream
+ css::uno::Reference< css::io::XInputStream > xObjectInputStream
= getObjectInputStream( ouUri );
if ( xObjectInputStream.is() )
{
- cssu::Reference<cssxc::XUriBinding> xUriBinding
- (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
+ css::uno::Reference<css::xml::crypto::XUriBinding> xUriBinding
+ (isi.xReferenceResolvedListener, css::uno::UNO_QUERY);
xUriBinding->setUriBinding(ouUri, xObjectInputStream);
}
}
@@ -220,13 +236,15 @@ void XSecController::setReferenceCount() const
}
}
- cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
- (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
+ css::uno::Reference<css::xml::crypto::sax::XReferenceCollector> xReferenceCollector
+ (isi.xReferenceResolvedListener, css::uno::UNO_QUERY);
xReferenceCollector->setReferenceCount( referenceCount );
}
}
-void XSecController::setX509IssuerName( OUString const & ouX509IssuerName )
+void XSecController::setX509Data(
+ std::vector<std::pair<OUString, OUString>> & rX509IssuerSerials,
+ std::vector<OUString> const& rX509Certificates)
{
if (m_vInternalSignatureInformations.empty())
{
@@ -234,29 +252,52 @@ void XSecController::setX509IssuerName( OUString const & ouX509IssuerName )
return;
}
InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
- isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
-}
-
-void XSecController::setX509SerialNumber( OUString const & ouX509SerialNumber )
-{
- if (m_vInternalSignatureInformations.empty())
+ SignatureInformation::X509Data data;
+ // due to the excessive flexibility of the spec it's possible that there
+ // is both a reference to a cert and the cert itself in one X509Data
+ for (OUString const& it : rX509Certificates)
{
- SAL_INFO("xmlsecurity.helper","XSecController::setX509SerialNumber: no signature");
- return;
+ try
+ {
+ data.emplace_back();
+ data.back().X509Certificate = it;
+ uno::Reference<xml::crypto::XSecurityEnvironment> const xSecEnv(m_xSecurityContext->getSecurityEnvironment());
+ uno::Reference<security::XCertificate> const xCert(xSecEnv->createCertificateFromAscii(it));
+ if (!xCert.is())
+ {
+ SAL_INFO("xmlsecurity.helper", "cannot parse X509Certificate");
+ continue; // will be handled in CheckX509Data
+ }
+ OUString const issuerName(xCert->getIssuerName());
+ OUString const serialNumber(xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber()));
+ auto const iter = std::find_if(rX509IssuerSerials.begin(), rX509IssuerSerials.end(),
+ [&](auto const& rX509IssuerSerial) {
+ return xmlsecurity::EqualDistinguishedNames(issuerName, rX509IssuerSerial.first)
+ && serialNumber == rX509IssuerSerial.second;
+ });
+ if (iter != rX509IssuerSerials.end())
+ {
+ data.back().X509IssuerName = iter->first;
+ data.back().X509SerialNumber = iter->second;
+ rX509IssuerSerials.erase(iter);
+ }
+ }
+ catch (uno::Exception const&)
+ {
+ SAL_INFO("xmlsecurity.helper", "cannot parse X509Certificate");
+ }
}
- InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
- isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
-}
-
-void XSecController::setX509Certificate( OUString const & ouX509Certificate )
-{
- if (m_vInternalSignatureInformations.empty())
+ // now handle any that are left...
+ for (auto const& it : rX509IssuerSerials)
{
- SAL_INFO("xmlsecurity.helper","XSecController::setX509Certificate: no signature");
- return;
+ data.emplace_back();
+ data.back().X509IssuerName = it.first;
+ data.back().X509SerialNumber = it.second;
+ }
+ if (!data.empty())
+ {
+ isi.signatureInfor.X509Datas.push_back(data);
}
- InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
- isi.signatureInfor.ouX509Certificate = ouX509Certificate;
}
void XSecController::setSignatureValue( OUString const & ouSignatureValue )
@@ -322,7 +363,7 @@ void XSecController::setGpgOwner( OUString const & ouGpgOwner )
isi.signatureInfor.ouGpgOwner = ouGpgOwner;
}
-void XSecController::setDate( OUString const & ouDate )
+void XSecController::setDate(OUString const& rId, OUString const& ouDate)
{
if (m_vInternalSignatureInformations.empty())
{
@@ -330,17 +371,31 @@ void XSecController::setDate( OUString const & ouDate )
return;
}
InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
+ // there may be multiple timestamps in a signature - check them for consistency
+ if (!isi.signatureInfor.ouDateTime.isEmpty()
+ && isi.signatureInfor.ouDateTime != ouDate)
+ {
+ isi.signatureInfor.hasInconsistentSigningTime = true;
+ }
(void)utl::ISO8601parseDateTime( ouDate, isi.signatureInfor.stDateTime);
isi.signatureInfor.ouDateTime = ouDate;
+ if (!rId.isEmpty())
+ {
+ isi.signatureInfor.ouDateTimePropertyId = rId;
+ }
}
-void XSecController::setDescription(const OUString& rDescription)
+void XSecController::setDescription(OUString const& rId, OUString const& rDescription)
{
if (m_vInternalSignatureInformations.empty())
return;
InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
rInformation.signatureInfor.ouDescription = rDescription;
+ if (!rId.isEmpty())
+ {
+ rInformation.signatureInfor.ouDescriptionPropertyId = rId;
+ }
}
void XSecController::setSignatureBytes(const uno::Sequence<sal_Int8>& rBytes)
@@ -352,13 +407,67 @@ void XSecController::setSignatureBytes(const uno::Sequence<sal_Int8>& rBytes)
rInformation.signatureInfor.aSignatureBytes = rBytes;
}
-void XSecController::setCertDigest(const OUString& rCertDigest)
+void XSecController::setX509CertDigest(
+ OUString const& rCertDigest, sal_Int32 const /*TODO nReferenceDigestID*/,
+ OUString const& rX509IssuerName, OUString const& rX509SerialNumber)
{
if (m_vInternalSignatureInformations.empty())
return;
InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
- rInformation.signatureInfor.ouCertDigest = rCertDigest;
+ for (auto & rData : rInformation.signatureInfor.X509Datas)
+ {
+ for (auto & it : rData)
+ {
+ if (xmlsecurity::EqualDistinguishedNames(it.X509IssuerName, rX509IssuerName)
+ && it.X509SerialNumber == rX509SerialNumber)
+ {
+ it.CertDigest = rCertDigest;
+ return;
+ }
+ }
+ }
+ // fall-back: read the actual certificates
+ for (auto & rData : rInformation.signatureInfor.X509Datas)
+ {
+ for (auto & it : rData)
+ {
+ if (!it.X509Certificate.isEmpty())
+ {
+ try
+ {
+ uno::Reference<xml::crypto::XSecurityEnvironment> const xSecEnv(m_xSecurityContext->getSecurityEnvironment());
+ uno::Reference<security::XCertificate> const xCert(xSecEnv->createCertificateFromAscii(it.X509Certificate));
+ if (!xCert.is())
+ {
+ SAL_INFO("xmlsecurity.helper", "cannot parse X509Certificate");
+ }
+ else if (xmlsecurity::EqualDistinguishedNames(xCert->getIssuerName(),rX509IssuerName)
+ && xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber()) == rX509SerialNumber)
+ {
+ it.CertDigest = rCertDigest;
+ // note: testInsertCertificate_PEM_DOCX requires these!
+ it.X509SerialNumber = rX509SerialNumber;
+ it.X509IssuerName = rX509IssuerName;
+ return;
+ }
+ }
+ catch (uno::Exception const&)
+ {
+ SAL_INFO("xmlsecurity.helper", "cannot parse X509Certificate");
+ }
+ }
+ }
+ }
+ if (!rInformation.signatureInfor.ouGpgCertificate.isEmpty())
+ {
+ SAL_INFO_IF(rCertDigest != rInformation.signatureInfor.ouGpgKeyID,
+ "xmlsecurity.helper", "PGPKeyID vs CertDigest mismatch");
+ }
+ else
+ {
+ SAL_INFO("xmlsecurity.helper", "cannot find X509Data for CertDigest");
+ }
}
namespace {
@@ -434,27 +543,6 @@ void XSecController::setId( OUString const & ouId )
isi.signatureInfor.ouSignatureId = ouId;
}
-void XSecController::setPropertyId( OUString const & ouPropertyId )
-{
- if (m_vInternalSignatureInformations.empty())
- {
- SAL_INFO("xmlsecurity.helper","XSecController::setPropertyId: no signature");
- return;
- }
- InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
-
- if (isi.signatureInfor.ouPropertyId.isEmpty())
- {
- // <SignatureProperty> ID attribute is for the date.
- isi.signatureInfor.ouPropertyId = ouPropertyId;
- }
- else
- {
- // <SignatureProperty> ID attribute is for the description.
- isi.signatureInfor.ouDescriptionPropertyId = ouPropertyId;
- }
-}
-
/* public: for signature verify */
void XSecController::collectToVerify( const OUString& referenceId )
{
@@ -466,7 +554,7 @@ void XSecController::collectToVerify( const OUString& referenceId )
*/
{
bool bJustChainingOn = false;
- cssu::Reference< cssxs::XDocumentHandler > xHandler;
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xHandler;
int i,j;
int sigNum = m_vInternalSignatureInformations.size();
@@ -490,10 +578,10 @@ void XSecController::collectToVerify( const OUString& referenceId )
}
sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
- cssxc::sax::ElementMarkPriority_BEFOREMODIFY, false );
+ css::xml::crypto::sax::ElementMarkPriority_BEFOREMODIFY, false );
- cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
- ( isi.xReferenceResolvedListener, cssu::UNO_QUERY );
+ css::uno::Reference<css::xml::crypto::sax::XReferenceCollector> xReferenceCollector
+ ( isi.xReferenceResolvedListener, css::uno::UNO_QUERY );
m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
m_xSAXEventKeeper->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
@@ -507,7 +595,6 @@ void XSecController::collectToVerify( const OUString& referenceId )
if ( bJustChainingOn )
{
- cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), cssu::UNO_QUERY);
m_xSAXEventKeeper->setNextHandler(xHandler);
}
}
@@ -521,13 +608,13 @@ void XSecController::addSignature( sal_Int32 nSignatureId )
m_bVerifyCurrentSignature = true;
}
-cssu::Reference< cssxs::XDocumentHandler > const & XSecController::createSignatureReader(XMLSignatureHelper& rXMLSignatureHelper, sal_Int32 nType)
+css::uno::Reference< css::xml::sax::XDocumentHandler > const & XSecController::createSignatureReader(XMLSignatureHelper& rXMLSignatureHelper, sal_Int32 nType)
{
if (nType == embed::StorageFormats::OFOPXML)
m_xSecParser = new OOXMLSecParser(rXMLSignatureHelper, this);
else
m_xSecParser = new XSecParser(rXMLSignatureHelper, this);
- cssu::Reference< cssl::XInitialization > xInitialization(m_xSecParser, uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XInitialization > xInitialization(m_xSecParser, uno::UNO_QUERY);
setSAXChainConnector(xInitialization);
diff --git a/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx
index 2a8ab3603de1..f339c1be480d 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx
@@ -782,7 +782,7 @@ sal_Int32 SecurityEnvironment_MSCryptImpl::verifyCertificate(
const uno::Reference< css::security::XCertificate >& aCert,
const uno::Sequence< uno::Reference< css::security::XCertificate > >& seqCerts)
{
- sal_Int32 validity = 0;
+ sal_Int32 validity = css::security::CertificateValidity::INVALID;
PCCERT_CHAIN_CONTEXT pChainContext = nullptr;
PCCERT_CONTEXT pCertContext = nullptr;
@@ -927,7 +927,7 @@ sal_Int32 SecurityEnvironment_MSCryptImpl::verifyCertificate(
}
else
{
- SAL_INFO("xmlsecurity.xmlsec", "CertGetCertificateChaine failed.");
+ SAL_INFO("xmlsecurity.xmlsec", "CertGetCertificateChain failed.");
}
}
diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
index d44d093641c1..b5f779db3029 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
@@ -26,6 +26,7 @@
#include <cppuhelper/supportsservice.hxx>
#include "x509certificate_mscryptimpl.hxx"
#include <certificateextension_xmlsecimpl.hxx>
+#include <biginteger.hxx>
#include "sanextension_mscryptimpl.hxx"
#include "oid.hxx"
@@ -674,4 +675,50 @@ Sequence<OUString> SAL_CALL X509Certificate_MSCryptImpl::getSupportedServiceName
return { OUString() };
}
+namespace xmlsecurity {
+
+static bool EncodeDistinguishedName(OUString const& rName, CERT_NAME_BLOB & rBlob)
+{
+ LPCWSTR pszError;
+ if (!CertStrToNameW(X509_ASN_ENCODING,
+ reinterpret_cast<LPCWSTR>(rName.getStr()), CERT_X500_NAME_STR,
+ nullptr, nullptr, &rBlob.cbData, &pszError))
+ {
+ SAL_INFO("xmlsecurity.xmlsec", "CertStrToNameW failed: " << WindowsErrorString(GetLastError()) << "; " << reinterpret_cast<char16_t const*>(pszError));
+ return false;
+ }
+ rBlob.pbData = new BYTE[rBlob.cbData];
+ if (!CertStrToNameW(X509_ASN_ENCODING,
+ reinterpret_cast<LPCWSTR>(rName.getStr()), CERT_X500_NAME_STR,
+ nullptr, rBlob.pbData, &rBlob.cbData, &pszError))
+ {
+ SAL_INFO("xmlsecurity.xmlsec", "CertStrToNameW failed: " << WindowsErrorString(GetLastError()) << "; " << reinterpret_cast<char16_t const*>(pszError));
+ return false;
+ }
+ return true;
+}
+
+bool EqualDistinguishedNames(
+ OUString const& rName1, OUString const& rName2)
+{
+ CERT_NAME_BLOB blob1;
+ if (!EncodeDistinguishedName(rName1, blob1))
+ {
+ return false;
+ }
+ CERT_NAME_BLOB blob2;
+ if (!EncodeDistinguishedName(rName2, blob2))
+ {
+ delete[] blob1.pbData;
+ return false;
+ }
+ bool const ret(CertCompareCertificateName(X509_ASN_ENCODING,
+ &blob1, &blob2) == TRUE);
+ delete[] blob2.pbData;
+ delete[] blob1.pbData;
+ return ret;
+}
+
+} // namespace xmlsecurity
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx
index dfa9c4ad494b..a3a04b5c1241 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx
@@ -18,6 +18,7 @@
*/
#include <sal/config.h>
+#include <sal/log.hxx>
#include <rtl/uuid.h>
#include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
@@ -228,6 +229,10 @@ SAL_CALL XMLSignature_MSCryptImpl::validate(
// We do certificate verification ourselves.
pDsigCtx->keyInfoReadCtx.flags |= XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS;
+ // limit possible key data to valid X509 certificates only, no KeyValues
+ if (xmlSecPtrListAdd(&(pDsigCtx->keyInfoReadCtx.enabledKeyData), BAD_CAST xmlSecMSCngKeyDataX509GetKlass()) < 0)
+ throw RuntimeException("failed to limit allowed key data");
+
//Verify signature
//The documentation says that the signature is only valid if the return value is 0 (that is, not < 0)
//AND pDsigCtx->status == xmlSecDSigStatusSucceeded. That is, we must not make any assumptions, if
@@ -250,6 +255,7 @@ SAL_CALL XMLSignature_MSCryptImpl::validate(
++nReferenceGood;
}
}
+ SAL_INFO("xmlsecurity.xmlsec", "xmlSecDSigCtxVerify status " << pDsigCtx->status << ", references good " << nReferenceGood << " of " << nReferenceCount);
if (rs == 0 && nReferenceCount == nReferenceGood)
{
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
index 180ef6558d38..cfa4ed65a049 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
@@ -32,6 +32,7 @@
#include <rtl/ref.hxx>
#include "x509certificate_nssimpl.hxx"
+#include <biginteger.hxx>
#include <certificateextension_xmlsecimpl.hxx>
#include "sanextension_nssimpl.hxx"
@@ -534,4 +535,28 @@ sal_Bool SAL_CALL X509Certificate_NssImpl::supportsService(const OUString& servi
/* XServiceInfo */
Sequence<OUString> SAL_CALL X509Certificate_NssImpl::getSupportedServiceNames() { return { OUString() }; }
+namespace xmlsecurity {
+
+bool EqualDistinguishedNames(
+ OUString const& rName1, OUString const& rName2)
+{
+ CERTName *const pName1(CERT_AsciiToName(OUStringToOString(rName1, RTL_TEXTENCODING_UTF8).getStr()));
+ if (pName1 == nullptr)
+ {
+ return false;
+ }
+ CERTName *const pName2(CERT_AsciiToName(OUStringToOString(rName2, RTL_TEXTENCODING_UTF8).getStr()));
+ if (pName2 == nullptr)
+ {
+ CERT_DestroyName(pName1);
+ return false;
+ }
+ bool const ret(CERT_CompareName(pName1, pName2) == SECEqual);
+ CERT_DestroyName(pName2);
+ CERT_DestroyName(pName1);
+ return ret;
+}
+
+} // namespace xmlsecurity
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx
index 311ce6aeb69f..1108d8fd8661 100644
--- a/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx
@@ -28,6 +28,9 @@
#include "securityenvironment_nssimpl.hxx"
#include <xmlsec-wrapper.h>
+
+#include <sal/log.hxx>
+
#include <com/sun/star/xml/crypto/XXMLSignature.hpp>
#include <memory>
@@ -244,6 +247,10 @@ SAL_CALL XMLSignature_NssImpl::validate(
// We do certificate verification ourselves.
pDsigCtx->keyInfoReadCtx.flags |= XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS;
+ // limit possible key data to valid X509 certificates only, no KeyValues
+ if (xmlSecPtrListAdd(&(pDsigCtx->keyInfoReadCtx.enabledKeyData), BAD_CAST xmlSecNssKeyDataX509GetKlass()) < 0)
+ throw RuntimeException("failed to limit allowed key data");
+
//Verify signature
int rs = xmlSecDSigCtxVerify( pDsigCtx.get() , pNode );
@@ -260,6 +267,7 @@ SAL_CALL XMLSignature_NssImpl::validate(
++nReferenceGood;
}
}
+ SAL_INFO("xmlsecurity.xmlsec", "xmlSecDSigCtxVerify status " << pDsigCtx->status << ", references good " << nReferenceGood << " of " << nReferenceCount);
if (rs == 0 && pDsigCtx->status == xmlSecDSigStatusSucceeded && nReferenceCount == nReferenceGood)
{