[Libreoffice-commits] core.git: xmlsecurity/inc xmlsecurity/qa xmlsecurity/source

Tor Lillqvist tml at collabora.com
Thu Nov 10 15:55:28 UTC 2016


 xmlsecurity/inc/documentsignaturehelper.hxx            |    8 ++
 xmlsecurity/inc/documentsignaturemanager.hxx           |    2 
 xmlsecurity/inc/sigstruct.hxx                          |    2 
 xmlsecurity/inc/xmlsignaturehelper.hxx                 |    5 +
 xmlsecurity/qa/unit/signing/signing.cxx                |    2 
 xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx |    2 
 xmlsecurity/source/helper/documentsignaturehelper.cxx  |   58 +++++++++++++++
 xmlsecurity/source/helper/documentsignaturemanager.cxx |    8 +-
 xmlsecurity/source/helper/ooxmlsecexporter.cxx         |   61 +---------------
 xmlsecurity/source/helper/xmlsignaturehelper.cxx       |    5 -
 xmlsecurity/source/helper/xsecctl.cxx                  |   63 ++++++++++++++++-
 xmlsecurity/source/helper/xsecctl.hxx                  |    3 
 xmlsecurity/source/helper/xsecparser.cxx               |   21 ++++-
 xmlsecurity/source/helper/xsecparser.hxx               |    2 
 xmlsecurity/source/helper/xsecsign.cxx                 |    4 -
 15 files changed, 170 insertions(+), 76 deletions(-)

New commits:
commit 59547a54958914f57f5a9bcff6434c3acca042f6
Author: Tor Lillqvist <tml at collabora.com>
Date:   Wed Nov 9 15:14:03 2016 +0200

    More work in progress on XAdES compliant ODF signing
    
    Pass an XAdES flag to a couple more functions and adapt to that.
    
    Factor out writeDigestMethod() and writeSignedProperties() from
    OOXMLSecExporter::Impl to DocumentSignatureHelper and use them in an
    additional place.
    
    Write xd:UnsignedProperties with EncapsulatedX509Certificate. Probably
    much more work needed.
    
    Change-Id: I2a0cd1db6dd487b9c7ba256ad29473de3d271cd8

diff --git a/xmlsecurity/inc/documentsignaturehelper.hxx b/xmlsecurity/inc/documentsignaturehelper.hxx
index 50c8d43..10268e7 100644
--- a/xmlsecurity/inc/documentsignaturehelper.hxx
+++ b/xmlsecurity/inc/documentsignaturehelper.hxx
@@ -21,6 +21,7 @@
 #define INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREHELPER_HXX
 
 #include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
 #include <rtl/ustring.hxx>
 #include "sigstruct.hxx"
 #include "xmlsecuritydllapi.h"
@@ -92,6 +93,13 @@ namespace DocumentSignatureHelper
 
     /// In case the storage is OOXML, prepend a leading '/' and append content type to the element URIs.
     void AppendContentTypes(const css::uno::Reference<css::embed::XStorage>& xStorage, std::vector<OUString>& rElements);
+
+    void writeDigestMethod(
+        const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler);
+    void writeSignedProperties(
+        const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
+        const SignatureInformation& signatureInfo,
+        const OUString& sDate);
 };
 
 #endif // INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREHELPER_HXX
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index 7062303..08bdcf6 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -65,7 +65,7 @@ public:
     /// Read signatures from either a temp stream or the real storage.
     void read(bool bUseTempStream, bool bCacheLastSignature = true);
     /// Write signatures back to the persistent storage.
-    void write();
+    void write(bool bXAdESCompliantIfODF);
     /// Lazy creation of PDF helper.
     PDFSignatureHelper& getPDFSignatureHelper();
 #if 0
diff --git a/xmlsecurity/inc/sigstruct.hxx b/xmlsecurity/inc/sigstruct.hxx
index 1b6cdb8..85cf085 100644
--- a/xmlsecurity/inc/sigstruct.hxx
+++ b/xmlsecurity/inc/sigstruct.hxx
@@ -96,7 +96,7 @@ struct SignatureInformation
     OUString ouDescription;
     /// The Id attribute of the <SignatureProperty> element that contains the <dc:description>.
     OUString ouDescriptionPropertyId;
-    /// OOXML certificate SHA-256 digest, empty for ODF.
+    /// OOXML certificate SHA-256 digest, empty for ODF except when doing XAdES signature.
     OUString ouCertDigest;
     /// A full OOXML signguature for unchanged roundtrip, empty for ODF.
     css::uno::Sequence<sal_Int8> aSignatureBytes;
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index c2a163b..89eeb55 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -171,7 +171,10 @@ public:
     //     will be very useful, see Mission 3 in the new "multisigdemo" program   :-)
     css::uno::Reference< css::xml::sax::XWriter> CreateDocumentHandlerWithHeader( const css::uno::Reference< css::io::XOutputStream >& xOutputStream );
     static void CloseDocumentHandler( const css::uno::Reference< css::xml::sax::XDocumentHandler>& xDocumentHandler );
-    static void ExportSignature( const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler, const SignatureInformation& signatureInfo );
+    static void ExportSignature(
+        const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
+        const SignatureInformation& signatureInfo,
+        bool bXAdESCompliantIfODF );
 
     /// Read and verify OOXML signatures.
     bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bCacheLastSignature = true);
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index bad29211..e14b3a7 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -324,7 +324,7 @@ void SigningTest::testOOXMLRemoveAll()
     CPPUNIT_ASSERT(xCertificate.is());
     aManager.remove(0);
     aManager.read(/*bUseTempStream=*/true);
-    aManager.write();
+    aManager.write(/*bXAdESCompliantIfODF=*/false);
 
     // Make sure that the signature count is zero and the whole signature storage is removed completely.
     CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(0), rInformations.size());
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 19ea5d0..c48c5ad 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -357,7 +357,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureHighlightHdl, SvTreeListBox*,
 
 IMPL_LINK_NOARG(DigitalSignaturesDialog, OKButtonHdl, Button*, void)
 {
-    maSignatureManager.write();
+    maSignatureManager.write(m_bXAdESCompliant);
 
     EndDialog(RET_OK);
 }
diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx
index 3909c4c..103f5c8 100644
--- a/xmlsecurity/source/helper/documentsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx
@@ -36,7 +36,11 @@
 #include <comphelper/processfactory.hxx>
 #include <tools/debug.hxx>
 #include <osl/diagnose.h>
+#include <rtl/ref.hxx>
 #include <rtl/uri.hxx>
+#include <xmloff/attrlist.hxx>
+
+#include "xsecctl.hxx"
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -522,4 +526,58 @@ OUString DocumentSignatureHelper::GetPackageSignatureDefaultStreamName()
     return OUString(  "packagesignatures.xml"  );
 }
 
