Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/draw/SignatureLineContext.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
#include "SignatureLineContext.hxx"
11
12
#include <com/sun/star/beans/XPropertySet.hpp>
13
#include <com/sun/star/embed/XStorage.hpp>
14
#include <com/sun/star/frame/XModel.hpp>
15
#include <com/sun/star/frame/XStorable.hpp>
16
#include <com/sun/star/graphic/XGraphic.hpp>
17
#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
18
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
19
20
#include <sal/log.hxx>
21
#include <comphelper/processfactory.hxx>
22
#include <comphelper/storagehelper.hxx>
23
#include <xmloff/xmltoken.hxx>
24
#include <xmloff/xmlimp.hxx>
25
#include <xmloff/xmlnamespace.hxx>
26
27
using namespace css;
28
using namespace css::xml::sax;
29
using namespace css::uno;
30
using namespace css::drawing;
31
using namespace css::embed;
32
using namespace css::frame;
33
using namespace css::io;
34
using namespace css::graphic;
35
using namespace css::security;
36
using namespace xmloff::token;
37
38
SignatureLineContext::SignatureLineContext(SvXMLImport& rImport, sal_Int32 /*nElement*/,
39
                                           const Reference<XFastAttributeList>& xAttrList,
40
                                           const Reference<XShape>& rxShape)
41
0
    : SvXMLImportContext(rImport)
42
0
{
43
0
    Reference<beans::XPropertySet> xPropSet(rxShape, UNO_QUERY_THROW);
44
45
0
    xPropSet->setPropertyValue(u"IsSignatureLine"_ustr, Any(true));
46
47
0
    xPropSet->setPropertyValue(u"SignatureLineId"_ustr,
48
0
                               Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_ID))));
49
0
    xPropSet->setPropertyValue(
50
0
        u"SignatureLineSuggestedSignerName"_ustr,
51
0
        Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SUGGESTED_SIGNER_NAME))));
52
0
    xPropSet->setPropertyValue(
53
0
        u"SignatureLineSuggestedSignerTitle"_ustr,
54
0
        Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SUGGESTED_SIGNER_TITLE))));
55
0
    xPropSet->setPropertyValue(
56
0
        u"SignatureLineSuggestedSignerEmail"_ustr,
57
0
        Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SUGGESTED_SIGNER_EMAIL))));
58
0
    xPropSet->setPropertyValue(
59
0
        u"SignatureLineSigningInstructions"_ustr,
60
0
        Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SIGNING_INSTRUCTIONS))));
61
62
0
    bool bShowSignDate = xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SHOW_SIGN_DATE))
63
0
                         == GetXMLToken(XML_TRUE);
64
0
    bool bCanAddComment = xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_CAN_ADD_COMMENT))
65
0
                          == GetXMLToken(XML_TRUE);
66
0
    xPropSet->setPropertyValue(u"SignatureLineShowSignDate"_ustr, Any(bShowSignDate));
67
0
    xPropSet->setPropertyValue(u"SignatureLineCanAddComment"_ustr, Any(bCanAddComment));
68
69
    // Save unsigned graphic (need it when exporting)
70
0
    Reference<XGraphic> xUnsignedGraphic;
71
0
    xPropSet->getPropertyValue(u"Graphic"_ustr) >>= xUnsignedGraphic;
72
0
    if (xUnsignedGraphic.is())
73
0
        xPropSet->setPropertyValue(u"SignatureLineUnsignedImage"_ustr, Any(xUnsignedGraphic));
74
75
0
    Reference<XGraphic> xGraphic;
76
0
    try
77
0
    {
78
        // Get the document signatures
79
0
        css::uno::Reference<XStorable> xStorable(GetImport().GetModel(), UNO_QUERY_THROW);
80
0
        Reference<XStorage> xStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
81
0
            ZIP_STORAGE_FORMAT_STRING, xStorable->getLocation(), ElementModes::READ);
82
83
0
        if (!xStorage.is())
84
0
        {
85
0
            SAL_WARN("xmloff", "No xStorage!");
86
0
            return;
87
0
        }
88
89
0
        OUString const aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(xStorage));
90
0
        Reference<XDocumentDigitalSignatures> xSignatures(
91
0
            security::DocumentDigitalSignatures::createWithVersion(
92
0
                comphelper::getProcessComponentContext(), aODFVersion));
93
94
0
        const Sequence<DocumentSignatureInformation> xSignatureInfo
95
0
            = xSignatures->verifyDocumentContentSignatures(xStorage, Reference<XInputStream>());
96
97
        // Try to find matching signature line image - if none exists that is fine,
98
        // then the signature line is not digitally signed.
99
0
        auto pSignatureInfo
100
0
            = std::find_if(xSignatureInfo.begin(), xSignatureInfo.end(),
101
0
                           [&xAttrList](const DocumentSignatureInformation& rSignatureInfo) {
102
0
                               return rSignatureInfo.SignatureLineId
103
0
                                      == xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_ID));
104
0
                           });
105
0
        bool bIsSigned(false);
106
0
        if (pSignatureInfo != xSignatureInfo.end())
107
0
        {
108
0
            bIsSigned = true;
109
0
            if (pSignatureInfo->SignatureIsValid)
110
0
            {
111
                // Signature is valid, use the 'valid' image
112
0
                SAL_WARN_IF(!pSignatureInfo->ValidSignatureLineImage.is(), "xmloff",
113
0
                            "No ValidSignatureLineImage!");
114
0
                xGraphic = pSignatureInfo->ValidSignatureLineImage;
115
0
            }
116
0
            else
117
0
            {
118
                // Signature is invalid, use the 'invalid' image
119
0
                SAL_WARN_IF(!pSignatureInfo->InvalidSignatureLineImage.is(), "xmloff",
120
0
                            "No InvalidSignatureLineImage!");
121
0
                xGraphic = pSignatureInfo->InvalidSignatureLineImage;
122
0
            }
123
124
0
            xPropSet->setPropertyValue(u"Graphic"_ustr, Any(xGraphic));
125
0
        }
126
0
        xPropSet->setPropertyValue(u"SignatureLineIsSigned"_ustr, Any(bIsSigned));
127
0
    }
128
0
    catch (css::uno::Exception&)
129
0
    {
130
        // DocumentDigitalSignatures service not available.
131
        // We render the "unsigned" shape instead.
132
0
    }
133
0
}
134
135
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */