Get the style color and number just once
[LibreOffice.git] / xmlsecurity / source / helper / ooxmlsecexporter.cxx
blobf8a870d168604c22ff10e639ea37794918388f8c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include "ooxmlsecexporter.hxx"
12 #include <algorithm>
13 #include <memory>
14 #include <string_view>
16 #include <com/sun/star/embed/ElementModes.hpp>
17 #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
18 #include <com/sun/star/embed/XStorage.hpp>
19 #include <com/sun/star/beans/StringPair.hpp>
20 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
22 #include <comphelper/attributelist.hxx>
23 #include <comphelper/ofopxmlhelper.hxx>
24 #include <o3tl/string_view.hxx>
25 #include <rtl/ref.hxx>
26 #include <sal/log.hxx>
27 #include <svx/xoutbmp.hxx>
28 #include <unotools/datetime.hxx>
29 #include <vcl/salctype.hxx>
31 #include <documentsignaturehelper.hxx>
32 #include <xsecctl.hxx>
34 using namespace com::sun::star;
35 using namespace css::xml::sax;
37 struct OOXMLSecExporter::Impl
39 private:
40 const uno::Reference<uno::XComponentContext>& m_xComponentContext;
41 const uno::Reference<embed::XStorage>& m_xRootStorage;
42 const uno::Reference<xml::sax::XDocumentHandler>& m_xDocumentHandler;
43 const SignatureInformation& m_rInformation;
44 OUString m_aSignatureTimeValue;
46 public:
47 Impl(const uno::Reference<uno::XComponentContext>& xComponentContext,
48 const uno::Reference<embed::XStorage>& xRootStorage,
49 const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
50 const SignatureInformation& rInformation)
51 : m_xComponentContext(xComponentContext)
52 , m_xRootStorage(xRootStorage)
53 , m_xDocumentHandler(xDocumentHandler)
54 , m_rInformation(rInformation)
58 /// Should we intentionally not sign this stream?
59 static bool isOOXMLDenylist(std::u16string_view rStreamName);
60 /// Should we intentionally not sign this relation type?
61 static bool isOOXMLRelationDenylist(const OUString& rRelationName);
63 const uno::Reference<xml::sax::XDocumentHandler>& getDocumentHandler() const
65 return m_xDocumentHandler;
68 void writeSignature();
69 void writeSignedInfo();
70 void writeCanonicalizationMethod();
71 void writeCanonicalizationTransform();
72 void writeSignatureMethod();
73 void writeSignedInfoReferences();
74 void writeSignatureValue();
75 void writeKeyInfo();
76 void writePackageObject();
77 void writeManifest();
78 void writeRelationshipTransform(const OUString& rURI);
79 /// Writes <SignatureProperties> inside idPackageObject.
80 void writePackageObjectSignatureProperties();
81 /// Writes a single <Reference> inside <Manifest>.
82 void writeManifestReference(const SignatureReferenceInformation& rReference);
83 void writeOfficeObject();
84 /// Writes <SignatureInfoV1>.
85 void writeSignatureInfo();
86 void writePackageSignature();
87 void writeSignatureLineImages();
90 bool OOXMLSecExporter::Impl::isOOXMLDenylist(std::u16string_view rStreamName)
92 static const std::initializer_list<std::u16string_view> vDenylist
93 = { u"/%5BContent_Types%5D.xml", u"/docProps/app.xml", u"/docProps/core.xml",
94 // Don't attempt to sign other signatures for now.
95 u"/_xmlsignatures" };
96 // Just check the prefix, as we don't care about the content type part of the stream name.
97 return std::any_of(vDenylist.begin(), vDenylist.end(), [&](std::u16string_view rLiteral) {
98 return o3tl::starts_with(rStreamName, rLiteral);
99 });
102 bool OOXMLSecExporter::Impl::isOOXMLRelationDenylist(const OUString& rRelationName)
104 static const std::initializer_list<std::u16string_view> vDenylist = {
105 u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
106 u"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
107 u"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
109 return std::find(vDenylist.begin(), vDenylist.end(), rRelationName) != vDenylist.end();
112 void OOXMLSecExporter::Impl::writeSignedInfo()
114 m_xDocumentHandler->startElement(u"SignedInfo"_ustr, uno::Reference<xml::sax::XAttributeList>(
115 new comphelper::AttributeList()));
117 writeCanonicalizationMethod();
118 writeSignatureMethod();
119 writeSignedInfoReferences();
121 m_xDocumentHandler->endElement(u"SignedInfo"_ustr);
124 void OOXMLSecExporter::Impl::writeCanonicalizationMethod()
126 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
127 pAttributeList->AddAttribute(u"Algorithm"_ustr, ALGO_C14N);
128 m_xDocumentHandler->startElement(u"CanonicalizationMethod"_ustr,
129 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
130 m_xDocumentHandler->endElement(u"CanonicalizationMethod"_ustr);
133 void OOXMLSecExporter::Impl::writeCanonicalizationTransform()
135 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
136 pAttributeList->AddAttribute(u"Algorithm"_ustr, ALGO_C14N);
137 m_xDocumentHandler->startElement(u"Transform"_ustr,
138 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
139 m_xDocumentHandler->endElement(u"Transform"_ustr);
142 void OOXMLSecExporter::Impl::writeSignatureMethod()
144 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
146 if (m_rInformation.eAlgorithmID == svl::crypto::SignatureMethodAlgorithm::ECDSA)
147 pAttributeList->AddAttribute(u"Algorithm"_ustr, ALGO_ECDSASHA256);
148 else
149 pAttributeList->AddAttribute(u"Algorithm"_ustr, ALGO_RSASHA256);
151 m_xDocumentHandler->startElement(u"SignatureMethod"_ustr,
152 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
153 m_xDocumentHandler->endElement(u"SignatureMethod"_ustr);
156 void OOXMLSecExporter::Impl::writeSignedInfoReferences()
158 const SignatureReferenceInformations& rReferences = m_rInformation.vSignatureReferenceInfors;
159 for (const SignatureReferenceInformation& rReference : rReferences)
161 if (rReference.nType == SignatureReferenceType::SAMEDOCUMENT)
164 rtl::Reference<comphelper::AttributeList> pAttributeList(
165 new comphelper::AttributeList());
166 if (!rReference.ouURI.startsWith("idSignedProperties"))
167 pAttributeList->AddAttribute(u"Type"_ustr,
168 u"http://www.w3.org/2000/09/xmldsig#Object"_ustr);
169 else
170 pAttributeList->AddAttribute(
171 u"Type"_ustr, u"http://uri.etsi.org/01903#SignedProperties"_ustr);
172 pAttributeList->AddAttribute(u"URI"_ustr, "#" + rReference.ouURI);
173 m_xDocumentHandler->startElement(
174 u"Reference"_ustr, uno::Reference<xml::sax::XAttributeList>(pAttributeList));
176 if (rReference.ouURI.startsWith("idSignedProperties"))
178 m_xDocumentHandler->startElement(
179 u"Transforms"_ustr,
180 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
181 writeCanonicalizationTransform();
182 m_xDocumentHandler->endElement(u"Transforms"_ustr);
185 DocumentSignatureHelper::writeDigestMethod(m_xDocumentHandler);
186 m_xDocumentHandler->startElement(
187 u"DigestValue"_ustr,
188 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
189 m_xDocumentHandler->characters(rReference.ouDigestValue);
190 m_xDocumentHandler->endElement(u"DigestValue"_ustr);
191 m_xDocumentHandler->endElement(u"Reference"_ustr);
196 void OOXMLSecExporter::Impl::writeSignatureValue()
198 m_xDocumentHandler->startElement(
199 u"SignatureValue"_ustr,
200 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
201 m_xDocumentHandler->characters(m_rInformation.ouSignatureValue);
202 m_xDocumentHandler->endElement(u"SignatureValue"_ustr);
205 void OOXMLSecExporter::Impl::writeKeyInfo()
207 m_xDocumentHandler->startElement(
208 u"KeyInfo"_ustr, uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
209 assert(m_rInformation.GetSigningCertificate());
210 for (auto const& rData : m_rInformation.X509Datas)
212 m_xDocumentHandler->startElement(u"X509Data"_ustr, uno::Reference<xml::sax::XAttributeList>(
213 new comphelper::AttributeList()));
214 for (auto const& it : rData)
216 m_xDocumentHandler->startElement(
217 u"X509Certificate"_ustr,
218 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
219 m_xDocumentHandler->characters(it.X509Certificate);
220 m_xDocumentHandler->endElement(u"X509Certificate"_ustr);
222 m_xDocumentHandler->endElement(u"X509Data"_ustr);
224 m_xDocumentHandler->endElement(u"KeyInfo"_ustr);
227 void OOXMLSecExporter::Impl::writePackageObject()
229 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
230 pAttributeList->AddAttribute(u"Id"_ustr, "idPackageObject_" + m_rInformation.ouSignatureId);
231 m_xDocumentHandler->startElement(u"Object"_ustr,
232 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
234 writeManifest();
235 writePackageObjectSignatureProperties();
237 m_xDocumentHandler->endElement(u"Object"_ustr);
240 void OOXMLSecExporter::Impl::writeManifest()
242 m_xDocumentHandler->startElement(u"Manifest"_ustr, uno::Reference<xml::sax::XAttributeList>(
243 new comphelper::AttributeList()));
244 const SignatureReferenceInformations& rReferences = m_rInformation.vSignatureReferenceInfors;
245 for (const SignatureReferenceInformation& rReference : rReferences)
247 if (rReference.nType != SignatureReferenceType::SAMEDOCUMENT)
249 if (OOXMLSecExporter::Impl::isOOXMLDenylist(rReference.ouURI))
250 continue;
252 writeManifestReference(rReference);
255 m_xDocumentHandler->endElement(u"Manifest"_ustr);
258 void OOXMLSecExporter::Impl::writeRelationshipTransform(const OUString& rURI)
260 uno::Reference<embed::XHierarchicalStorageAccess> xHierarchicalStorageAccess(m_xRootStorage,
261 uno::UNO_QUERY);
262 uno::Reference<io::XInputStream> xRelStream(
263 xHierarchicalStorageAccess->openStreamElementByHierarchicalName(rURI,
264 embed::ElementModes::READ),
265 uno::UNO_QUERY);
267 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
268 pAttributeList->AddAttribute(u"Algorithm"_ustr, ALGO_RELATIONSHIP);
269 m_xDocumentHandler->startElement(u"Transform"_ustr,
270 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
273 const uno::Sequence<uno::Sequence<beans::StringPair>> aRelationsInfo
274 = comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, rURI,
275 m_xComponentContext);
276 for (const uno::Sequence<beans::StringPair>& rPairs : aRelationsInfo)
278 OUString aId;
279 OUString aType;
280 for (const beans::StringPair& rPair : rPairs)
282 if (rPair.First == "Id")
283 aId = rPair.Second;
284 else if (rPair.First == "Type")
285 aType = rPair.Second;
288 if (OOXMLSecExporter::Impl::isOOXMLRelationDenylist(aType))
289 continue;
291 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
292 pAttributeList->AddAttribute(u"xmlns:mdssi"_ustr, NS_MDSSI);
293 pAttributeList->AddAttribute(u"SourceId"_ustr, aId);
294 m_xDocumentHandler->startElement(u"mdssi:RelationshipReference"_ustr,
295 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
296 m_xDocumentHandler->endElement(u"mdssi:RelationshipReference"_ustr);
299 m_xDocumentHandler->endElement(u"Transform"_ustr);
302 void OOXMLSecExporter::Impl::writePackageObjectSignatureProperties()
304 m_xDocumentHandler->startElement(
305 u"SignatureProperties"_ustr,
306 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
308 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
309 pAttributeList->AddAttribute(u"Id"_ustr, "idSignatureTime_" + m_rInformation.ouSignatureId);
310 pAttributeList->AddAttribute(u"Target"_ustr, "#" + m_rInformation.ouSignatureId);
311 m_xDocumentHandler->startElement(u"SignatureProperty"_ustr,
312 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
315 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
316 pAttributeList->AddAttribute(u"xmlns:mdssi"_ustr, NS_MDSSI);
317 m_xDocumentHandler->startElement(u"mdssi:SignatureTime"_ustr,
318 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
320 m_xDocumentHandler->startElement(u"mdssi:Format"_ustr, uno::Reference<xml::sax::XAttributeList>(
321 new comphelper::AttributeList()));
322 m_xDocumentHandler->characters(u"YYYY-MM-DDThh:mm:ssTZD"_ustr);
323 m_xDocumentHandler->endElement(u"mdssi:Format"_ustr);
325 m_xDocumentHandler->startElement(u"mdssi:Value"_ustr, uno::Reference<xml::sax::XAttributeList>(
326 new comphelper::AttributeList()));
327 if (!m_rInformation.ouDateTime.isEmpty())
328 m_aSignatureTimeValue = m_rInformation.ouDateTime;
329 else
331 m_aSignatureTimeValue = utl::toISO8601(m_rInformation.stDateTime);
332 // Ignore sub-seconds.
333 sal_Int32 nCommaPos = m_aSignatureTimeValue.indexOf(',');
334 if (nCommaPos != -1)
336 m_aSignatureTimeValue
337 = OUString::Concat(m_aSignatureTimeValue.subView(0, nCommaPos)) + "Z";
340 m_xDocumentHandler->characters(m_aSignatureTimeValue);
341 m_xDocumentHandler->endElement(u"mdssi:Value"_ustr);
343 m_xDocumentHandler->endElement(u"mdssi:SignatureTime"_ustr);
344 m_xDocumentHandler->endElement(u"SignatureProperty"_ustr);
345 m_xDocumentHandler->endElement(u"SignatureProperties"_ustr);
348 void OOXMLSecExporter::Impl::writeManifestReference(const SignatureReferenceInformation& rReference)
350 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
351 pAttributeList->AddAttribute(u"URI"_ustr, rReference.ouURI);
352 m_xDocumentHandler->startElement(u"Reference"_ustr,
353 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
355 // Transforms
356 if (rReference.ouURI.endsWith(
357 "?ContentType=application/vnd.openxmlformats-package.relationships+xml"))
359 OUString aURI = rReference.ouURI;
360 // Ignore leading slash.
361 if (aURI.startsWith("/"))
362 aURI = aURI.copy(1);
363 // Ignore query part of the URI.
364 sal_Int32 nQueryPos = aURI.indexOf('?');
365 if (nQueryPos != -1)
366 aURI = aURI.copy(0, nQueryPos);
368 m_xDocumentHandler->startElement(
369 u"Transforms"_ustr,
370 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
372 writeRelationshipTransform(aURI);
373 writeCanonicalizationTransform();
375 m_xDocumentHandler->endElement(u"Transforms"_ustr);
378 DocumentSignatureHelper::writeDigestMethod(m_xDocumentHandler);
379 m_xDocumentHandler->startElement(u"DigestValue"_ustr, uno::Reference<xml::sax::XAttributeList>(
380 new comphelper::AttributeList()));
381 m_xDocumentHandler->characters(rReference.ouDigestValue);
382 m_xDocumentHandler->endElement(u"DigestValue"_ustr);
383 m_xDocumentHandler->endElement(u"Reference"_ustr);
386 void OOXMLSecExporter::Impl::writeOfficeObject()
389 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
390 pAttributeList->AddAttribute(u"Id"_ustr, "idOfficeObject_" + m_rInformation.ouSignatureId);
391 m_xDocumentHandler->startElement(u"Object"_ustr,
392 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
394 m_xDocumentHandler->startElement(
395 u"SignatureProperties"_ustr,
396 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
398 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
399 pAttributeList->AddAttribute(u"Id"_ustr,
400 "idOfficeV1Details_" + m_rInformation.ouSignatureId);
401 pAttributeList->AddAttribute(u"Target"_ustr, "#" + m_rInformation.ouSignatureId);
402 m_xDocumentHandler->startElement(u"SignatureProperty"_ustr,
403 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
405 writeSignatureInfo();
406 m_xDocumentHandler->endElement(u"SignatureProperty"_ustr);
407 m_xDocumentHandler->endElement(u"SignatureProperties"_ustr);
408 m_xDocumentHandler->endElement(u"Object"_ustr);
411 void OOXMLSecExporter::Impl::writeSignatureInfo()
413 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
414 pAttributeList->AddAttribute(u"xmlns"_ustr,
415 u"http://schemas.microsoft.com/office/2006/digsig"_ustr);
416 m_xDocumentHandler->startElement(u"SignatureInfoV1"_ustr,
417 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
419 m_xDocumentHandler->startElement(
420 u"SetupID"_ustr, uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
421 m_xDocumentHandler->characters(m_rInformation.ouSignatureLineId);
422 m_xDocumentHandler->endElement(u"SetupID"_ustr);
423 m_xDocumentHandler->startElement(
424 u"SignatureText"_ustr,
425 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
426 m_xDocumentHandler->endElement(u"SignatureText"_ustr);
427 m_xDocumentHandler->startElement(
428 u"SignatureImage"_ustr,
429 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
430 m_xDocumentHandler->endElement(u"SignatureImage"_ustr);
431 m_xDocumentHandler->startElement(
432 u"SignatureComments"_ustr,
433 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
434 m_xDocumentHandler->characters(m_rInformation.ouDescription);
435 m_xDocumentHandler->endElement(u"SignatureComments"_ustr);
436 // Just hardcode something valid according to [MS-OFFCRYPTO].
437 m_xDocumentHandler->startElement(
438 u"WindowsVersion"_ustr,
439 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
440 m_xDocumentHandler->characters(u"6.1"_ustr);
441 m_xDocumentHandler->endElement(u"WindowsVersion"_ustr);
442 m_xDocumentHandler->startElement(
443 u"OfficeVersion"_ustr,
444 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
445 m_xDocumentHandler->characters(u"16.0"_ustr);
446 m_xDocumentHandler->endElement(u"OfficeVersion"_ustr);
447 m_xDocumentHandler->startElement(
448 u"ApplicationVersion"_ustr,
449 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
450 m_xDocumentHandler->characters(u"16.0"_ustr);
451 m_xDocumentHandler->endElement(u"ApplicationVersion"_ustr);
452 m_xDocumentHandler->startElement(u"Monitors"_ustr, uno::Reference<xml::sax::XAttributeList>(
453 new comphelper::AttributeList()));
454 m_xDocumentHandler->characters(u"1"_ustr);
455 m_xDocumentHandler->endElement(u"Monitors"_ustr);
456 m_xDocumentHandler->startElement(
457 u"HorizontalResolution"_ustr,
458 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
459 m_xDocumentHandler->characters(u"1280"_ustr);
460 m_xDocumentHandler->endElement(u"HorizontalResolution"_ustr);
461 m_xDocumentHandler->startElement(
462 u"VerticalResolution"_ustr,
463 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
464 m_xDocumentHandler->characters(u"800"_ustr);
465 m_xDocumentHandler->endElement(u"VerticalResolution"_ustr);
466 m_xDocumentHandler->startElement(u"ColorDepth"_ustr, uno::Reference<xml::sax::XAttributeList>(
467 new comphelper::AttributeList()));
468 m_xDocumentHandler->characters(u"32"_ustr);
469 m_xDocumentHandler->endElement(u"ColorDepth"_ustr);
470 m_xDocumentHandler->startElement(
471 u"SignatureProviderId"_ustr,
472 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
473 m_xDocumentHandler->characters(u"{00000000-0000-0000-0000-000000000000}"_ustr);
474 m_xDocumentHandler->endElement(u"SignatureProviderId"_ustr);
475 m_xDocumentHandler->startElement(
476 u"SignatureProviderUrl"_ustr,
477 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
478 m_xDocumentHandler->endElement(u"SignatureProviderUrl"_ustr);
479 m_xDocumentHandler->startElement(
480 u"SignatureProviderDetails"_ustr,
481 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
482 m_xDocumentHandler->characters(
483 u"9"_ustr); // This is what MSO 2016 writes, though [MS-OFFCRYPTO] doesn't document what the value means.
484 m_xDocumentHandler->endElement(u"SignatureProviderDetails"_ustr);
485 m_xDocumentHandler->startElement(
486 u"SignatureType"_ustr,
487 uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
488 m_xDocumentHandler->characters(u"2"_ustr);
489 m_xDocumentHandler->endElement(u"SignatureType"_ustr);
491 m_xDocumentHandler->endElement(u"SignatureInfoV1"_ustr);
494 void OOXMLSecExporter::Impl::writePackageSignature()
496 m_xDocumentHandler->startElement(
497 u"Object"_ustr, uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
499 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
500 pAttributeList->AddAttribute(u"xmlns:xd"_ustr, NS_XD);
501 pAttributeList->AddAttribute(u"Target"_ustr, "#" + m_rInformation.ouSignatureId);
502 m_xDocumentHandler->startElement(u"xd:QualifyingProperties"_ustr,
503 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
506 DocumentSignatureHelper::writeSignedProperties(m_xDocumentHandler, m_rInformation,
507 m_aSignatureTimeValue, false);
509 m_xDocumentHandler->endElement(u"xd:QualifyingProperties"_ustr);
510 m_xDocumentHandler->endElement(u"Object"_ustr);
513 void OOXMLSecExporter::Impl::writeSignatureLineImages()
515 if (m_rInformation.aValidSignatureImage.is())
517 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
518 pAttributeList->AddAttribute(u"Id"_ustr, u"idValidSigLnImg"_ustr);
519 m_xDocumentHandler->startElement(u"Object"_ustr,
520 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
521 OUString aGraphicInBase64;
522 Graphic aGraphic(m_rInformation.aValidSignatureImage);
523 if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64, false, ConvertDataFormat::EMF))
524 SAL_WARN("xmlsecurity.helper", "could not convert graphic to base64");
525 m_xDocumentHandler->characters(aGraphicInBase64);
526 m_xDocumentHandler->endElement(u"Object"_ustr);
528 if (!m_rInformation.aInvalidSignatureImage.is())
529 return;
531 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
532 pAttributeList->AddAttribute(u"Id"_ustr, u"idInvalidSigLnImg"_ustr);
533 m_xDocumentHandler->startElement(u"Object"_ustr,
534 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
535 OUString aGraphicInBase64;
536 Graphic aGraphic(m_rInformation.aInvalidSignatureImage);
537 if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64, false, ConvertDataFormat::EMF))
538 SAL_WARN("xmlsecurity.helper", "could not convert graphic to base64");
539 m_xDocumentHandler->characters(aGraphicInBase64);
540 m_xDocumentHandler->endElement(u"Object"_ustr);
543 void OOXMLSecExporter::Impl::writeSignature()
545 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
546 pAttributeList->AddAttribute(u"xmlns"_ustr, NS_XMLDSIG);
547 pAttributeList->AddAttribute(u"Id"_ustr, m_rInformation.ouSignatureId);
548 getDocumentHandler()->startElement(u"Signature"_ustr,
549 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
551 writeSignedInfo();
552 writeSignatureValue();
553 writeKeyInfo();
554 writePackageObject();
555 writeOfficeObject();
556 writePackageSignature();
557 writeSignatureLineImages();
559 getDocumentHandler()->endElement(u"Signature"_ustr);
562 OOXMLSecExporter::OOXMLSecExporter(
563 const uno::Reference<uno::XComponentContext>& xComponentContext,
564 const uno::Reference<embed::XStorage>& xRootStorage,
565 const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
566 const SignatureInformation& rInformation)
567 : m_pImpl(
568 std::make_unique<Impl>(xComponentContext, xRootStorage, xDocumentHandler, rInformation))
572 OOXMLSecExporter::~OOXMLSecExporter() = default;
574 void OOXMLSecExporter::writeSignature() { m_pImpl->writeSignature(); }
576 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */