Fix signing empty Configurations2/accelerator/current.xml
When determining if a file is an XML file for siging, we need to
read the manifest file to get an accurate detection. In case when
we were signing in the GUI the manifest file was read when the
storage was set. When we didn't sign over the GUI, the manifest
was never read: the code was only present in the GUI code -
"documentsignaturesdialog.cxx" so the detection was wrong and
isXML returned "true" for current.xml.
With this we move the manifest reading to DigitalSignatureManager,
where the manifest is read when needed.
Change-Id: If45a32af6410bc5f7c5afdb976b182bd69ab7d6b
Reviewed-on: https://gerrit.libreoffice.org/65600
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index e769490..a934ac5 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2372,6 +2372,9 @@ void DesktopLOKTest::testInsertCertificate()
CPPUNIT_ASSERT(bResult);
}
int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
CPPUNIT_ASSERT_EQUAL(int(1), nState);
comphelper::LibreOfficeKit::setActive(false);
}
@@ -2458,6 +2461,9 @@ void DesktopLOKTest::testInsertCertificatePEM()
CPPUNIT_ASSERT(bResult);
}
int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
CPPUNIT_ASSERT_EQUAL(int(1), nState);
comphelper::LibreOfficeKit::setActive(false);
}
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index d67e083..85ad7cb 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -83,6 +83,8 @@ public:
* differently when they are signed (c14n transformation)
*/
bool isXML(const OUString& rURI);
bool readManifest();
SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 nStreamOpenMode, bool bTempStream);
/// Add a new signature, using xCert as a signing certificate, and rDescription as description.
bool add(const css::uno::Reference<css::security::XCertificate>& xCert,
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index a09dfad..63c0c83 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -36,7 +36,6 @@
#include <com/sun/star/security/CertificateKind.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
#include <com/sun/star/packages/manifest/ManifestReader.hpp>
#include <com/sun/star/system/SystemShellExecute.hpp>
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
#include <com/sun/star/system/SystemShellExecuteException.hpp>
@@ -243,26 +242,6 @@ void DigitalSignaturesDialog::SetStorage( const css::uno::Reference < css::embed
maSignatureManager.mxStore = rxStore;
maSignatureManager.maSignatureHelper.SetStorage( maSignatureManager.mxStore, m_sODFVersion);
Reference < css::packages::manifest::XManifestReader > xReader =
css::packages::manifest::ManifestReader::create(mxCtx);
uno::Reference<container::XNameAccess> xNameAccess(rxStore, uno::UNO_QUERY);
if (!xNameAccess.is())
return;
if (xNameAccess->hasByName("META-INF"))
{
//Get the manifest.xml
Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement(
"META-INF", css::embed::ElementModes::READ), UNO_QUERY_THROW);
Reference< css::io::XInputStream > xStream(
xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
UNO_QUERY_THROW);
maSignatureManager.m_manifest = xReader->readManifestSequence(xStream);
}
}
void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream )
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 2b3c0a8..5da6459 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -30,6 +30,7 @@
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/packages/manifest/ManifestReader.hpp>
#include <comphelper/base64.hxx>
#include <comphelper/storagehelper.hxx>
@@ -125,6 +126,40 @@ bool DocumentSignatureManager::IsXAdESRelevant()
}
#endif
bool DocumentSignatureManager::readManifest()
{
// Check if manifest was already read
if (m_manifest.getLength() > 0)
return true;
if (!mxContext.is())
return false;
if (!mxStore.is())
return false;
uno::Reference<packages::manifest::XManifestReader> xReader
= packages::manifest::ManifestReader::create(mxContext);
uno::Reference<container::XNameAccess> xNameAccess(mxStore, uno::UNO_QUERY);
if (!xNameAccess.is())
return false;
if (xNameAccess->hasByName("META-INF"))
{
//Get the manifest.xml
uno::Reference<embed::XStorage> xSubStore(
mxStore->openStorageElement("META-INF", embed::ElementModes::READ), UNO_QUERY_THROW);
uno::Reference<io::XInputStream> xStream(
xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
UNO_QUERY_THROW);
m_manifest = xReader->readManifestSequence(xStream);
}
return true;
}
/* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
We use the manifest to find out if a file is xml and if it is encrypted.
The parameter is an encoded uri. However, the manifest contains paths. Therefore
@@ -140,27 +175,30 @@ bool DocumentSignatureManager::isXML(const OUString& rURI)
const OUString sPropMediaType("MediaType");
const OUString sPropDigest("Digest");
for (int i = 0; i < m_manifest.getLength(); i++)
if (readManifest())
{
const uno::Sequence<beans::PropertyValue>& entry = m_manifest[i];
OUString sPath, sMediaType;
bool bEncrypted = false;
for (int j = 0; j < entry.getLength(); j++)
for (int i = 0; i < m_manifest.getLength(); i++)
{
const beans::PropertyValue& prop = entry[j];
const uno::Sequence<beans::PropertyValue>& entry = m_manifest[i];
OUString sPath, sMediaType;
bool bEncrypted = false;
for (int j = 0; j < entry.getLength(); j++)
{
const beans::PropertyValue& prop = entry[j];
if (prop.Name == sPropFullPath)
prop.Value >>= sPath;
else if (prop.Name == sPropMediaType)
prop.Value >>= sMediaType;
else if (prop.Name == sPropDigest)
bEncrypted = true;
}
if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
{
bIsXML = sMediaType == "text/xml" && !bEncrypted;
bPropsAvailable = true;
break;
if (prop.Name == sPropFullPath)
prop.Value >>= sPath;
else if (prop.Name == sPropMediaType)
prop.Value >>= sMediaType;
else if (prop.Name == sPropDigest)
bEncrypted = true;
}
if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
{
bIsXML = sMediaType == "text/xml" && !bEncrypted;
bPropsAvailable = true;
break;
}
}
}
if (!bPropsAvailable)