+void DocumentSignatureHelper::writeDigestMethod(
+    const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler)
+{
+    rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
+    pAttributeList->AddAttribute("Algorithm", ALGO_XMLDSIGSHA256);
+    xDocumentHandler->startElement("DigestMethod", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
+    xDocumentHandler->endElement("DigestMethod");
+}
+
+void DocumentSignatureHelper::writeSignedProperties(
+    const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
+    const SignatureInformation& signatureInfo,
+    const OUString& sDate)
+{
+    {
+        rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
+        pAttributeList->AddAttribute("Id", "idSignedProperties");
+        xDocumentHandler->startElement("xd:SignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
+    }
+
+    xDocumentHandler->startElement("xd:SignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->startElement("xd:SigningTime", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->characters(sDate);
+    xDocumentHandler->endElement("xd:SigningTime");
+    xDocumentHandler->startElement("xd:SigningCertificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->startElement("xd:Cert", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->startElement("xd:CertDigest", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    writeDigestMethod(xDocumentHandler);
+
+    xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    assert(!signatureInfo.ouCertDigest.isEmpty());
+    xDocumentHandler->characters(signatureInfo.ouCertDigest);
+    xDocumentHandler->endElement("DigestValue");
+
+    xDocumentHandler->endElement("xd:CertDigest");
+    xDocumentHandler->startElement("xd:IssuerSerial", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->startElement("X509IssuerName", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->characters(signatureInfo.ouX509IssuerName);
+    xDocumentHandler->endElement("X509IssuerName");
+    xDocumentHandler->startElement("X509SerialNumber", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->characters(signatureInfo.ouX509SerialNumber);
+    xDocumentHandler->endElement("X509SerialNumber");
+    xDocumentHandler->endElement("xd:IssuerSerial");
+    xDocumentHandler->endElement("xd:Cert");
+    xDocumentHandler->endElement("xd:SigningCertificate");
+    xDocumentHandler->startElement("xd:SignaturePolicyIdentifier", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->startElement("xd:SignaturePolicyImplied", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    xDocumentHandler->endElement("xd:SignaturePolicyImplied");
+    xDocumentHandler->endElement("xd:SignaturePolicyIdentifier");
+    xDocumentHandler->endElement("xd:SignedSignatureProperties");
+
+    xDocumentHandler->endElement("xd:SignedProperties");
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 2afdcc9..2e055dd 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -308,7 +308,7 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>&
         uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY_THROW);
         std::size_t nInfos = maCurrentSignatureInformations.size();
         for (std::size_t n = 0; n < nInfos; n++)
-            XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n]);
+            XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n], bXAdESCompliantIfODF);
 
         // Create a new one...
         maSignatureHelper.CreateAndWriteSignature(xDocumentHandler, bXAdESCompliantIfODF);
@@ -378,7 +378,7 @@ void DocumentSignatureManager::remove(sal_uInt16 nPosition)
         uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY_THROW);
         std::size_t nInfos = maCurrentSignatureInformations.size();
         for (std::size_t n = 0 ; n < nInfos ; ++n)
-            XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n]);
+            XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n], false /* ??? */);
 
         XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler);
     }
@@ -435,7 +435,7 @@ void DocumentSignatureManager::read(bool bUseTempStream, bool bCacheLastSignatur
     }
 }
 
-void DocumentSignatureManager::write()
+void DocumentSignatureManager::write(bool bXAdESCompliantIfODF)
 {
     if (!mxStore.is())
     {
@@ -455,7 +455,7 @@ void DocumentSignatureManager::write()
         uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY_THROW);
         std::size_t nInfos = maCurrentSignatureInformations.size();
         for (std::size_t n = 0 ; n < nInfos ; ++n)
-            XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n]);
+            XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n], bXAdESCompliantIfODF);
 
         XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler);
 
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 11d5ee8..34843a5 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -22,7 +22,8 @@
 #include <unotools/datetime.hxx>
 #include <xmloff/attrlist.hxx>
 
-#include <xsecctl.hxx>
+#include "documentsignaturehelper.hxx"
+#include "xsecctl.hxx"
 
 using namespace com::sun::star;
 
@@ -53,7 +54,6 @@ struct OOXMLSecExporter::Impl
     void writeSignedInfo();
     void writeCanonicalizationMethod();
     void writeCanonicalizationTransform();
-    void writeDigestMethod();
     void writeSignatureMethod();
     void writeSignedInfoReferences();
     void writeSignatureValue();
@@ -69,7 +69,6 @@ struct OOXMLSecExporter::Impl
     /// Writes <SignatureInfoV1>.
     void writeSignatureInfo();
     void writePackageSignature();
-    void writeSignedProperties();
 };
 
 bool OOXMLSecExporter::Impl::isOOXMLBlacklist(const OUString& rStreamName)
@@ -135,14 +134,6 @@ void OOXMLSecExporter::Impl::writeCanonicalizationTransform()
 
 }
 
