From adb203bc05e3e36173cbd46b9951f79821a81799 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 11:27:54 +0200 Subject: Merging upstream version 4:24.2.1. Signed-off-by: Daniel Baumann --- xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx | 9 +- .../signing/data/encrypted_scriptsig_lo242.odt | Bin 0 -> 13599 bytes .../signing/data/encrypted_scriptsig_odf13.odt | Bin 0 -> 19707 bytes xmlsecurity/qa/unit/signing/signing.cxx | 5 +- xmlsecurity/qa/unit/signing/signing2.cxx | 309 +++++++++++++++++++++ 5 files changed, 313 insertions(+), 10 deletions(-) create mode 100644 xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_lo242.odt create mode 100644 xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_odf13.odt (limited to 'xmlsecurity/qa') diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx index 0196a4707b..46981b250a 100644 --- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx +++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx @@ -63,7 +63,6 @@ protected: public: PDFSigningTest(); void setUp() override; - void tearDown() override; }; PDFSigningTest::PDFSigningTest() {} @@ -71,7 +70,7 @@ PDFSigningTest::PDFSigningTest() {} void PDFSigningTest::setUp() { test::BootstrapFixture::setUp(); - MacrosTest::setUpNssGpg(m_directories, "xmlsecurity_pdfsigning"); + MacrosTest::setUpX509(m_directories, "xmlsecurity_pdfsigning"); uno::Reference xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); @@ -86,12 +85,6 @@ void PDFSigningTest::setUp() #endif } -void PDFSigningTest::tearDown() -{ - MacrosTest::tearDownNssGpg(); - test::BootstrapFixture::tearDown(); -} - std::vector PDFSigningTest::verify(const OUString& rURL, size_t nCount) { uno::Reference xSEInitializer diff --git a/xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_lo242.odt b/xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_lo242.odt new file mode 100644 index 0000000000..1747448ac5 Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_lo242.odt differ diff --git a/xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_odf13.odt b/xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_odf13.odt new file mode 100644 index 0000000000..fb2b978bc0 Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/encrypted_scriptsig_odf13.odt differ diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index 9f449d26d6..316eaf22f5 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -92,7 +92,8 @@ void SigningTest::setUp() { UnoApiXmlTest::setUp(); - MacrosTest::setUpNssGpg(m_directories, "xmlsecurity_signing"); + MacrosTest::setUpX509(m_directories, "xmlsecurity_signing"); + MacrosTest::setUpGpg(m_directories, "xmlsecurity_signing"); // Initialize crypto after setting up the environment variables. mxSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); @@ -108,7 +109,7 @@ void SigningTest::setUp() void SigningTest::tearDown() { - MacrosTest::tearDownNssGpg(); + MacrosTest::tearDownGpg(); UnoApiXmlTest::tearDown(); } 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 +#include + +#if USE_CRYPTO_NSS +#include +#endif + #include +#include #include #include #include +#include #include #include +#include + +#include +#include +#include #include #include #include @@ -30,8 +43,14 @@ using namespace css; /// Testsuite for the document signing feature. class SigningTest2 : public UnoApiXmlTest { +protected: + uno::Reference mxSEInitializer; + uno::Reference 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 xTextDoc(mxComponent, uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString()); + // test macro signature + SfxBaseModel* pBaseModel(dynamic_cast(mxComponent.get())); + CPPUNIT_ASSERT(pBaseModel); + SfxObjectShell* pObjectShell(pBaseModel->GetObjectShell()); + uno::Reference xPropSet(pObjectShell->GetStorage(), + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(ODFVER_013_TEXT, + xPropSet->getPropertyValue("Version").get()); + 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 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 pBatch( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::Misc::ExperimentalMode::set(false, pBatch); + return pBatch->commit(); + }); + std::shared_ptr 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 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 xTextDoc(mxComponent, uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("secret"), xTextDoc->getText()->getString()); + // test macro signature + SfxBaseModel* pBaseModel(dynamic_cast(mxComponent.get())); + CPPUNIT_ASSERT(pBaseModel); + SfxObjectShell* pObjectShell(pBaseModel->GetObjectShell()); + uno::Reference xPropSet(pObjectShell->GetStorage(), + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(ODFVER_013_TEXT, + xPropSet->getPropertyValue("Version").get()); + CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetScriptingSignatureState()); + } + + { + Resetter resetter([]() { + std::shared_ptr pBatch( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::Misc::ExperimentalMode::set(false, pBatch); + return pBatch->commit(); + }); + std::shared_ptr 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 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(mxComponent.get())); + CPPUNIT_ASSERT(pBaseModel); + SfxObjectShell* pObjectShell(pBaseModel->GetObjectShell()); + uno::Reference xPropSet(pObjectShell->GetStorage(), + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(ODFVER_013_TEXT, + xPropSet->getPropertyValue("Version").get()); + 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 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(); -- cgit v1.2.3