[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - 4 commits - include/oox include/sal offapi/com oox/source writerfilter/source xmloff/source xmlsecurity/inc xmlsecurity/qa xmlsecurity/source

Regina Henschel rb.henschel at t-online.de
Mon Nov 6 09:23:21 UTC 2017


 include/oox/vml/vmlshape.hxx                                  |    7 
 include/sal/log-areas.dox                                     |    1 
 offapi/com/sun/star/security/DocumentSignatureInformation.idl |   17 ++
 oox/source/vml/vmlshape.cxx                                   |   74 ++++++++--
 oox/source/vml/vmlshapecontext.cxx                            |    7 
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx         |    7 
 xmloff/source/text/txtimp.cxx                                 |    2 
 xmloff/source/text/txtparae.cxx                               |    2 
 xmlsecurity/inc/xmlsecurity/sigstruct.hxx                     |    6 
 xmlsecurity/qa/unit/signing/data/signatureline.docx           |binary
 xmlsecurity/qa/unit/signing/signing.cxx                       |   27 +++
 xmlsecurity/source/component/documentdigitalsignatures.cxx    |    9 +
 xmlsecurity/source/helper/ooxmlsecparser.cxx                  |   53 +++++++
 xmlsecurity/source/helper/ooxmlsecparser.hxx                  |    6 
 xmlsecurity/source/helper/xsecctl.hxx                         |    3 
 xmlsecurity/source/helper/xsecverify.cxx                      |   64 ++++++++
 16 files changed, 267 insertions(+), 18 deletions(-)

New commits:
commit 11c842f450561953b11f3bc9a44404c6e83682ea
Author: Regina Henschel <rb.henschel at t-online.de>
Date:   Thu Oct 26 14:41:38 2017 +0200

    tdf#113367 Change namespace from svg to draw for attr transform
    
    The new feature of rotating images in Writer first time triggers the
    export of the attribute transform. So now it becomes visible, that
    it has the wrong namespace, see ODF 19.228 part 1.
    
    Change-Id: I00d5e6a12bd564e814679e8be862c7d08baae956
    Reviewed-on: https://gerrit.libreoffice.org/43890
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index 08dafafdcbfe..3c19db3b8a1a 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -364,7 +364,7 @@ static const SvXMLTokenMapEntry aTextFrameAttrTokenMap[] =
     { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_TEXT_FRAME_HREF },
     { XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_TEXT_FRAME_FILTER_NAME },
     { XML_NAMESPACE_DRAW, XML_ZINDEX, XML_TOK_TEXT_FRAME_Z_INDEX },
-    { XML_NAMESPACE_SVG, XML_TRANSFORM, XML_TOK_TEXT_FRAME_TRANSFORM },
+    { XML_NAMESPACE_DRAW, XML_TRANSFORM, XML_TOK_TEXT_FRAME_TRANSFORM },
     { XML_NAMESPACE_DRAW, XML_CLASS_ID, XML_TOK_TEXT_FRAME_CLASS_ID },
     { XML_NAMESPACE_DRAW,   XML_CODE,           XML_TOK_TEXT_FRAME_CODE },
     { XML_NAMESPACE_DRAW,   XML_OBJECT,         XML_TOK_TEXT_FRAME_OBJECT },
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 481d474674aa..a809bf0b758c 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -3068,7 +3068,7 @@ void XMLTextParagraphExport::_exportTextGraphic(
         sRet.append( '(' );
         ::sax::Converter::convertNumber( sRet, (sal_Int32)nVal );
         sRet.append( ')' );
-        GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_TRANSFORM,
+        GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_TRANSFORM,
                                   sRet.makeStringAndClear() );
     }
 
commit 637cdd25bd1b5268ddba0f23be6701538c73fc62
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Fri Nov 3 18:42:44 2017 +0100

    Only downcast to OOXMLFastContextHandlerShape when actually necessary
    
    After bd3c5c4c234e3dc6b89cd235321945a41a08d562 "[API CHANGE] tdf#65393 Import
    signature line images from ooxml", UBSan CppunitTest_chart2_export had started
    to fail with
    
    > writerfilter/source/ooxml/OOXMLFastContextHandler.cxx:1898:25: runtime error: downcast of address 0x61200070a440 which does not point to an object of type 'writerfilter::ooxml::OOXMLFastContextHandlerShape'
    > 0x61200070a440: note: object is of type 'writerfilter::ooxml::OOXMLFastContextHandlerWrapper'
    >  0e 10 00 20  50 86 4a 00 a2 7f 00 00  01 00 00 00 be be be be  00 00 00 00 00 00 00 00  00 00 00 00
    >               ^~~~~~~~~~~~~~~~~~~~~~~
    >               vptr for 'writerfilter::ooxml::OOXMLFastContextHandlerWrapper'
    
    Change-Id: I028ef619766466e8cd9bb0ca09174b926fc6d23c

diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index b3eae0abd171..d3a6a02d3ab6 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1844,11 +1844,10 @@ OOXMLFastContextHandlerWrapper::lcl_createFastChildContext
     // here until we need a more generic solution.
     bool bIsWrap = Element == static_cast<sal_Int32>(NMSP_vmlWord | XML_wrap);
     bool bIsSignatureLine = Element == static_cast<sal_Int32>(NMSP_vmlOffice | XML_signatureline);
-    bool bIsShapeSent = static_cast<OOXMLFastContextHandlerShape*>(mpParent)->isShapeSent();
     bool bSkipImages = getDocument()->IsSkipImages() && oox::getNamespace(Element) == static_cast<sal_Int32>(NMSP_dml) &&
         !((oox::getBaseToken(Element) == XML_linkedTxbx) || (oox::getBaseToken(Element) == XML_txbx));
 
-    if ( bInNamespaces && ((!bIsWrap && !bIsSignatureLine) || bIsShapeSent) )
+    if ( bInNamespaces && ((!bIsWrap && !bIsSignatureLine) || static_cast<OOXMLFastContextHandlerShape*>(mpParent)->isShapeSent()) )
         xResult.set(OOXMLFactory::createFastChildContextFromStart(this, Element));
     else if (mxContext.is()  && !bSkipImages)
     {
commit 7ad85dcb6289c8f8bb0cdfe41c5c75ba17e4e48b
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Thu Nov 2 15:47:32 2017 +0100

    tdf#65393 Test for signature line images
    
    Change-Id: I6f37919da5fef0a90fad314019db19e4a5604169

diff --git a/xmlsecurity/qa/unit/signing/data/signatureline.docx b/xmlsecurity/qa/unit/signing/data/signatureline.docx
new file mode 100644
index 000000000000..e1dae66989d3
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/signatureline.docx differ
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index d2a9f1741f34..132ddaf12fa9 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -23,6 +23,8 @@
 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
 #include <com/sun/star/io/TempFile.hpp>
 #include <com/sun/star/packages/manifest/ManifestReader.hpp>
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
 
 #include <comphelper/processfactory.hxx>
 #include <sax/tools/converter.hxx>
@@ -78,6 +80,8 @@ public:
     void testOOXMLRemoveAll();
     void test96097Calc();
     void test96097Doc();
+    /// Test importing of signature line images
+    void testSignatureLineImages();
 
     CPPUNIT_TEST_SUITE(SigningTest);
     CPPUNIT_TEST(testDescription);
@@ -92,6 +96,7 @@ public:
     CPPUNIT_TEST(testOOXMLRemoveAll);
     CPPUNIT_TEST(test96097Calc);
     CPPUNIT_TEST(test96097Doc);
+    CPPUNIT_TEST(testSignatureLineImages);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -475,6 +480,28 @@ void SigningTest::test96097Doc()
     }
 }
 
+void SigningTest::testSignatureLineImages()
+{
+    // Given: A document (docx) with a signature line and a valid signature
+    uno::Reference< security::XDocumentDigitalSignatures > xSignatures(
+        security::DocumentDigitalSignatures::createWithVersion(
+            comphelper::getProcessComponentContext(), "1.2" ) );
+
+    uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+        ZIP_STORAGE_FORMAT_STRING, m_directories.getURLFromSrc(DATA_DIRECTORY) + "signatureline.docx",
+         embed::ElementModes::READ);
+    CPPUNIT_ASSERT(xStorage.is());
+
+    uno::Sequence< security::DocumentSignatureInformation > xSignatureInfo =
+        xSignatures->verifyScriptingContentSignatures(xStorage, uno::Reference< io::XInputStream >());
+
+    // The signature should have a valid signature, and signature line with two valid images
+    CPPUNIT_ASSERT(xSignatureInfo[0].SignatureIsValid);
+    CPPUNIT_ASSERT_EQUAL(OUString("{DEE0514B-13E8-4674-A831-46E3CDB18BB4}"), xSignatureInfo[0].SignatureLineId);
+    CPPUNIT_ASSERT(xSignatureInfo[0].ValidSignatureLineImage.is());
+    CPPUNIT_ASSERT(xSignatureInfo[0].InvalidSignatureLineImage.is());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SigningTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit ead1ad35ab69f5327f64f26fc1ac9f74da054182
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Aug 8 16:23:07 2017 +0200

    [API CHANGE] tdf#65393 Import signature line images from ooxml
    
    showing whether the signature behind the signature line is valid or not.
    
    Change-Id: Ia6cca62812019f26d55d234cac767a9b4b7c8175