-void OOXMLSecExporter::Impl::writeDigestMethod()
-{
-    rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
-    pAttributeList->AddAttribute("Algorithm", ALGO_XMLDSIGSHA256);
-    m_xDocumentHandler->startElement("DigestMethod", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
-    m_xDocumentHandler->endElement("DigestMethod");
-}
-
 void OOXMLSecExporter::Impl::writeSignatureMethod()
 {
     rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
@@ -174,7 +165,7 @@ void OOXMLSecExporter::Impl::writeSignedInfoReferences()
                 m_xDocumentHandler->endElement("Transforms");
             }
 
-            writeDigestMethod();
+            DocumentSignatureHelper::writeDigestMethod(m_xDocumentHandler);
             m_xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
             m_xDocumentHandler->characters(rReference.ouDigestValue);
             m_xDocumentHandler->endElement("DigestValue");
@@ -332,7 +323,7 @@ void OOXMLSecExporter::Impl::writeManifestReference(const SignatureReferenceInfo
         m_xDocumentHandler->endElement("Transforms");
     }
 
-    writeDigestMethod();
+    DocumentSignatureHelper::writeDigestMethod(m_xDocumentHandler);
     m_xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
     m_xDocumentHandler->characters(rReference.ouDigestValue);
     m_xDocumentHandler->endElement("DigestValue");
@@ -421,54 +412,12 @@ void OOXMLSecExporter::Impl::writePackageSignature()
         m_xDocumentHandler->startElement("xd:QualifyingProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
     }
 
-    writeSignedProperties();
+    DocumentSignatureHelper::writeSignedProperties(m_xDocumentHandler, m_rInformation, m_aSignatureTimeValue);
 
     m_xDocumentHandler->endElement("xd:QualifyingProperties");
     m_xDocumentHandler->endElement("Object");
 }
 
