sd/qa/unit/tiledrendering/tiledrendering.cxx | 9 ++- sw/source/core/doc/DocumentStylePoolManager.cxx | 2 xmlsecurity/inc/documentsignaturemanager.hxx | 2 xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx | 2 xmlsecurity/inc/xmlsecurity/sigstruct.hxx | 3 + xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx | 2 xmlsecurity/qa/unit/signing/signing.cxx | 31 ++++++++++ xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 8 +- xmlsecurity/source/helper/documentsignaturemanager.cxx | 4 - xmlsecurity/source/helper/xmlsignaturehelper.cxx | 46 +++++++++++++--- xmlsecurity/source/helper/xsecctl.hxx | 3 + xmlsecurity/source/helper/xsecverify.cxx | 9 +++ 12 files changed, 99 insertions(+), 22 deletions(-)
New commits: commit 78a209b951d2f6e6bb3001b45c242a85fcf9ebb0 Author: Miklos Vajna <[email protected]> Date: Fri Mar 4 11:18:17 2016 +0100 CppunitTest_xmlsecurity_signing: add signature append testcase Fails with e.g. commit 963264a417ce807201f0021fc6000ce7d6cf0245 (xmlsecurity OOXML export: don't loose old signatures when adding a new one, 2016-03-03) reverted. Change-Id: Ia2b0f3d8914bca14075481f5ac8cd4c0033d26c1 diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index d9aec73..5d97d71 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -64,12 +64,15 @@ public: /// Test a typical broken OOXML signature where one stream is corrupted. void testOOXMLBroken(); void testOOXMLDescription(); + /// Test appending a new signature next to an existing one. + void testOOXMLAppend(); CPPUNIT_TEST_SUITE(SigningTest); CPPUNIT_TEST(testDescription); CPPUNIT_TEST(testOOXMLPartial); CPPUNIT_TEST(testOOXMLBroken); CPPUNIT_TEST(testOOXMLDescription); + CPPUNIT_TEST(testOOXMLAppend); CPPUNIT_TEST_SUITE_END(); private: @@ -177,7 +180,7 @@ void SigningTest::testOOXMLDescription() aManager.mxStore = xStorage; aManager.maSignatureHelper.SetStorage(xStorage, "1.2"); - // Then add a signature document. + // Then add a document signature. uno::Reference<security::XCertificate> xCertificate = getCertificate(aManager.maSignatureHelper); CPPUNIT_ASSERT(xCertificate.is()); OUString aDescription("SigningTest::testDescription"); @@ -191,6 +194,32 @@ void SigningTest::testOOXMLDescription() CPPUNIT_ASSERT_EQUAL(aDescription, rInformations[0].ouDescription); } +void SigningTest::testOOXMLAppend() +{ + // Load the test document as a storage and read its single signature. + DocumentSignatureManager aManager(mxComponentContext, SignatureModeDocumentContent); + CPPUNIT_ASSERT(aManager.maSignatureHelper.Init()); + OUString aURL = getURLFromSrc(DATA_DIRECTORY) + "partial.docx"; + uno::Reference <embed::XStorage> xStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL(ZIP_STORAGE_FORMAT_STRING, aURL, embed::ElementModes::READWRITE); + CPPUNIT_ASSERT(xStorage.is()); + aManager.mxStore = xStorage; + aManager.maSignatureHelper.SetStorage(xStorage, "1.2"); + aManager.read(/*bUseTempStream=*/false); + std::vector<SignatureInformation>& rInformations = aManager.maCurrentSignatureInformations; + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rInformations.size()); + + // Then add a second document signature. + uno::Reference<security::XCertificate> xCertificate = getCertificate(aManager.maSignatureHelper); + CPPUNIT_ASSERT(xCertificate.is()); + sal_Int32 nSecurityId; + aManager.add(xCertificate, OUString(), nSecurityId); + + // Read back the signatures and make sure that we have the expected amount. + aManager.read(/*bUseTempStream=*/true); + // This was 1: the original signature was lost. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rInformations.size()); +} + void SigningTest::testOOXMLPartial() { createDoc(getURLFromSrc(DATA_DIRECTORY) + "partial.docx"); commit e89610dad647ea5c77805ff06af1ea9870ae9f15 Author: Miklos Vajna <[email protected]> Date: Fri Mar 4 10:49:12 2016 +0100 xmlsecurity OOXML export: only cache existing signatures, not our temp. one When adding a signature, first we export it to a temp. storage, then read it back, show the verification to the user, and then later we do or do not write the temp. storage back to the original one. This means the signature gets exported two times, and MSO only considers the final result valid. So when caching signatures (to avoid a real export based on our data model), don't cache the one we just added to the temp. storage, but do a real export second time as well. With this, MSO considers our appended signature (next to an existing one) valid, too. Change-Id: I4d615298463e037ea4e654ff5c3addcef8b0a094 diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx index 6719c26..b5a7e1b 100644 --- a/xmlsecurity/inc/documentsignaturemanager.hxx +++ b/xmlsecurity/inc/documentsignaturemanager.hxx @@ -54,7 +54,7 @@ public: /// Add a new signature, using xCert as a signing certificate, and rDescription as description. bool add(const css::uno::Reference<css::security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId); /// Read signatures from either a temp stream or the real storage. - void read(bool bUseTempStream); + void read(bool bUseTempStream, bool bCacheLastSignature = true); }; #endif // INCLUDED_XMLSECURITY_INC_XMLSECURITY_DOCUMENTSIGNATUREMANAGER_HXX diff --git a/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx b/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx index eb99f35..83370db 100644 --- a/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx +++ b/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx @@ -91,7 +91,7 @@ private: DECL_LINK_TYPED(StartVerifySignatureHdl, LinkParamNone*, bool ); DECL_LINK_TYPED(OKButtonHdl, Button*, void ); - void ImplGetSignatureInformations(bool bUseTempStream); + void ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature = true); void ImplFillSignaturesBox(); void ImplShowSignaturesDetails(); diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx index 55dc230..a8cdf93 100644 --- a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx +++ b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx @@ -178,7 +178,7 @@ public: static void ExportSignature( const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler, const SignatureInformation& signatureInfo ); /// Read and verify OOXML signatures. - bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage); + bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bCacheLastSignature = true); /// Read and verify a single OOXML signature. bool ReadAndVerifySignatureStorageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream); /// Adds an OOXML digital signature relation to _rels/.rels if there wasn't any before. diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index 77d058d..8e7806e 100644 --- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx +++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx @@ -413,7 +413,7 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, AddButtonHdl, Button*, void) // will not contain // SecurityOperationStatus_OPERATION_SUCCEEDED mbVerifySignatures = true; - ImplGetSignatureInformations(true); + ImplGetSignatureInformations(true, /*bCacheLastSignature=*/false); ImplFillSignaturesBox(); } } @@ -422,7 +422,7 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, AddButtonHdl, Button*, void) { OSL_FAIL( "Exception while adding a signature!" ); // Don't keep invalid entries... - ImplGetSignatureInformations(true); + ImplGetSignatureInformations(true, /*bCacheLastSignature=*/false); ImplFillSignaturesBox(); } } @@ -624,9 +624,9 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox() //If bUseTempStream is true then the temporary signature stream is used. //Otherwise the real signature stream is used. -void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream) +void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature) { - maSignatureManager.read(bUseTempStream); + maSignatureManager.read(bUseTempStream, bCacheLastSignature); mbVerifySignatures = false; } diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx index b5bc008..5127e3c 100644 --- a/xmlsecurity/source/helper/documentsignaturemanager.cxx +++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx @@ -290,7 +290,7 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>& return true; } -void DocumentSignatureManager::read(bool bUseTempStream) +void DocumentSignatureManager::read(bool bUseTempStream, bool bCacheLastSignature) { maCurrentSignatureInformations.clear(); @@ -303,7 +303,7 @@ void DocumentSignatureManager::read(bool bUseTempStream) maSignatureHelper.ReadAndVerifySignature(xInputStream); } else if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML && aStreamHelper.xSignatureStorage.is()) - maSignatureHelper.ReadAndVerifySignatureStorage(aStreamHelper.xSignatureStorage); + maSignatureHelper.ReadAndVerifySignatureStorage(aStreamHelper.xSignatureStorage, bCacheLastSignature); maSignatureHelper.EndMission(); maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations(); diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx index 2b05621..57474f2 100644 --- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx +++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx @@ -385,7 +385,7 @@ bool lcl_isSignatureOriginType(const beans::StringPair& rPair) } } -bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage) +bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage, bool bCacheLastSignature) { sal_Int32 nOpenMode = embed::ElementModes::READ; uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode); @@ -393,8 +393,9 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embe uno::Sequence< uno::Sequence<beans::StringPair> > aRelationsInfo; aRelationsInfo = comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, "origin.sigs.rels", mxCtx); - for (const uno::Sequence<beans::StringPair>& rRelation : aRelationsInfo) + for (sal_Int32 i = 0; i < aRelationsInfo.getLength(); ++i) { + const uno::Sequence<beans::StringPair>& rRelation = aRelationsInfo[i]; auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation); if (std::find_if(aRelation.begin(), aRelation.end(), lcl_isSignatureType) != aRelation.end()) { @@ -412,17 +413,25 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embe if (!ReadAndVerifySignatureStorageStream(xInputStream)) return false; - // Store the contents of the stream as is, in case we need to write it back later. - xInputStream.clear(); - xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY); - if (xPropertySet.is()) + // By default, we cache. If it's requested, then we don't cache the last signature. + bool bCache = true; + if (!bCacheLastSignature && i == aRelationsInfo.getLength() - 1) + bCache = false; + + if (bCache) { - sal_Int64 nSize = 0; - xPropertySet->getPropertyValue("Size") >>= nSize; - uno::Sequence<sal_Int8> aData; - xInputStream->readBytes(aData, nSize); - mpXSecController->setSignatureBytes(aData); + // Store the contents of the stream as is, in case we need to write it back later. + xInputStream.clear(); + xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY); + if (xPropertySet.is()) + { + sal_Int64 nSize = 0; + xPropertySet->getPropertyValue("Size") >>= nSize; + uno::Sequence<sal_Int8> aData; + xInputStream->readBytes(aData, nSize); + mpXSecController->setSignatureBytes(aData); + } } } } commit 38c39dc49c502683a3ccbcbfaa7e7ecee413c30f Author: Miklos Vajna <[email protected]> Date: Fri Mar 4 09:40:17 2016 +0100 xmlsecurity OOXML export: fix appending new signatures next to existing ones We append a new signature to a document by re-exporting the existing ones, then writing the new signature. Given that existing signatures aren't canonicalized before hashing, write them back as-is. With this, our own signature verification is happy about the export result, containing an existing and a newly created signature. Change-Id: I0ff57a2266c6070a945f0c45ca5793406678be60 diff --git a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx index e501239..3cb1e7d 100644 --- a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx +++ b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx @@ -23,6 +23,7 @@ #include <rtl/ustring.hxx> #include <com/sun/star/util/DateTime.hpp> #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp> +#include <com/sun/star/uno/Sequence.h> #include <vector> @@ -83,6 +84,8 @@ struct SignatureInformation OUString ouDescriptionPropertyId; /// OOXML certificate SHA-256 digest, empty for ODF. OUString ouCertDigest; + /// A full OOXML signguature for unchanged roundtrip, empty for ODF. + css::uno::Sequence<sal_Int8> aSignatureBytes; SignatureInformation( sal_Int32 nId ) { diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx index 59d5ec4..2b05621 100644 --- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx +++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx @@ -44,6 +44,7 @@ #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/embed/StorageFormats.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/io/XSeekable.hpp> #include <tools/date.hxx> #include <tools/time.hxx> @@ -207,14 +208,21 @@ void XMLSignatureHelper::ExportOOXMLSignature(uno::Reference<embed::XStorage> xR { sal_Int32 nOpenMode = embed::ElementModes::READWRITE; uno::Reference<io::XOutputStream> xOutputStream(xSignatureStorage->openStreamElement("sig" + OUString::number(nSignatureIndex) + ".xml", nOpenMode), uno::UNO_QUERY); - uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx); - xSaxWriter->setOutputStream(xOutputStream); - xSaxWriter->startDocument(); - uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY); - mpXSecController->exportOOXMLSignature(xRootStorage, xDocumentHandler, rInformation); + if (rInformation.aSignatureBytes.hasElements()) + // This is a signature roundtrip, just write back the signature as-is. + xOutputStream->writeBytes(rInformation.aSignatureBytes); + else + { + uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx); + xSaxWriter->setOutputStream(xOutputStream); + xSaxWriter->startDocument(); - xSaxWriter->endDocument(); + uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY); + mpXSecController->exportOOXMLSignature(xRootStorage, xDocumentHandler, rInformation); + + xSaxWriter->endDocument(); + } } bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler ) @@ -403,6 +411,19 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embe uno::Reference<io::XInputStream> xInputStream(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY); if (!ReadAndVerifySignatureStorageStream(xInputStream)) return false; + + // Store the contents of the stream as is, in case we need to write it back later. + xInputStream.clear(); + xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY); + if (xPropertySet.is()) + { + sal_Int64 nSize = 0; + xPropertySet->getPropertyValue("Size") >>= nSize; + uno::Sequence<sal_Int8> aData; + xInputStream->readBytes(aData, nSize); + mpXSecController->setSignatureBytes(aData); + } } } } diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx index 1b52072..595ea82 100644 --- a/xmlsecurity/source/helper/xsecctl.hxx +++ b/xmlsecurity/source/helper/xsecctl.hxx @@ -390,7 +390,10 @@ private: void setDate( OUString& ouDate ); void setDescription(const OUString& rDescription); void setCertDigest(const OUString& rCertDigest); +public: + void setSignatureBytes(const css::uno::Sequence<sal_Int8>& rBytes); +private: void setId( OUString& ouId ); void setPropertyId( OUString& ouPropertyId ); diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx index a7e2183..bef6fa7 100644 --- a/xmlsecurity/source/helper/xsecverify.cxx +++ b/xmlsecurity/source/helper/xsecverify.cxx @@ -274,6 +274,15 @@ void XSecController::setDescription(const OUString& rDescription) rInformation.signatureInfor.ouDescription = rDescription; } +void XSecController::setSignatureBytes(const uno::Sequence<sal_Int8>& rBytes) +{ + if (m_vInternalSignatureInformations.empty()) + return; + + InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back(); + rInformation.signatureInfor.aSignatureBytes = rBytes; +} + void XSecController::setCertDigest(const OUString& rCertDigest) { if (m_vInternalSignatureInformations.empty()) commit b9fb9062a999b3342010e6d26919e6d49065abb1 Author: Miklos Vajna <[email protected]> Date: Fri Mar 4 09:02:02 2016 +0100 sw, sd: indentation fixes Change-Id: I4813488d94e6ae2877cdaf39a3849bccb83c389d diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 8ee50a3..cea486e 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -511,7 +511,8 @@ void SdTiledRenderingTest::testSearchAllFollowedBySearch() CPPUNIT_ASSERT_EQUAL(OString("match"), pXImpressDocument->getTextSelection("text/plain;charset=utf-8", aUsedFormat)); } -namespace { +namespace +{ std::vector<OUString> getCurrentParts(SdXImpressDocument* pDocument) { @@ -537,12 +538,14 @@ void SdTiledRenderingTest::testInsertDeletePage() SdDrawDocument* pDoc = pXImpressDocument->GetDocShell()->GetDoc(); CPPUNIT_ASSERT(pDoc); - std::vector<OUString> aInserted = { + std::vector<OUString> aInserted = + { "Slide 1", "Slide 2", "Slide 3", "Slide 4", "Slide 5", "Slide 6", "Slide 7", "Slide 8", "Slide 9", "Slide 10", "Slide 11" }; - std::vector<OUString> aDeleted = { + std::vector<OUString> aDeleted = + { "Slide 1" }; diff --git a/sw/source/core/doc/DocumentStylePoolManager.cxx b/sw/source/core/doc/DocumentStylePoolManager.cxx index d52f9a680..6b255e9 100644 --- a/sw/source/core/doc/DocumentStylePoolManager.cxx +++ b/sw/source/core/doc/DocumentStylePoolManager.cxx @@ -1270,7 +1270,7 @@ SwFormat* DocumentStylePoolManager::GetFormatFromPool( sal_uInt16 nId ) ::lcl_SetDfltFont( DefaultFontType::FIXED, aSet ); } break; - case RES_POOLCHR_VERT_NUM: + case RES_POOLCHR_VERT_NUM: aSet.Put( SvxCharRotateItem( 900, false, RES_CHRATR_ROTATE ) ); break; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
