From 7ac4e48687d7679927f5659e941024445946ffa7 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 30 Jul 2018 20:29:08 +0200 Subject: tdf#118593 sfx2: no need to call into xmlsecurity without signature streams In the ODF and OOXML cases the ZIP storage already tells us if there are signatures on this file so we can avoid the whole libxmlsec init, which can be slow. The bugreport talks about a smartcard setup, I also heard that the gpg code in xmlsecurity isn't cheap to init, either. Change-Id: Ife9ed577d03e96a9ac2f42a28776b7df58e76c59 Reviewed-on: https://gerrit.libreoffice.org/58344 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- sfx2/source/doc/objserv.cxx | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'sfx2') diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 0c17b7e45722..69b933c7fbdc 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -1295,6 +1295,38 @@ SignatureState SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequen return nResult; } +/// Does this ZIP storage have a signature stream? +static bool HasSignatureStream(const uno::Reference& xStorage) +{ + uno::Reference xNameAccess(xStorage, uno::UNO_QUERY); + if (!xNameAccess.is()) + return false; + + if (xNameAccess->hasByName("META-INF")) + { + // ODF case. + try + { + uno::Reference xMetaInf + = xStorage->openStorageElement("META-INF", embed::ElementModes::READ); + uno::Reference xMetaInfNames(xMetaInf, uno::UNO_QUERY); + if (xMetaInfNames.is()) + { + return xMetaInfNames->hasByName("documentsignatures.xml") + || xMetaInfNames->hasByName("macrosignatures.xml") + || xMetaInfNames->hasByName("packagesignatures.xml"); + } + } + catch (const css::io::IOException& rException) + { + SAL_WARN("sfx.doc", "HasSignatureStream: failed to open META-INF: " << rException.Message); + } + } + + // OOXML case. + return xNameAccess->hasByName("_xmlsignatures"); +} + uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner ) { uno::Sequence< security::DocumentSignatureInformation > aResult; @@ -1329,8 +1361,11 @@ uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnal if (GetMedium()->GetStorage().is()) { // Something ZIP-based. - aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), - uno::Reference< io::XInputStream >() ); + // Only call into xmlsecurity if we see a signature stream, + // as libxmlsec init is expensive. + if (HasSignatureStream(GetMedium()->GetZipStorageToSign_Impl())) + aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), + uno::Reference< io::XInputStream >() ); } else { -- cgit