diff --git a/include/oox/vml/vmlshape.hxx b/include/oox/vml/vmlshape.hxx
index 93f0943bcfe1..2bd7d3d1a86d 100644
--- a/include/oox/vml/vmlshape.hxx
+++ b/include/oox/vml/vmlshape.hxx
@@ -205,6 +205,8 @@ struct ShapeModel
     OUString     maControl1;         ///< Bezier control point 1
     OUString     maControl2;         ///< Bezier control point 2
     OUString     maVmlPath;          ///< VML path for this shape
+    bool         mbIsSignatureLine;  ///< Shape is a signature line
+    OUString     maSignatureId;      ///< ID of the signature
 
     explicit            ShapeModel();
                         ~ShapeModel();
@@ -290,9 +292,12 @@ protected:
                             const css::uno::Reference< css::drawing::XShapes >& rxShapes,
                             const css::awt::Rectangle& rShapeRect ) const override;
     /** Used by both RectangleShape and ComplexShape. */
+    css::uno::Reference<css::drawing::XShape>createEmbeddedPictureObject(
+        const css::uno::Reference< css::drawing::XShapes >& rxShapes,
+        const css::awt::Rectangle& rShapeRect, OUString const & rGraphicPath ) const;
     css::uno::Reference<css::drawing::XShape>createPictureObject(
             const css::uno::Reference< css::drawing::XShapes >& rxShapes,
-            const css::awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const;
+            const css::awt::Rectangle& rShapeRect, OUString& rGraphicUrl ) const;
 
 private:
     OUString     maService;          ///< Name of the UNO shape service.
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index d7b812d37f7a..b595ea0fcf5f 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -220,6 +220,7 @@ certain functionality.
 @li @c oox.ppt - pptx filter
 @li @c oox.shape
 @li @c oox.storage - ZipStorage class
+ at li @c oox.vml - VML
 @li @c oox.xmlstream - XmlStream class
 
 @section forms
diff --git a/offapi/com/sun/star/security/DocumentSignatureInformation.idl b/offapi/com/sun/star/security/DocumentSignatureInformation.idl
index 39012bcd0491..d49669856564 100644
--- a/offapi/com/sun/star/security/DocumentSignatureInformation.idl
+++ b/offapi/com/sun/star/security/DocumentSignatureInformation.idl
@@ -20,6 +20,7 @@
 #ifndef __com_sun_star_security_DocumentSignatureInformation_idl__
 #define __com_sun_star_security_DocumentSignatureInformation_idl__
 
+#include <com/sun/star/graphic/XGraphic.idl>
 #include <com/sun/star/security/XCertificate.idl>
 #include <com/sun/star/security/CertificateValidity.idl>
 
@@ -65,7 +66,21 @@ struct DocumentSignatureInformation
         the fact, that not everything in this document is signed.
     */
     boolean PartialDocumentSignature;
-
+    /**
+     *  The ID of the Signature Line
+     *  @since LibreOffice 6.0
+     */
+    string SignatureLineId;
+    /**
+     *  The Signature Line Image which is shown when the signature is valid
+     *  @since LibreOffice 6.0
+     */
+    com::sun::star::graphic::XGraphic ValidSignatureLineImage;
+    /**
+     *  The Signature Line Image which is shown when the signature is invalid
+     *  @since LibreOffice 6.0
+     */
+    com::sun::star::graphic::XGraphic InvalidSignatureLineImage;
 };
 
 
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 4c5f54c77df0..efcc700d1e4d 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -42,9 +42,11 @@
 #include <com/sun/star/text/XTextContent.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/text/XTextFrame.hpp>
