summaryrefslogtreecommitdiffstats
path: root/xmlsecurity/qa/unit/signing/signing2.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xmlsecurity/qa/unit/signing/signing2.cxx')
-rw-r--r--xmlsecurity/qa/unit/signing/signing2.cxx309
1 files changed, 309 insertions, 0 deletions
diff --git a/xmlsecurity/qa/unit/signing/signing2.cxx b/xmlsecurity/qa/unit/signing/signing2.cxx
index aef3c7f088..50baa98223 100644
--- a/xmlsecurity/qa/unit/signing/signing2.cxx
+++ b/xmlsecurity/qa/unit/signing/signing2.cxx
@@ -9,14 +9,27 @@
#include <sal/config.h>
+#include <config_crypto.h>
+
+#if USE_CRYPTO_NSS
+#include <secoid.h>
+#endif
+
#include <test/unoapixml_test.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
+#include <officecfg/Office/Common.hxx>
+
+#include <sfx2/sfxbasemodel.hxx>
+#include <sfx2/objsh.hxx>
+#include <comphelper/documentconstants.hxx>
#include <comphelper/propertysequence.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/ucbstreamhelper.hxx>
@@ -30,8 +43,14 @@ using namespace css;
/// Testsuite for the document signing feature.
class SigningTest2 : public UnoApiXmlTest
{
+protected:
+ uno::Reference<xml::crypto::XSEInitializer> mxSEInitializer;
+ uno::Reference<xml::crypto::XXMLSecurityContext> mxSecurityContext;
+
public:
SigningTest2();
+ virtual void setUp() override;
+ virtual void tearDown() override;
void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override;
};
@@ -40,6 +59,32 @@ SigningTest2::SigningTest2()
{
}
+void SigningTest2::setUp()
+{
+ UnoApiXmlTest::setUp();
+
+ MacrosTest::setUpX509(m_directories, "xmlsecurity_signing2");
+ MacrosTest::setUpGpg(m_directories, "xmlsecurity_signing2");
+
+ // Initialize crypto after setting up the environment variables.
+ mxSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext);
+ mxSecurityContext = mxSEInitializer->createSecurityContext(OUString());
+#if USE_CRYPTO_NSS
+#ifdef NSS_USE_ALG_IN_ANY_SIGNATURE
+ // policy may disallow using SHA1 for signatures but unit test documents
+ // have such existing signatures (call this after createSecurityContext!)
+ NSS_SetAlgorithmPolicy(SEC_OID_SHA1, NSS_USE_ALG_IN_ANY_SIGNATURE, 0);
+#endif
+#endif
+}
+
+void SigningTest2::tearDown()
+{
+ MacrosTest::tearDownGpg();
+
+ UnoApiXmlTest::tearDown();
+}
+
/// Test if a macro signature from a ODF Database is preserved when saving
CPPUNIT_TEST_FIXTURE(SigningTest2, testPreserveMacroSignatureODB)
{
@@ -66,6 +111,263 @@ CPPUNIT_TEST_FIXTURE(SigningTest2, testPreserveMacroSignatureODB)
"ID_00a7002f009000bc00ce00f7004400460080002f002e00e400e0003700df00e8");
}
+CPPUNIT_TEST_FIXTURE(SigningTest2, testPasswordPreserveMacroSignatureODF13)
+{
+ // load ODF 1.3 encrypted document
+ load(createFileURL(u"encrypted_scriptsig_odf13.odt"), "password");
+ {
+ uno::Reference<text::XTextDocument> xTextDoc(mxComponent, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString());
+ // test macro signature
+ SfxBaseModel* pBaseModel(dynamic_cast<SfxBaseModel*>(mxComponent.get()));
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell(pBaseModel->GetObjectShell());
+ uno::Reference<beans::XPropertySet> xPropSet(pObjectShell->GetStorage(),
+ uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(ODFVER_013_TEXT,
+ xPropSet->getPropertyValue("Version").get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetScriptingSignatureState());
+ }
+
+ saveAndReload("writer8", "password");
+ {
+ // test standard ODF 1.2/1.3/1.4 encryption
+ xmlDocUniquePtr pXmlDoc = parseExport("META-INF/manifest.xml");
+ assertXPath(pXmlDoc, "/manifest:manifest"_ostr, "version"_ostr, "1.3");
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry[@manifest:size != '0']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data[@manifest:checksum-type and @manifest:checksum]"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[@manifest:algorithm-name='http://www.w3.org/2001/04/xmlenc#aes256-cbc']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[string-length(@manifest:initialisation-vector) = 24]"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:start-key-generation[@manifest:start-key-generation-name='http://www.w3.org/2000/09/xmldsig#sha256' and @manifest:key-size='32']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:key-derivation-name='PBKDF2' and @manifest:key-size='32']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:iteration-count='100000']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[string-length(@manifest:salt) = 24]"_ostr,
+ 8);
+ // test reimport
+ uno::Reference<text::XTextDocument> xTextDoc(mxComponent, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString());
+ // test macro signature - this didn't actually work!
+ // using Zip Storage means the encrypted streams are signed, so
+ // after encrypting again the sigature didn't match and was dropped
+ // assertDocument(CPPUNIT_SOURCELINE(), "writer8", SignatureState::NOSIGNATURES,
+ // SignatureState::OK, ODFVER_013_TEXT);
+ }
+
+ {
+ Resetter resetter([]() {
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(false, pBatch);
+ return pBatch->commit();
+ });
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(true, pBatch);
+ pBatch->commit();
+
+ // store it experimental - reload
+ saveAndReload("writer8", "password");
+
+ // test wholesome ODF extended encryption
+ xmlDocUniquePtr pXmlDoc = parseExport("META-INF/manifest.xml");
+ assertXPath(pXmlDoc, "/manifest:manifest"_ostr, "version"_ostr, "1.3");
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry"_ostr, 1);
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry"_ostr, "full-path"_ostr,
+ "encrypted-package");
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry[@manifest:size != '0']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data[@manifest:checksum-type or @manifest:checksum]"_ostr,
+ 0);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[@manifest:algorithm-name='http://www.w3.org/2009/xmlenc11#aes256-gcm']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[string-length(@manifest:initialisation-vector) = 16]"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:start-key-generation[@manifest:start-key-generation-name='http://www.w3.org/2001/04/xmlenc#sha256' and @manifest:key-size='32']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:key-derivation-name='urn:org:documentfoundation:names:experimental:office:manifest:argon2id' and @manifest:key-size='32']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:iteration-count]"_ostr,
+ 0);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[string-length(@manifest:salt) = 24]"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@loext:argon2-iterations='3' and @loext:argon2-memory='65536' and @loext:argon2-lanes='4']"_ostr,
+ 1);
+ // test reimport
+ uno::Reference<text::XTextDocument> xTextDoc(mxComponent, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString());
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SigningTest2, testPasswordPreserveMacroSignatureODFWholesomeLO242)
+{
+ // load wholesome ODF (extended) encrypted document
+ load(createFileURL(u"encrypted_scriptsig_lo242.odt"), "password");
+ {
+ uno::Reference<text::XTextDocument> xTextDoc(mxComponent, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString());
+ // test macro signature
+ SfxBaseModel* pBaseModel(dynamic_cast<SfxBaseModel*>(mxComponent.get()));
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell(pBaseModel->GetObjectShell());
+ uno::Reference<beans::XPropertySet> xPropSet(pObjectShell->GetStorage(),
+ uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(ODFVER_013_TEXT,
+ xPropSet->getPropertyValue("Version").get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetScriptingSignatureState());
+ }
+
+ {
+ Resetter resetter([]() {
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(false, pBatch);
+ return pBatch->commit();
+ });
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(true, pBatch);
+ pBatch->commit();
+
+ // store it experimental - reload
+ saveAndReload("writer8", "password");
+
+ // test wholesome ODF extended encryption
+ xmlDocUniquePtr pXmlDoc = parseExport("META-INF/manifest.xml");
+ assertXPath(pXmlDoc, "/manifest:manifest"_ostr, "version"_ostr, "1.3");
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry"_ostr, 1);
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry"_ostr, "full-path"_ostr,
+ "encrypted-package");
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry[@manifest:size != '0']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data[@manifest:checksum-type or @manifest:checksum]"_ostr,
+ 0);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[@manifest:algorithm-name='http://www.w3.org/2009/xmlenc11#aes256-gcm']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[string-length(@manifest:initialisation-vector) = 16]"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:start-key-generation[@manifest:start-key-generation-name='http://www.w3.org/2001/04/xmlenc#sha256' and @manifest:key-size='32']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:key-derivation-name='urn:org:documentfoundation:names:experimental:office:manifest:argon2id' and @manifest:key-size='32']"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:iteration-count]"_ostr,
+ 0);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[string-length(@manifest:salt) = 24]"_ostr,
+ 1);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@loext:argon2-iterations='3' and @loext:argon2-memory='65536' and @loext:argon2-lanes='4']"_ostr,
+ 1);
+ // test reimport
+ uno::Reference<text::XTextDocument> xTextDoc(mxComponent, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString());
+ // test macro signature - this should work now
+ SfxBaseModel* pBaseModel(dynamic_cast<SfxBaseModel*>(mxComponent.get()));
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell(pBaseModel->GetObjectShell());
+ uno::Reference<beans::XPropertySet> xPropSet(pObjectShell->GetStorage(),
+ uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(ODFVER_013_TEXT,
+ xPropSet->getPropertyValue("Version").get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetScriptingSignatureState());
+ }
+
+ saveAndReload("writer8", "password");
+ {
+ // test standard ODF 1.2/1.3/1.4 encryption
+ xmlDocUniquePtr pXmlDoc = parseExport("META-INF/manifest.xml");
+ assertXPath(pXmlDoc, "/manifest:manifest"_ostr, "version"_ostr, "1.3");
+ assertXPath(pXmlDoc, "/manifest:manifest/manifest:file-entry[@manifest:size != '0']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data[@manifest:checksum-type and @manifest:checksum]"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[@manifest:algorithm-name='http://www.w3.org/2001/04/xmlenc#aes256-cbc']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:algorithm[string-length(@manifest:initialisation-vector) = 24]"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:start-key-generation[@manifest:start-key-generation-name='http://www.w3.org/2000/09/xmldsig#sha256' and @manifest:key-size='32']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:key-derivation-name='PBKDF2' and @manifest:key-size='32']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[@manifest:iteration-count='100000']"_ostr,
+ 8);
+ assertXPath(
+ pXmlDoc,
+ "/manifest:manifest/manifest:file-entry/manifest:encryption-data/manifest:key-derivation[string-length(@manifest:salt) = 24]"_ostr,
+ 8);
+ // test reimport
+ uno::Reference<text::XTextDocument> xTextDoc(mxComponent, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString());
+ // test macro signature - this didn't actually work!
+ // using Zip Storage means the encrypted streams are signed, so
+ // after encrypting again the sigature didn't match and was dropped
+ // assertDocument(CPPUNIT_SOURCELINE(), "writer8", SignatureState::NOSIGNATURES,
+ // SignatureState::OK, ODFVER_013_TEXT);
+ }
+}
+
void SigningTest2::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
{
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("odfds"),
@@ -73,6 +375,13 @@ void SigningTest2::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dsig"),
BAD_CAST("http://www.w3.org/2000/09/xmldsig#"));
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xd"), BAD_CAST("http://uri.etsi.org/01903/v1.3.2#"));
+
+ // manifest.xml
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("manifest"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("loext"),
+ BAD_CAST("urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"));
}
CPPUNIT_PLUGIN_IMPLEMENT();