1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include "ooxmlsecexporter.hxx"
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
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
;
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();
76 void writePackageObject();
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.
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
);
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
);
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
);
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(
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(
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
));
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
))
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
,
262 uno::Reference
<io::XInputStream
> xRelStream(
263 xHierarchicalStorageAccess
->openStreamElementByHierarchicalName(rURI
,
264 embed::ElementModes::READ
),
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
)
280 for (const beans::StringPair
& rPair
: rPairs
)
282 if (rPair
.First
== "Id")
284 else if (rPair
.First
== "Type")
285 aType
= rPair
.Second
;
288 if (OOXMLSecExporter::Impl::isOOXMLRelationDenylist(aType
))
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
;
331 m_aSignatureTimeValue
= utl::toISO8601(m_rInformation
.stDateTime
);
332 // Ignore sub-seconds.
333 sal_Int32 nCommaPos
= m_aSignatureTimeValue
.indexOf(',');
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
));
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("/"))
363 // Ignore query part of the URI.
364 sal_Int32 nQueryPos
= aURI
.indexOf('?');
366 aURI
= aURI
.copy(0, nQueryPos
);
368 m_xDocumentHandler
->startElement(
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())
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
));
552 writeSignatureValue();
554 writePackageObject();
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
)
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: */