- #include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
 #include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
 #include <rtl/math.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <svx/svdtrans.hxx>
@@ -65,7 +67,9 @@
 #include <svx/unoapi.hxx>
 #include <svx/svdoashp.hxx>
 #include <comphelper/sequence.hxx>
+#include <comphelper/processfactory.hxx>
 #include <comphelper/propertyvalue.hxx>
+#include <comphelper/storagehelper.hxx>
 
 using ::com::sun::star::beans::XPropertySet;
 using ::com::sun::star::uno::Any;
@@ -248,7 +252,8 @@ ClientData::ClientData() :
 {
 }
 
-ShapeModel::ShapeModel()
+ShapeModel::ShapeModel() :
+    mbIsSignatureLine(false)
 {
 }
 
@@ -823,17 +828,23 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
     return xShape;
 }
 
-Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const
+Reference< XShape > SimpleShape::createEmbeddedPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString const & rGraphicPath ) const
+{
+    XmlFilterBase& rFilter = mrDrawing.getFilter();
+    OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
+    return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicUrl);
+}
+
+Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString & rGraphicUrl ) const
 {
     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect );
     if( xShape.is() )
     {
-        XmlFilterBase& rFilter = mrDrawing.getFilter();
-        OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
+
         PropertySet aPropSet( xShape );
-        if( !aGraphicUrl.isEmpty() )
+        if( !rGraphicUrl.isEmpty() )
         {
-            aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
+            aPropSet.setProperty( PROP_GraphicURL, rGraphicUrl );
         }
         uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
         // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
@@ -883,7 +894,7 @@ Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>&
 
     // try to create a picture object
     if(!aGraphicPath.isEmpty())
-        return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
+        return SimpleShape::createEmbeddedPictureObject(rxShapes, rShapeRect, aGraphicPath);
 
     // default: try to create a rectangle shape
     Reference<XShape> xShape = SimpleShape::implConvertAndInsert(rxShapes, rShapeRect);
@@ -1169,15 +1180,60 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes
             return xShape;
     }
 
+
+    if( getShapeModel().mbIsSignatureLine )
+    {
+        // Get the document signatures
+        Reference< security::XDocumentDigitalSignatures > xSignatures(
+            security::DocumentDigitalSignatures::createWithVersion(
+                comphelper::getProcessComponentContext(), "1.2" ) );
+
+        uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+            ZIP_STORAGE_FORMAT_STRING, mrDrawing.getFilter().getFileUrl(), embed::ElementModes::READ);
+        SAL_WARN_IF(!xStorage.is(), "oox.vml", "No xStorage!");
+
+        uno::Sequence< security::DocumentSignatureInformation > xSignatureInfo =
+            xSignatures->verifyScriptingContentSignatures(xStorage, uno::Reference< io::XInputStream >());
+
+        for (int i=0; i<xSignatureInfo.getLength(); i++)
+        {
+            // Try to find matching signature line image - if none exists that is fine,
+            // then the signature line is not digitally signed.
+            if (xSignatureInfo[i].SignatureLineId == getShapeModel().maSignatureId)
+            {
+                OUString aGraphicUrl;
+                if (xSignatureInfo[i].SignatureIsValid)
+                {
+                    // Signature is valid, use the 'valid' image
+                    SAL_WARN_IF(!xSignatureInfo[i].ValidSignatureLineImage.is(), "oox.vml", "No ValidSignatureLineImage!");
+                    aGraphicUrl = rFilter.getGraphicHelper().createGraphicObject(xSignatureInfo[i].ValidSignatureLineImage);
+                }
+                else
+                {
+                    // Signature is invalid, use the 'invalid' image
+                    SAL_WARN_IF(!xSignatureInfo[i].InvalidSignatureLineImage.is(), "oox.vml", "No InvalidSignatureLineImage!");
+                    aGraphicUrl = rFilter.getGraphicHelper().createGraphicObject(xSignatureInfo[i].InvalidSignatureLineImage);
+                }
+                Reference< XShape > xShape = SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicUrl);
+                PropertySet aPropSet(xShape);
+                aPropSet.setProperty(PROP_GraphicURL, aGraphicUrl);
+
+                return xShape;
+            }
+        }
+        // In case no matching signature line is found, render the unsigned signature line image (next if branch)
+    }
+
     // try to create a picture object
     if( !aGraphicPath.isEmpty() )
     {
-        Reference< XShape > xShape = SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
+        Reference< XShape > xShape = SimpleShape::createEmbeddedPictureObject(rxShapes, rShapeRect, aGraphicPath);
         // AS_CHARACTER shape: vertical orientation default is bottom, MSO default is top.
         if ( maTypeModel.maPosition != "absolute" && maTypeModel.maPosition != "relative" )
             PropertySet( xShape ).setAnyProperty( PROP_VertOrient, makeAny(text::VertOrientation::TOP));
         return xShape;
     }
+
     // default: try to create a custom shape
     return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
 }
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index dc654223aca6..a45f779f5237 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -472,6 +472,13 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const Attri
                     "com.sun.star.drawing.RectangleShape");
             mrShapeModel.maLegacyDiagramPath = getFragmentPathFromRelId(rAttribs.getString(XML_id, OUString()));
             break;
+        case O_TOKEN( signatureline ):
+            mrShapeModel.mbIsSignatureLine = true;
+            mrShapeModel.maSignatureId = rAttribs.getString(XML_id, OUString());
+            break;
+        case O_TOKEN( lock ):
+            // TODO
+            break;
     }
     // handle remaining stuff in base class
     return ShapeTypeContext::onCreateContext( nElement, rAttribs );
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index b91276c1b2cc..b3eae0abd171 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1840,13 +1840,15 @@ OOXMLFastContextHandlerWrapper::lcl_createFastChildContext
 
     // We have methods to _add_ individual tokens or whole namespaces to be
     // processed by writerfilter (instead of oox), but we have no method to
-    // filter out a single token. Just hardwire the wrap token here until we
-    // need a more generic solution.
+    // filter out a single token. Just hardwire the 'wrap' and 'signatureline' tokens
+    // here until we need a more generic solution.
     bool bIsWrap = Element == static_cast<sal_Int32>(NMSP_vmlWord | XML_wrap);
+    bool bIsSignatureLine = Element == static_cast<sal_Int32>(NMSP_vmlOffice | XML_signatureline);
+    bool bIsShapeSent = static_cast<OOXMLFastContextHandlerShape*>(mpParent)->isShapeSent();
     bool bSkipImages = getDocument()->IsSkipImages() && oox::getNamespace(Element) == static_cast<sal_Int32>(NMSP_dml) &&
         !((oox::getBaseToken(Element) == XML_linkedTxbx) || (oox::getBaseToken(Element) == XML_txbx));
 
