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>
35using namespace css::xml::sax;
47 Impl(
const uno::Reference<uno::XComponentContext>& xComponentContext,
48 const uno::Reference<embed::XStorage>& xRootStorage,
49 const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
92 static const std::initializer_list<std::u16string_view> vDenylist
93 = {
u"/%5BContent_Types%5D.xml",
u"/docProps/app.xml",
u"/docProps/core.xml",
97 return std::any_of(vDenylist.begin(), vDenylist.end(),
98 [&](
const std::u16string_view& rLiteral) {
99 return o3tl::starts_with(rStreamName, rLiteral);
105 static const std::initializer_list<std::u16string_view> vDenylist = {
106 u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
107 u"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
108 u"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
110 return std::find(vDenylist.begin(), vDenylist.end(), rRelationName) != vDenylist.end();
115 m_xDocumentHandler->startElement(
118 writeCanonicalizationMethod();
119 writeSignatureMethod();
120 writeSignedInfoReferences();
122 m_xDocumentHandler->endElement(
"SignedInfo");
128 pAttributeList->AddAttribute(
"Algorithm",
ALGO_C14N);
129 m_xDocumentHandler->startElement(
"CanonicalizationMethod",
130 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
131 m_xDocumentHandler->endElement(
"CanonicalizationMethod");
137 pAttributeList->AddAttribute(
"Algorithm",
ALGO_C14N);
138 m_xDocumentHandler->startElement(
"Transform",
139 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
140 m_xDocumentHandler->endElement(
"Transform");
152 m_xDocumentHandler->startElement(
"SignatureMethod",
153 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
154 m_xDocumentHandler->endElement(
"SignatureMethod");
162 if (rReference.nType == SignatureReferenceType::SAMEDOCUMENT)
167 if (!rReference.ouURI.startsWith(
"idSignedProperties"))
168 pAttributeList->AddAttribute(
"Type",
169 "http://www.w3.org/2000/09/xmldsig#Object");
171 pAttributeList->AddAttribute(
"Type",
172 "http://uri.etsi.org/01903#SignedProperties");
173 pAttributeList->AddAttribute(
"URI",
"#" + rReference.ouURI);
174 m_xDocumentHandler->startElement(
175 "Reference", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
177 if (rReference.ouURI.startsWith(
"idSignedProperties"))
179 m_xDocumentHandler->startElement(
182 writeCanonicalizationTransform();
183 m_xDocumentHandler->endElement(
"Transforms");
187 m_xDocumentHandler->startElement(
190 m_xDocumentHandler->characters(rReference.ouDigestValue);
191 m_xDocumentHandler->endElement(
"DigestValue");
192 m_xDocumentHandler->endElement(
"Reference");
199 m_xDocumentHandler->startElement(
"SignatureValue", uno::Reference<xml::sax::XAttributeList>(
201 m_xDocumentHandler->characters(m_rInformation.ouSignatureValue);
202 m_xDocumentHandler->endElement(
"SignatureValue");
207 m_xDocumentHandler->startElement(
209 assert(m_rInformation.GetSigningCertificate());
210 for (
auto const& rData : m_rInformation.X509Datas)
212 m_xDocumentHandler->startElement(
214 for (
auto const& it : rData)
216 m_xDocumentHandler->startElement(
219 m_xDocumentHandler->characters(it.X509Certificate);
220 m_xDocumentHandler->endElement(
"X509Certificate");
222 m_xDocumentHandler->endElement(
"X509Data");
224 m_xDocumentHandler->endElement(
"KeyInfo");
230 pAttributeList->AddAttribute(
"Id",
"idPackageObject_" + m_rInformation.ouSignatureId);
231 m_xDocumentHandler->startElement(
"Object",
232 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
235 writePackageObjectSignatureProperties();
237 m_xDocumentHandler->endElement(
"Object");
242 m_xDocumentHandler->startElement(
247 if (rReference.nType != SignatureReferenceType::SAMEDOCUMENT)
252 writeManifestReference(rReference);
255 m_xDocumentHandler->endElement(
"Manifest");
260 uno::Reference<embed::XHierarchicalStorageAccess> xHierarchicalStorageAccess(m_xRootStorage,
262 uno::Reference<io::XInputStream> xRelStream(
263 xHierarchicalStorageAccess->openStreamElementByHierarchicalName(rURI,
264 embed::ElementModes::READ),
269 m_xDocumentHandler->startElement(
"Transform",
270 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
273 const uno::Sequence<uno::Sequence<beans::StringPair>> aRelationsInfo
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;
292 pAttributeList->AddAttribute(
"xmlns:mdssi",
NS_MDSSI);
293 pAttributeList->AddAttribute(
"SourceId", aId);
294 m_xDocumentHandler->startElement(
"mdssi:RelationshipReference",
295 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
296 m_xDocumentHandler->endElement(
"mdssi:RelationshipReference");
299 m_xDocumentHandler->endElement(
"Transform");
304 m_xDocumentHandler->startElement(
305 "SignatureProperties",
309 pAttributeList->AddAttribute(
"Id",
"idSignatureTime_" + m_rInformation.ouSignatureId);
310 pAttributeList->AddAttribute(
"Target",
"#" + m_rInformation.ouSignatureId);
311 m_xDocumentHandler->startElement(
"SignatureProperty",
312 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
316 pAttributeList->AddAttribute(
"xmlns:mdssi",
NS_MDSSI);
317 m_xDocumentHandler->startElement(
"mdssi:SignatureTime",
318 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
320 m_xDocumentHandler->startElement(
322 m_xDocumentHandler->characters(
"YYYY-MM-DDThh:mm:ssTZD");
323 m_xDocumentHandler->endElement(
"mdssi:Format");
325 m_xDocumentHandler->startElement(
327 if (!m_rInformation.ouDateTime.isEmpty())
328 m_aSignatureTimeValue = m_rInformation.ouDateTime;
331 m_aSignatureTimeValue =
utl::toISO8601(m_rInformation.stDateTime);
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(
"mdssi:Value");
343 m_xDocumentHandler->endElement(
"mdssi:SignatureTime");
344 m_xDocumentHandler->endElement(
"SignatureProperty");
345 m_xDocumentHandler->endElement(
"SignatureProperties");
351 pAttributeList->AddAttribute(
"URI", rReference.
ouURI);
352 m_xDocumentHandler->startElement(
"Reference",
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;
361 if (aURI.startsWith(
"/"))
364 sal_Int32 nQueryPos = aURI.indexOf(
'?');
366 aURI = aURI.copy(0, nQueryPos);
368 m_xDocumentHandler->startElement(
"Transforms", uno::Reference<xml::sax::XAttributeList>(
371 writeRelationshipTransform(aURI);
372 writeCanonicalizationTransform();
374 m_xDocumentHandler->endElement(
"Transforms");
378 m_xDocumentHandler->startElement(
381 m_xDocumentHandler->endElement(
"DigestValue");
382 m_xDocumentHandler->endElement(
"Reference");
389 pAttributeList->AddAttribute(
"Id",
"idOfficeObject_" + m_rInformation.ouSignatureId);
390 m_xDocumentHandler->startElement(
"Object",
391 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
393 m_xDocumentHandler->startElement(
394 "SignatureProperties",
398 pAttributeList->AddAttribute(
"Id",
"idOfficeV1Details_" + m_rInformation.ouSignatureId);
399 pAttributeList->AddAttribute(
"Target",
"#" + m_rInformation.ouSignatureId);
400 m_xDocumentHandler->startElement(
"SignatureProperty",
401 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
403 writeSignatureInfo();
404 m_xDocumentHandler->endElement(
"SignatureProperty");
405 m_xDocumentHandler->endElement(
"SignatureProperties");
406 m_xDocumentHandler->endElement(
"Object");
412 pAttributeList->AddAttribute(
"xmlns",
"http://schemas.microsoft.com/office/2006/digsig");
413 m_xDocumentHandler->startElement(
"SignatureInfoV1",
414 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
416 m_xDocumentHandler->startElement(
418 m_xDocumentHandler->characters(m_rInformation.ouSignatureLineId);
419 m_xDocumentHandler->endElement(
"SetupID");
420 m_xDocumentHandler->startElement(
422 m_xDocumentHandler->endElement(
"SignatureText");
423 m_xDocumentHandler->startElement(
"SignatureImage", uno::Reference<xml::sax::XAttributeList>(
425 m_xDocumentHandler->endElement(
"SignatureImage");
426 m_xDocumentHandler->startElement(
"SignatureComments", uno::Reference<xml::sax::XAttributeList>(
428 m_xDocumentHandler->characters(m_rInformation.ouDescription);
429 m_xDocumentHandler->endElement(
"SignatureComments");
431 m_xDocumentHandler->startElement(
"WindowsVersion", uno::Reference<xml::sax::XAttributeList>(
433 m_xDocumentHandler->characters(
"6.1");
434 m_xDocumentHandler->endElement(
"WindowsVersion");
435 m_xDocumentHandler->startElement(
437 m_xDocumentHandler->characters(
"16.0");
438 m_xDocumentHandler->endElement(
"OfficeVersion");
439 m_xDocumentHandler->startElement(
"ApplicationVersion", uno::Reference<xml::sax::XAttributeList>(
441 m_xDocumentHandler->characters(
"16.0");
442 m_xDocumentHandler->endElement(
"ApplicationVersion");
443 m_xDocumentHandler->startElement(
445 m_xDocumentHandler->characters(
"1");
446 m_xDocumentHandler->endElement(
"Monitors");
447 m_xDocumentHandler->startElement(
448 "HorizontalResolution",
450 m_xDocumentHandler->characters(
"1280");
451 m_xDocumentHandler->endElement(
"HorizontalResolution");
452 m_xDocumentHandler->startElement(
"VerticalResolution", uno::Reference<xml::sax::XAttributeList>(
454 m_xDocumentHandler->characters(
"800");
455 m_xDocumentHandler->endElement(
"VerticalResolution");
456 m_xDocumentHandler->startElement(
458 m_xDocumentHandler->characters(
"32");
459 m_xDocumentHandler->endElement(
"ColorDepth");
460 m_xDocumentHandler->startElement(
461 "SignatureProviderId",
463 m_xDocumentHandler->characters(
"{00000000-0000-0000-0000-000000000000}");
464 m_xDocumentHandler->endElement(
"SignatureProviderId");
465 m_xDocumentHandler->startElement(
466 "SignatureProviderUrl",
468 m_xDocumentHandler->endElement(
"SignatureProviderUrl");
469 m_xDocumentHandler->startElement(
470 "SignatureProviderDetails",
472 m_xDocumentHandler->characters(
474 m_xDocumentHandler->endElement(
"SignatureProviderDetails");
475 m_xDocumentHandler->startElement(
477 m_xDocumentHandler->characters(
"2");
478 m_xDocumentHandler->endElement(
"SignatureType");
480 m_xDocumentHandler->endElement(
"SignatureInfoV1");
485 m_xDocumentHandler->startElement(
489 pAttributeList->AddAttribute(
"xmlns:xd",
NS_XD);
490 pAttributeList->AddAttribute(
"Target",
"#" + m_rInformation.ouSignatureId);
491 m_xDocumentHandler->startElement(
"xd:QualifyingProperties",
492 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
496 m_aSignatureTimeValue,
false);
498 m_xDocumentHandler->endElement(
"xd:QualifyingProperties");
499 m_xDocumentHandler->endElement(
"Object");
504 if (m_rInformation.aValidSignatureImage.is())
507 pAttributeList->AddAttribute(
"Id",
"idValidSigLnImg");
508 m_xDocumentHandler->startElement(
"Object",
509 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
510 OUString aGraphicInBase64;
511 Graphic aGraphic(m_rInformation.aValidSignatureImage);
513 SAL_WARN(
"xmlsecurity.helper",
"could not convert graphic to base64");
514 m_xDocumentHandler->characters(aGraphicInBase64);
515 m_xDocumentHandler->endElement(
"Object");
517 if (!m_rInformation.aInvalidSignatureImage.is())
521 pAttributeList->AddAttribute(
"Id",
"idInvalidSigLnImg");
522 m_xDocumentHandler->startElement(
"Object",
523 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
524 OUString aGraphicInBase64;
525 Graphic aGraphic(m_rInformation.aInvalidSignatureImage);
527 SAL_WARN(
"xmlsecurity.helper",
"could not convert graphic to base64");
528 m_xDocumentHandler->characters(aGraphicInBase64);
529 m_xDocumentHandler->endElement(
"Object");
535 pAttributeList->AddAttribute(
"xmlns",
NS_XMLDSIG);
536 pAttributeList->AddAttribute(
"Id", m_rInformation.ouSignatureId);
537 getDocumentHandler()->startElement(
"Signature",
538 uno::Reference<xml::sax::XAttributeList>(pAttributeList));
541 writeSignatureValue();
543 writePackageObject();
545 writePackageSignature();
546 writeSignatureLineImages();
548 getDocumentHandler()->endElement(
"Signature");
552 const uno::Reference<uno::XComponentContext>& xComponentContext,
553 const uno::Reference<embed::XStorage>& xRootStorage,
554 const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
557 std::make_unique<
Impl>(xComponentContext, xRootStorage, xDocumentHandler, rInformation))
OOXMLSecExporter(const css::uno::Reference< css::uno::XComponentContext > &xComponentContext, const css::uno::Reference< css::embed::XStorage > &xRootStorage, const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler, const SignatureInformation &rInformation)
std::unique_ptr< Impl > m_pImpl
static bool GraphicToBase64(const Graphic &rGraphic, OUString &rOUString, bool bAddPrefix=true, ConvertDataFormat aTargetFormat=ConvertDataFormat::Unknown)
Reference< XComponentContext > const m_xComponentContext
#define SAL_WARN(area, stream)
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, const bool bWriteSignatureLineData)
uno::Sequence< uno::Sequence< beans::StringPair > > ReadRelationsInfoSequence(const uno::Reference< io::XInputStream > &xInStream, std::u16string_view aStreamName, const uno::Reference< uno::XComponentContext > &rContext)
OUString toISO8601(const css::util::DateTime &rDateTime)
::std::vector< SignatureReferenceInformation > SignatureReferenceInformations
const uno::Reference< xml::sax::XDocumentHandler > & getDocumentHandler() const
void writeSignatureInfo()
Writes <SignatureInfoV1>.
void writeSignatureLineImages()
void writeManifestReference(const SignatureReferenceInformation &rReference)
Writes a single <Reference> inside <Manifest>.
const uno::Reference< uno::XComponentContext > & m_xComponentContext
const uno::Reference< xml::sax::XDocumentHandler > & m_xDocumentHandler
void writePackageSignature()
const uno::Reference< embed::XStorage > & m_xRootStorage
static bool isOOXMLDenylist(std::u16string_view rStreamName)
Should we intentionally not sign this stream?
void writeSignatureMethod()
void writeSignatureValue()
void writeRelationshipTransform(const OUString &rURI)
const SignatureInformation & m_rInformation
void writePackageObject()
Impl(const uno::Reference< uno::XComponentContext > &xComponentContext, const uno::Reference< embed::XStorage > &xRootStorage, const uno::Reference< xml::sax::XDocumentHandler > &xDocumentHandler, const SignatureInformation &rInformation)
void writeSignedInfoReferences()
void writeCanonicalizationTransform()
void writePackageObjectSignatureProperties()
Writes <SignatureProperties> inside idPackageObject.
static bool isOOXMLRelationDenylist(const OUString &rRelationName)
Should we intentionally not sign this relation type?
void writeCanonicalizationMethod()
OUString m_aSignatureTimeValue
constexpr OUStringLiteral NS_XMLDSIG
constexpr OUStringLiteral NS_XD
constexpr OUStringLiteral NS_MDSSI
constexpr OUStringLiteral ALGO_RELATIONSHIP
constexpr OUStringLiteral ALGO_RSASHA256
constexpr OUStringLiteral ALGO_C14N
constexpr OUStringLiteral ALGO_ECDSASHA256