-void OOXMLSecExporter::Impl::writeSignedProperties()
-{
-    {
-        rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
-        pAttributeList->AddAttribute("Id", "idSignedProperties");
-        m_xDocumentHandler->startElement("xd:SignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
-    }
-
-    m_xDocumentHandler->startElement("xd:SignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->startElement("xd:SigningTime", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->characters(m_aSignatureTimeValue);
-    m_xDocumentHandler->endElement("xd:SigningTime");
-    m_xDocumentHandler->startElement("xd:SigningCertificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->startElement("xd:Cert", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->startElement("xd:CertDigest", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    writeDigestMethod();
-
-    m_xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    assert(!m_rInformation.ouCertDigest.isEmpty());
-    m_xDocumentHandler->characters(m_rInformation.ouCertDigest);
-    m_xDocumentHandler->endElement("DigestValue");
-
-    m_xDocumentHandler->endElement("xd:CertDigest");
-    m_xDocumentHandler->startElement("xd:IssuerSerial", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->startElement("X509IssuerName", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->characters(m_rInformation.ouX509IssuerName);
-    m_xDocumentHandler->endElement("X509IssuerName");
-    m_xDocumentHandler->startElement("X509SerialNumber", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->characters(m_rInformation.ouX509SerialNumber);
-    m_xDocumentHandler->endElement("X509SerialNumber");
-    m_xDocumentHandler->endElement("xd:IssuerSerial");
-    m_xDocumentHandler->endElement("xd:Cert");
-    m_xDocumentHandler->endElement("xd:SigningCertificate");
-    m_xDocumentHandler->startElement("xd:SignaturePolicyIdentifier", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->startElement("xd:SignaturePolicyImplied", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
-    m_xDocumentHandler->endElement("xd:SignaturePolicyImplied");
-    m_xDocumentHandler->endElement("xd:SignaturePolicyIdentifier");
-    m_xDocumentHandler->endElement("xd:SignedSignatureProperties");
-
-    m_xDocumentHandler->endElement("xd:SignedProperties");
-}
-
 OOXMLSecExporter::OOXMLSecExporter(const uno::Reference<uno::XComponentContext>& xComponentContext,
                                    const uno::Reference<embed::XStorage>& xRootStorage,
                                    const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index d41d0fb..82101fa 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -181,9 +181,10 @@ void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XD
 
 void XMLSignatureHelper::ExportSignature(
     const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler,
-    const SignatureInformation& signatureInfo )
+    const SignatureInformation& signatureInfo,
+    bool bXAdESCompliantIfODF )
 {
-    XSecController::exportSignature(xDocumentHandler, signatureInfo);
+    XSecController::exportSignature(xDocumentHandler, signatureInfo, bXAdESCompliantIfODF);
 }
 
 void XMLSignatureHelper::ExportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<embed::XStorage>& xSignatureStorage, const SignatureInformation& rInformation, int nSignatureIndex)
diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx
index 380adf7..81ea2ec 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -19,6 +19,7 @@
 
 
 #include "xsecctl.hxx"
+#include "documentsignaturehelper.hxx"
 #include <algorithm>
 #include <initializer_list>
 #include <tools/debug.hxx>
@@ -564,9 +565,45 @@ void XSecController::endMission()
     }
 }
 
+namespace
+{
+void writeUnsignedProperties(
+    const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
+    const SignatureInformation& signatureInfo)
+{
+    {
+        rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
+        pAttributeList->AddAttribute("Id", "idUnsignedProperties");
+        xDocumentHandler->startElement("xd:UnsignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
+    }
+
+    {
+        xDocumentHandler->startElement("xd:UnsignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+
+        {
+            xDocumentHandler->startElement("xd:CertificateValues", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+
+            {
+                xDocumentHandler->startElement("xd:EncapsulatedX509Certificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+                xDocumentHandler->characters(signatureInfo.ouX509Certificate);
+                xDocumentHandler->endElement("xd:EncapsulatedX509Certificate");
+            }
+
+            xDocumentHandler->endElement("xd:CertificateValues");
+        }
+
+        xDocumentHandler->endElement("xd:UnsignedSignatureProperties");
+    }
+
+    xDocumentHandler->endElement("xd:UnsignedProperties");
+}
+
+}
+
 void XSecController::exportSignature(
     const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
-    const SignatureInformation& signatureInfo )
+    const SignatureInformation& signatureInfo,
+    bool bXAdESCompliantIfODF )
 /****** XSecController/exportSignature ****************************************
  *
  *   NAME
@@ -750,6 +787,8 @@ void XSecController::exportSignature(
         }
         xDocumentHandler->endElement( "KeyInfo" );
 
+        OUString sDate;
+
         /* Write Object element */
         xDocumentHandler->startElement(
             "Object",
@@ -794,7 +833,8 @@ void XSecController::exportSignature(
                     {
                         buffer = utl::toISO8601(signatureInfo.stDateTime);
                     }
-                    xDocumentHandler->characters( buffer.makeStringAndClear() );
+                    sDate = buffer.makeStringAndClear();
+                    xDocumentHandler->characters( sDate );
 
                     xDocumentHandler->endElement(
                         "dc:date");
@@ -827,6 +867,25 @@ void XSecController::exportSignature(
             xDocumentHandler->endElement( "SignatureProperties" );
         }
         xDocumentHandler->endElement( "Object" );
+
+        //  In XAdES, write another Object element for the QualifyingProperties
+        if (bXAdESCompliantIfODF)
+        {
+            pAttributeList =  new SvXMLAttributeList();
+            pAttributeList->AddAttribute("xmlns:xd", NS_XD);
+            xDocumentHandler->startElement(
+                "Object",
+                cssu::Reference< cssxs::XAttributeList > (pAttributeList));
+            {
+                xDocumentHandler->startElement(
+                    "xd:QualifyingProperties",
+                    cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+                DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate);
+                writeUnsignedProperties(xDocumentHandler, signatureInfo);
+                xDocumentHandler->endElement( "xd:QualifyingProperties" );
+            }
+            xDocumentHandler->endElement( "Object" );
+        }
     }
     xDocumentHandler->endElement( "Signature" );
 }
diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx
index e2d606f..3271f45 100644
--- a/xmlsecurity/source/helper/xsecctl.hxx
+++ b/xmlsecurity/source/helper/xsecctl.hxx
@@ -348,7 +348,8 @@ public:
 
     static void exportSignature(
         const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
-        const SignatureInformation& signatureInfo );
+        const SignatureInformation& signatureInfo,
+        bool bXAdESCompliantIfODF );
 
 
     /*
diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx
index c169498..bb2c097 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -33,6 +33,7 @@ XSecParser::XSecParser(XSecController* pXSecController,
     : m_bInX509IssuerName(false)
     , m_bInX509SerialNumber(false)
     , m_bInX509Certificate(false)
+    , m_bInCertDigest(false)
     , m_bInDigestValue(false)
     , m_bInSignatureValue(false)
     , m_bInDate(false)
@@ -177,11 +178,16 @@ void SAL_CALL XSecParser::startElement(
             m_ouSignatureValue.clear();
             m_bInSignatureValue = true;
         }
-        else if (aName == "DigestValue")
+        else if (aName == "DigestValue" && !m_bInCertDigest)
         {
             m_ouDigestValue.clear();
             m_bInDigestValue = true;
         }
+        else if (aName == "xd:CertDigest")
+        {
+            m_ouCertDigest.clear();
+            m_bInCertDigest = true;
+        }
         else if ( aName == "SignatureProperty" )
         {
             if (!ouIdAttr.isEmpty())
@@ -225,7 +231,7 @@ void SAL_CALL XSecParser::endElement( const OUString& aName )
 {
     try
     {
-        if (aName == "DigestValue")
+        if (aName == "DigestValue" && !m_bInCertDigest)
         {
             m_bInDigestValue = false;
         }
@@ -266,6 +272,11 @@ void SAL_CALL XSecParser::endElement( const OUString& aName )
             m_pXSecController->setX509Certificate( m_ouX509Certificate );
             m_bInX509Certificate = false;
         }
+        else if (aName == "xd:CertDigest")
+        {
+            m_pXSecController->setCertDigest( m_ouCertDigest );
+            m_bInX509Certificate = false;
+        }
         else if (aName == "dc:date")
         {
             m_pXSecController->setDate( m_ouDate );
@@ -316,7 +327,7 @@ void SAL_CALL XSecParser::characters( const OUString& aChars )
     {
         m_ouSignatureValue += aChars;
     }
-    else if (m_bInDigestValue)
+    else if (m_bInDigestValue && !m_bInCertDigest)
     {
         m_ouDigestValue += aChars;
     }
@@ -328,6 +339,10 @@ void SAL_CALL XSecParser::characters( const OUString& aChars )
     {
         m_ouDescription += aChars;
     }
+    else if (m_bInCertDigest)
+    {
+        m_ouCertDigest += aChars;
+    }
 
     if (m_xNextHandler.is())
     {
diff --git a/xmlsecurity/source/helper/xsecparser.hxx b/xmlsecurity/source/helper/xsecparser.hxx
index 530fa9a..37d8789 100644
--- a/xmlsecurity/source/helper/xsecparser.hxx
+++ b/xmlsecurity/source/helper/xsecparser.hxx
@@ -57,6 +57,7 @@ private:
     OUString m_ouX509IssuerName;
     OUString m_ouX509SerialNumber;
     OUString m_ouX509Certificate;
+    OUString m_ouCertDigest;
     OUString m_ouDigestValue;
     OUString m_ouSignatureValue;
     OUString m_ouDate;
@@ -69,6 +70,7 @@ private:
     bool m_bInX509IssuerName;
     bool m_bInX509SerialNumber;
     bool m_bInX509Certificate;
+    bool m_bInCertDigest;
     bool m_bInDigestValue;
     bool m_bInSignatureValue;
     bool m_bInDate;
diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx
index a994174..a838a9c 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -289,8 +289,6 @@ bool XSecController::WriteSignature(
     const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
     bool bXAdESCompliantIfODF )
 {
-    (void) bXAdESCompliantIfODF;
-
     bool rc = false;
 
     SAL_WARN_IF( !xDocumentHandler.is(), "xmlsecurity.helper", "I really need a document handler!" );
@@ -327,7 +325,7 @@ bool XSecController::WriteSignature(
                 // 0 is not a documented value of embed::StorageFormats, ugh
                 isi.xReferenceResolvedListener = prepareSignatureToWrite( isi, 0, bXAdESCompliantIfODF );
 
-                exportSignature( xSEKHandler, isi.signatureInfor );
+                exportSignature( xSEKHandler, isi.signatureInfor, bXAdESCompliantIfODF );
             }
 
             m_bIsSAXEventKeeperSticky = false;


More information about the Libreoffice-commits mailing list