-    if ( bInNamespaces && (!bIsWrap || static_cast<OOXMLFastContextHandlerShape*>(mpParent)->isShapeSent()) )
+    if ( bInNamespaces && ((!bIsWrap && !bIsSignatureLine) || bIsShapeSent) )
         xResult.set(OOXMLFactory::createFastChildContextFromStart(this, Element));
     else if (mxContext.is()  && !bSkipImages)
     {
diff --git a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx
index 5a7df3dedd76..237fbdbffafb 100644
--- a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx
+++ b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx
@@ -21,6 +21,7 @@
 #define INCLUDED_XMLSECURITY_INC_XMLSECURITY_SIGSTRUCT_HXX
 
 #include <rtl/ustring.hxx>
+#include <com/sun/star/graphic/XGraphic.hpp>
 #include <com/sun/star/util/DateTime.hpp>
 #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
 #include <com/sun/star/uno/Sequence.h>
@@ -84,6 +85,11 @@ struct SignatureInformation
     OUString ouDescriptionPropertyId;
     /// OOXML certificate SHA-256 digest, empty for ODF.
     OUString ouCertDigest;
+    /// OOXML Valid and invalid signature images
+    css::uno::Reference<css::graphic::XGraphic> aValidSignatureImage;
+    css::uno::Reference<css::graphic::XGraphic> aInvalidSignatureImage;
+    /// OOXML Signature Line Id, used to map signatures to their respective signature line images.
+    OUString ouSignatureLineId;
     /// A full OOXML signguature for unchanged roundtrip, empty for ODF.
     css::uno::Sequence<sal_Int8> aSignatureBytes;
 
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index f510f9c9ec30..04986328781c 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -358,6 +358,15 @@ DocumentDigitalSignatures::ImplVerifySignatures(
 
             rSigInfo.SignatureIsValid = ( rInfo.nStatus == css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );
 
+            // OOXML Signature line info (ID + Images)
+            if (!rInfo.ouSignatureLineId.isEmpty())
+                rSigInfo.SignatureLineId = rInfo.ouSignatureLineId;
+
+            if (rInfo.aValidSignatureImage.is())
+                rSigInfo.ValidSignatureLineImage = rInfo.aValidSignatureImage;
+
+            if (rInfo.aInvalidSignatureImage.is())
+                rSigInfo.InvalidSignatureLineImage = rInfo.aInvalidSignatureImage;
 
             // OOXML intentionally doesn't sign metadata.
             if ( rSigInfo.SignatureIsValid && aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx
index cc764b69b0be..50099c255418 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx
@@ -22,6 +22,8 @@ OOXMLSecParser::OOXMLSecParser(XSecController* pXSecController)
     ,m_bInX509IssuerName(false)
     ,m_bInX509SerialNumber(false)
     ,m_bInCertDigest(false)
+    ,m_bInValidSignatureImage(false)
+    ,m_bInInvalidSignatureImage(false)
     ,m_bReferenceUnresolved(false)
 {
 }
@@ -118,6 +120,33 @@ throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
         m_aCertDigest.clear();
         m_bInCertDigest = true;
     }
+    else if (rName == "Object")
+    {
+        OUString sId = xAttribs->getValueByName("Id");
+        if (sId == "idValidSigLnImg")
+        {
+            m_aValidSignatureImage.clear();
+            m_bInValidSignatureImage = true;
+        }
+        else if (sId == "idInvalidSigLnImg")
+        {
+            m_aInvalidSignatureImage.clear();
+            m_bInInvalidSignatureImage = true;
+        }
+        else
+        {
+            SAL_INFO("xmlsecurity.ooxml", "Unknown 'Object' child element: " << rName);
+        }
+    }
+    else if (rName == "SetupID")
+    {
+        m_aSignatureLineId.clear();
+        m_bInSignatureLineId = true;
+    }
+    else
+    {
+        SAL_INFO("xmlsecurity.ooxml", "Unknown xml element: " << rName);
+    }
 
     if (m_xNextHandler.is())
         m_xNextHandler->startElement(rName, xAttribs);
@@ -174,6 +203,24 @@ void SAL_CALL OOXMLSecParser::endElement(const OUString& rName) throw (xml::sax:
         m_pXSecController->setCertDigest(m_aCertDigest);
         m_bInCertDigest = false;
     }
+    else if (rName == "Object")
+    {
+        if (m_bInValidSignatureImage)
+        {
+            m_pXSecController->setValidSignatureImage(m_aValidSignatureImage);
+            m_bInValidSignatureImage = false;
+        }
+        else if (m_bInInvalidSignatureImage)
+        {
+            m_pXSecController->setInvalidSignatureImage(m_aInvalidSignatureImage);
+            m_bInInvalidSignatureImage = false;
+        }
+    }
+    else if (rName == "SetupID")
+    {
+        m_pXSecController->setSignatureLineId(m_aSignatureLineId);
+        m_bInSignatureLineId = false;
+    }
 
     if (m_xNextHandler.is())
         m_xNextHandler->endElement(rName);
@@ -197,6 +244,12 @@ void SAL_CALL OOXMLSecParser::characters(const OUString& rChars) throw (xml::sax
         m_aX509SerialNumber += rChars;
     else if (m_bInCertDigest)
         m_aCertDigest += rChars;
+    else if (m_bInValidSignatureImage)
+        m_aValidSignatureImage += rChars;
+    else if (m_bInInvalidSignatureImage)
+        m_aInvalidSignatureImage += rChars;
+    else if (m_bInSignatureLineId)
+        m_aSignatureLineId += rChars;
 
     if (m_xNextHandler.is())
         m_xNextHandler->characters(rChars);
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.hxx b/xmlsecurity/source/helper/ooxmlsecparser.hxx
index cd3eed01c2a6..591795618dbb 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.hxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.hxx
@@ -45,6 +45,12 @@ class OOXMLSecParser: public cppu::WeakImplHelper
     OUString m_aX509SerialNumber;
     bool m_bInCertDigest;
     OUString m_aCertDigest;
+    bool m_bInValidSignatureImage;
+    OUString m_aValidSignatureImage;
+    bool m_bInInvalidSignatureImage;
+    OUString m_aInvalidSignatureImage;
+    bool m_bInSignatureLineId;
+    OUString m_aSignatureLineId;
 
     /// Last seen <Reference URI="...">.
     OUString m_aReferenceURI;
diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx
index 4f124a2dc07e..5e5c580a5ca8 100644
--- a/xmlsecurity/source/helper/xsecctl.hxx
+++ b/xmlsecurity/source/helper/xsecctl.hxx
@@ -373,6 +373,9 @@ private:
     void setDate( OUString& ouDate );
     void setDescription(const OUString& rDescription);
     void setCertDigest(const OUString& rCertDigest);
+    void setValidSignatureImage(const OUString& rValidSigImg);
+    void setInvalidSignatureImage(const OUString& rInvalidSigImg);
+    void setSignatureLineId(const OUString& rSignatureLineId);
 public:
     void setSignatureBytes(const css::uno::Sequence<sal_Int8>& rBytes);
 
diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index a60b4c567022..2f9efcfdb9d0 100644
--- a/xmlsecurity/source/helper/xsecverify.cxx
+++ b/xmlsecurity/source/helper/xsecverify.cxx
@@ -23,17 +23,27 @@
 #include "ooxmlsecparser.hxx"
 #include <tools/debug.hxx>
 
+#include <com/sun/star/uno/Sequence.hxx>
 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
+#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
 #include <com/sun/star/xml/sax/SAXParseException.hpp>
 #include <com/sun/star/embed/StorageFormats.hpp>
 #include <sal/log.hxx>
+#include <sax/tools/converter.hxx>
 #include <unotools/datetime.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/seqstream.hxx>
 
-using namespace com::sun::star;
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
 namespace cssu = com::sun::star::uno;
 namespace cssl = com::sun::star::lang;
 namespace cssxc = com::sun::star::xml::crypto;
@@ -292,7 +302,57 @@ void XSecController::setCertDigest(const OUString& rCertDigest)
     rInformation.signatureInfor.ouCertDigest = rCertDigest;
 }
 
-void XSecController::setId( OUString& ouId )
+namespace {
+Reference<css::graphic::XGraphic> lcl_getGraphicFromString(const OUString& rImage)
+{
+    Sequence<sal_Int8> seq;
+    ::sax::Converter::decodeBase64(seq, rImage);
+
+    Reference< graphic::XGraphic > xGraphic;
+    if( !seq.hasElements() )
+        return Reference<css::graphic::XGraphic>();
+
+    Reference< graphic::XGraphicProvider > xGraphicProvider(
+        graphic::GraphicProvider::create(comphelper::getProcessComponentContext()) );
+    Reference< io::XInputStream > xInputStream( new ::comphelper::SequenceInputStream( seq ) );
+
+    Sequence< PropertyValue > aArgs( 1 );
+    aArgs[ 0 ].Name = "InputStream";
+    aArgs[ 0 ].Value <<= xInputStream;
+    xGraphic = xGraphicProvider->queryGraphic(aArgs);
+
+    return xGraphic;
+}
+}
+
+void XSecController::setValidSignatureImage(const OUString& rValidSigImg)
+{
+    if (m_vInternalSignatureInformations.empty() || rValidSigImg.isEmpty())
+        return;
+
+    InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
+    rInformation.signatureInfor.aValidSignatureImage = lcl_getGraphicFromString(rValidSigImg);
+}
+
+void XSecController::setInvalidSignatureImage(const OUString& rInvalidSigImg)
+{
+    if (m_vInternalSignatureInformations.empty() || rInvalidSigImg.isEmpty())
+        return;
+
+    InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
+    rInformation.signatureInfor.aInvalidSignatureImage = lcl_getGraphicFromString(rInvalidSigImg);
+}
+
+void XSecController::setSignatureLineId(const OUString& rSignatureLineId)
+{
+    if (m_vInternalSignatureInformations.empty())
+        return;
+
+    InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
+    rInformation.signatureInfor.ouSignatureLineId = rSignatureLineId;
+}
+
+void XSecController::setId( OUString & ouId )
 {
     if (m_vInternalSignatureInformations.empty())
     {


More information about the Libreoffice-commits mailing list