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/.
11 #include "ooxmlsecparser.hxx"
12 #include <xmlsignaturehelper.hxx>
13 #include <xsecctl.hxx>
15 #include <xmloff/xmlnamespace.hxx>
16 #include <xmloff/xmltoken.hxx>
17 #include <xmloff/xmlimp.hxx>
19 #include <com/sun/star/xml/sax/SAXException.hpp>
21 #include <sal/log.hxx>
23 using namespace com::sun::star
;
25 class OOXMLSecParser::Context
28 friend class OOXMLSecParser
;
29 OOXMLSecParser
& m_rParser
;
31 std::optional
<SvXMLNamespaceMap
> m_pOldNamespaceMap
;
34 Context(OOXMLSecParser
& rParser
,
35 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
37 , m_pOldNamespaceMap(std::move(pOldNamespaceMap
))
41 virtual ~Context() = default;
43 virtual void StartElement(
44 css::uno::Reference
<css::xml::sax::XAttributeList
> const& /*xAttrs*/)
48 virtual void EndElement()
52 virtual std::unique_ptr
<Context
> CreateChildContext(
53 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
54 sal_uInt16
const /*nNamespace*/, OUString
const& /*rName*/);
56 virtual void Characters(OUString
const& /*rChars*/)
61 // it's possible that an unsupported element has an Id attribute and a
62 // ds:Reference digesting it - probably this means XSecController needs to know
63 // about it. (For known elements, the Id attribute is only processed according
65 class OOXMLSecParser::UnknownContext
66 : public OOXMLSecParser::Context
69 UnknownContext(OOXMLSecParser
& rParser
,
70 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
71 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
75 virtual void StartElement(
76 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
78 m_rParser
.HandleIdAttr(xAttrs
);
82 auto OOXMLSecParser::Context::CreateChildContext(
83 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
84 sal_uInt16
const /*nNamespace*/, OUString
const& /*rName*/)
85 -> std::unique_ptr
<Context
>
87 // default: create new base context
88 return std::make_unique
<UnknownContext
>(m_rParser
, std::move(pOldNamespaceMap
));
92 note: anything in ds:Object should be trusted *only* if there is a ds:Reference
93 to it so it is signed (exception: the xades:EncapsulatedX509Certificate).
94 ds:SignedInfo precedes all ds:Object.
96 There may be multiple ds:Signature for purpose of counter-signatures
97 but the way XAdES describes these, only the ds:SignatureValue element
98 would be referenced, so requiring a ds:Reference for anything in
99 ds:Object shouldn't cause issues.
101 class OOXMLSecParser::ReferencedContextImpl
102 : public OOXMLSecParser::Context
108 ReferencedContextImpl(OOXMLSecParser
& rParser
,
109 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
110 bool const isReferenced
)
111 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
112 , m_isReferenced(isReferenced
)
116 OUString
CheckIdAttrReferenced(css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
)
118 OUString
const id(m_rParser
.HandleIdAttr(xAttrs
));
119 if (!id
.isEmpty() && m_rParser
.m_pXSecController
->haveReferenceForId(id
))
121 m_isReferenced
= true;
127 class OOXMLSecParser::DsX509CertificateContext
128 : public OOXMLSecParser::Context
134 DsX509CertificateContext(OOXMLSecParser
& rParser
,
135 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
137 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
142 virtual void Characters(OUString
const& rChars
) override
148 class OOXMLSecParser::DsX509SerialNumberContext
149 : public OOXMLSecParser::Context
155 DsX509SerialNumberContext(OOXMLSecParser
& rParser
,
156 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
158 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
163 virtual void Characters(OUString
const& rChars
) override
169 class OOXMLSecParser::DsX509IssuerNameContext
170 : public OOXMLSecParser::Context
176 DsX509IssuerNameContext(OOXMLSecParser
& rParser
,
177 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
179 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
184 virtual void Characters(OUString
const& rChars
) override
190 class OOXMLSecParser::DsX509IssuerSerialContext
191 : public OOXMLSecParser::Context
194 OUString
& m_rX509IssuerName
;
195 OUString
& m_rX509SerialNumber
;
198 DsX509IssuerSerialContext(OOXMLSecParser
& rParser
,
199 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
200 OUString
& rIssuerName
, OUString
& rSerialNumber
)
201 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
202 , m_rX509IssuerName(rIssuerName
)
203 , m_rX509SerialNumber(rSerialNumber
)
207 virtual std::unique_ptr
<Context
> CreateChildContext(
208 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
209 sal_uInt16
const nNamespace
, OUString
const& rName
) override
211 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "X509IssuerName")
213 return std::make_unique
<DsX509IssuerNameContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_rX509IssuerName
);
215 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "X509SerialNumber")
217 return std::make_unique
<DsX509SerialNumberContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_rX509SerialNumber
);
219 // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
220 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
224 /// can't be sure what is supposed to happen here because the spec is clear as mud
225 class OOXMLSecParser::DsX509DataContext
226 : public OOXMLSecParser::Context
229 // sigh... "No ordering is implied by the above constraints."
230 // so store the ball of mud in vectors and try to figure it out later.
231 std::vector
<std::pair
<OUString
, OUString
>> m_X509IssuerSerials
;
232 std::vector
<OUString
> m_X509Certificates
;
235 DsX509DataContext(OOXMLSecParser
& rParser
,
236 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
237 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
241 virtual void EndElement() override
243 m_rParser
.m_pXSecController
->setX509Data(m_X509IssuerSerials
, m_X509Certificates
);
246 virtual std::unique_ptr
<Context
> CreateChildContext(
247 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
248 sal_uInt16
const nNamespace
, OUString
const& rName
) override
250 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "X509IssuerSerial")
252 m_X509IssuerSerials
.emplace_back();
253 return std::make_unique
<DsX509IssuerSerialContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_X509IssuerSerials
.back().first
, m_X509IssuerSerials
.back().second
);
255 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "X509Certificate")
257 m_X509Certificates
.emplace_back();
258 return std::make_unique
<DsX509CertificateContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_X509Certificates
.back());
260 // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
261 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
265 class OOXMLSecParser::DsKeyInfoContext
266 : public OOXMLSecParser::Context
269 DsKeyInfoContext(OOXMLSecParser
& rParser
,
270 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
271 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
275 virtual void StartElement(
276 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
278 m_rParser
.HandleIdAttr(xAttrs
);
281 virtual std::unique_ptr
<Context
> CreateChildContext(
282 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
283 sal_uInt16
const nNamespace
, OUString
const& rName
) override
285 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "X509Data")
287 return std::make_unique
<DsX509DataContext
>(m_rParser
, std::move(pOldNamespaceMap
));
289 // missing: ds:PGPData
290 // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, ds:SPKIData, ds:MgmtData
291 // (old code would read ds:Transform inside ds:RetrievalMethod but
292 // presumably that was a bug)
293 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
298 class OOXMLSecParser::DsSignatureValueContext
299 : public OOXMLSecParser::Context
305 DsSignatureValueContext(OOXMLSecParser
& rParser
,
306 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
307 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
311 virtual void StartElement(
312 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
314 m_rParser
.HandleIdAttr(xAttrs
);
317 virtual void EndElement() override
319 m_rParser
.m_pXSecController
->setSignatureValue(m_Value
);
322 virtual void Characters(OUString
const& rChars
) override
328 class OOXMLSecParser::DsDigestValueContext
329 : public OOXMLSecParser::Context
335 DsDigestValueContext(OOXMLSecParser
& rParser
,
336 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
338 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
343 virtual void StartElement(
344 css::uno::Reference
<css::xml::sax::XAttributeList
> const& /*xAttrs*/) override
349 virtual void Characters(OUString
const& rChars
) override
355 class OOXMLSecParser::DsDigestMethodContext
356 : public OOXMLSecParser::Context
359 sal_Int32
& m_rReferenceDigestID
;
362 DsDigestMethodContext(OOXMLSecParser
& rParser
,
363 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
364 sal_Int32
& rReferenceDigestID
)
365 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
366 , m_rReferenceDigestID(rReferenceDigestID
)
370 virtual void StartElement(
371 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
373 OUString ouAlgorithm
= xAttrs
->getValueByName(u
"Algorithm"_ustr
);
375 SAL_WARN_IF( ouAlgorithm
.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
376 if (ouAlgorithm
.isEmpty())
379 SAL_WARN_IF( ouAlgorithm
!= ALGO_XMLDSIGSHA1
380 && ouAlgorithm
!= ALGO_XMLDSIGSHA256
381 && ouAlgorithm
!= ALGO_XMLDSIGSHA512
,
382 "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512");
383 if (ouAlgorithm
== ALGO_XMLDSIGSHA1
)
384 m_rReferenceDigestID
= css::xml::crypto::DigestID::SHA1
;
385 else if (ouAlgorithm
== ALGO_XMLDSIGSHA256
)
386 m_rReferenceDigestID
= css::xml::crypto::DigestID::SHA256
;
387 else if (ouAlgorithm
== ALGO_XMLDSIGSHA512
)
388 m_rReferenceDigestID
= css::xml::crypto::DigestID::SHA512
;
390 m_rReferenceDigestID
= 0;
394 class OOXMLSecParser::DsTransformContext
395 : public OOXMLSecParser::Context
401 DsTransformContext(OOXMLSecParser
& rParser
,
402 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
404 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
409 virtual void StartElement(
410 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
412 OUString aAlgorithm
= xAttrs
->getValueByName(u
"Algorithm"_ustr
);
414 if (aAlgorithm
== ALGO_RELATIONSHIP
)
421 class OOXMLSecParser::DsTransformsContext
422 : public OOXMLSecParser::Context
428 DsTransformsContext(OOXMLSecParser
& rParser
,
429 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
431 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
436 virtual std::unique_ptr
<Context
> CreateChildContext(
437 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
438 sal_uInt16
const nNamespace
, OUString
const& rName
) override
440 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "Transform")
442 return std::make_unique
<DsTransformContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_rIsC14N
);
444 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
448 class OOXMLSecParser::DsReferenceContext
449 : public OOXMLSecParser::Context
454 OUString m_DigestValue
;
455 bool m_IsC14N
= false;
456 // Relevant for ODF. The digest algorithm selected by the DigestMethod
457 // element's Algorithm attribute. @see css::xml::crypto::DigestID.
458 sal_Int32 m_nReferenceDigestID
= css::xml::crypto::DigestID::SHA256
;
461 DsReferenceContext(OOXMLSecParser
& rParser
,
462 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
463 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
467 virtual void StartElement(
468 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
470 m_rParser
.HandleIdAttr(xAttrs
);
472 m_URI
= xAttrs
->getValueByName(u
"URI"_ustr
);
473 SAL_WARN_IF(m_URI
.isEmpty(), "xmlsecurity.helper", "URI is empty");
474 // Remember the type of this reference.
475 m_Type
= xAttrs
->getValueByName(u
"Type"_ustr
);
478 virtual void EndElement() override
480 if (m_URI
.startsWith("#"))
483 * remove the first character '#' from the attribute value
485 m_rParser
.m_pXSecController
->addReference(m_URI
.copy(1), m_nReferenceDigestID
, m_Type
);
489 if (m_IsC14N
) // this is determined by nested ds:Transform
491 m_rParser
.m_pXSecController
->addStreamReference(m_URI
, false, m_nReferenceDigestID
);
495 * it must be an octet stream
498 m_rParser
.m_pXSecController
->addStreamReference(m_URI
, true, m_nReferenceDigestID
);
502 m_rParser
.m_pXSecController
->setDigestValue(m_nReferenceDigestID
, m_DigestValue
);
505 virtual std::unique_ptr
<Context
> CreateChildContext(
506 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
507 sal_uInt16
const nNamespace
, OUString
const& rName
) override
509 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "Transforms")
511 return std::make_unique
<DsTransformsContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_IsC14N
);
513 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "DigestMethod")
515 return std::make_unique
<DsDigestMethodContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_nReferenceDigestID
);
517 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "DigestValue")
519 return std::make_unique
<DsDigestValueContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_DigestValue
);
521 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
525 class OOXMLSecParser::DsSignatureMethodContext
526 : public OOXMLSecParser::Context
529 DsSignatureMethodContext(OOXMLSecParser
& rParser
,
530 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
531 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
535 virtual void StartElement(
536 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
538 OUString ouAlgorithm
= xAttrs
->getValueByName(u
"Algorithm"_ustr
);
539 if (ouAlgorithm
== ALGO_ECDSASHA1
|| ouAlgorithm
== ALGO_ECDSASHA256
540 || ouAlgorithm
== ALGO_ECDSASHA512
)
542 m_rParser
.m_pXSecController
->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA
);
547 class OOXMLSecParser::DsSignedInfoContext
548 : public OOXMLSecParser::Context
551 DsSignedInfoContext(OOXMLSecParser
& rParser
,
552 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
553 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
557 virtual void StartElement(
558 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
560 m_rParser
.HandleIdAttr(xAttrs
);
563 virtual void EndElement() override
565 m_rParser
.m_pXSecController
->setReferenceCount();
568 virtual std::unique_ptr
<Context
> CreateChildContext(
569 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
570 sal_uInt16
const nNamespace
, OUString
const& rName
) override
572 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "SignatureMethod")
574 return std::make_unique
<DsSignatureMethodContext
>(m_rParser
, std::move(pOldNamespaceMap
));
576 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "Reference")
578 return std::make_unique
<DsReferenceContext
>(m_rParser
, std::move(pOldNamespaceMap
));
580 // missing: ds:CanonicalizationMethod
581 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
585 class OOXMLSecParser::XadesCertDigestContext
586 : public OOXMLSecParser::Context
589 OUString
& m_rDigestValue
;
590 sal_Int32
& m_rReferenceDigestID
;
593 XadesCertDigestContext(OOXMLSecParser
& rParser
,
594 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
595 OUString
& rDigestValue
, sal_Int32
& rReferenceDigestID
)
596 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
597 , m_rDigestValue(rDigestValue
)
598 , m_rReferenceDigestID(rReferenceDigestID
)
602 virtual std::unique_ptr
<Context
> CreateChildContext(
603 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
604 sal_uInt16
const nNamespace
, OUString
const& rName
) override
606 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "DigestMethod")
608 return std::make_unique
<DsDigestMethodContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_rReferenceDigestID
);
610 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "DigestValue")
612 return std::make_unique
<DsDigestValueContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_rDigestValue
);
614 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
618 class OOXMLSecParser::XadesCertContext
619 : public OOXMLSecParser::ReferencedContextImpl
622 sal_Int32 m_nReferenceDigestID
= css::xml::crypto::DigestID::SHA1
;
623 OUString m_CertDigest
;
624 OUString m_X509IssuerName
;
625 OUString m_X509SerialNumber
;
628 XadesCertContext(OOXMLSecParser
& rParser
,
629 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
630 bool const isReferenced
)
631 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
635 virtual void EndElement() override
639 m_rParser
.m_pXSecController
->setX509CertDigest(m_CertDigest
, m_nReferenceDigestID
, m_X509IssuerName
, m_X509SerialNumber
);
643 SAL_INFO("xmlsecurity.helper", "ignoring unsigned xades:Cert");
647 virtual std::unique_ptr
<Context
> CreateChildContext(
648 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
649 sal_uInt16
const nNamespace
, OUString
const& rName
) override
651 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "CertDigest")
653 return std::make_unique
<XadesCertDigestContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_CertDigest
, m_nReferenceDigestID
);
655 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "IssuerSerial")
657 return std::make_unique
<DsX509IssuerSerialContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_X509IssuerName
, m_X509SerialNumber
);
659 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
663 class OOXMLSecParser::XadesSigningCertificateContext
664 : public OOXMLSecParser::ReferencedContextImpl
667 XadesSigningCertificateContext(OOXMLSecParser
& rParser
,
668 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
669 bool const isReferenced
)
670 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
674 virtual std::unique_ptr
<Context
> CreateChildContext(
675 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
676 sal_uInt16
const nNamespace
, OUString
const& rName
) override
678 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "Cert")
680 return std::make_unique
<XadesCertContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
682 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
686 class OOXMLSecParser::XadesSigningTimeContext
687 : public OOXMLSecParser::ReferencedContextImpl
693 XadesSigningTimeContext(OOXMLSecParser
& rParser
,
694 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
695 bool const isReferenced
)
696 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
700 virtual void EndElement() override
704 m_rParser
.m_pXSecController
->setDate(u
""_ustr
, m_Value
);
708 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SigningTime");
712 virtual void Characters(OUString
const& rChars
) override
718 class OOXMLSecParser::XadesSignedSignaturePropertiesContext
719 : public OOXMLSecParser::ReferencedContextImpl
722 XadesSignedSignaturePropertiesContext(OOXMLSecParser
& rParser
,
723 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
724 bool const isReferenced
)
725 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
729 virtual void StartElement(
730 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
732 CheckIdAttrReferenced(xAttrs
);
735 virtual std::unique_ptr
<Context
> CreateChildContext(
736 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
737 sal_uInt16
const nNamespace
, OUString
const& rName
) override
739 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "SigningTime")
741 return std::make_unique
<XadesSigningTimeContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
743 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "SigningCertificate")
745 return std::make_unique
<XadesSigningCertificateContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
747 // missing: xades:SignaturePolicyIdentifier, xades:SignatureProductionPlace, xades:SignerRole
748 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
752 class OOXMLSecParser::XadesSignedPropertiesContext
753 : public OOXMLSecParser::ReferencedContextImpl
756 XadesSignedPropertiesContext(OOXMLSecParser
& rParser
,
757 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
758 bool const isReferenced
)
759 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
763 virtual void StartElement(
764 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
766 CheckIdAttrReferenced(xAttrs
);
769 virtual std::unique_ptr
<Context
> CreateChildContext(
770 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
771 sal_uInt16
const nNamespace
, OUString
const& rName
) override
773 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "SignedSignatureProperties")
775 return std::make_unique
<XadesSignedSignaturePropertiesContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
777 // missing: xades:SignedDataObjectProperties
778 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
782 class OOXMLSecParser::XadesQualifyingPropertiesContext
783 : public OOXMLSecParser::ReferencedContextImpl
786 XadesQualifyingPropertiesContext(OOXMLSecParser
& rParser
,
787 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
788 bool const isReferenced
)
789 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
793 virtual void StartElement(
794 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
796 CheckIdAttrReferenced(xAttrs
);
799 virtual std::unique_ptr
<Context
> CreateChildContext(
800 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
801 sal_uInt16
const nNamespace
, OUString
const& rName
) override
803 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "SignedProperties")
805 return std::make_unique
<XadesSignedPropertiesContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
807 // missing: xades:UnsignedSignatureProperties
808 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
812 class OOXMLSecParser::MsodigsigSetupIDContext
813 : public OOXMLSecParser::Context
819 MsodigsigSetupIDContext(OOXMLSecParser
& rParser
,
820 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
822 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
827 virtual void Characters(OUString
const& rChars
) override
833 class OOXMLSecParser::MsodigsigSignatureCommentsContext
834 : public OOXMLSecParser::Context
840 MsodigsigSignatureCommentsContext(OOXMLSecParser
& rParser
,
841 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
843 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
848 virtual void Characters(OUString
const& rChars
) override
854 class OOXMLSecParser::MsodigsigSignatureInfoV1Context
855 : public OOXMLSecParser::ReferencedContextImpl
859 OUString m_SignatureComments
;
862 MsodigsigSignatureInfoV1Context(OOXMLSecParser
& rParser
,
863 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
864 bool const isReferenced
)
865 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
869 virtual void StartElement(
870 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
872 CheckIdAttrReferenced(xAttrs
);
875 virtual std::unique_ptr
<Context
> CreateChildContext(
876 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
877 sal_uInt16
const nNamespace
, OUString
const& rName
) override
879 if (nNamespace
== XML_NAMESPACE_MSODIGSIG
&& rName
== "SetupID")
881 return std::make_unique
<MsodigsigSetupIDContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_SetupID
);
883 if (nNamespace
== XML_NAMESPACE_MSODIGSIG
&& rName
== "SignatureComments")
885 return std::make_unique
<MsodigsigSignatureCommentsContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_SignatureComments
);
887 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
890 virtual void EndElement() override
894 if (!m_SetupID
.isEmpty())
896 m_rParser
.m_pXSecController
->setSignatureLineId(m_SetupID
);
898 if (!m_SignatureComments
.isEmpty())
900 m_rParser
.m_pXSecController
->setDescription(u
""_ustr
, m_SignatureComments
);
906 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureInfoV1");
911 class OOXMLSecParser::MdssiValueContext
912 : public OOXMLSecParser::Context
918 MdssiValueContext(OOXMLSecParser
& rParser
,
919 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
921 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
926 virtual void Characters(OUString
const& rChars
) override
932 class OOXMLSecParser::MdssiSignatureTimeContext
933 : public OOXMLSecParser::Context
939 MdssiSignatureTimeContext(OOXMLSecParser
& rParser
,
940 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
942 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
947 virtual std::unique_ptr
<Context
> CreateChildContext(
948 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
949 sal_uInt16
const nNamespace
, OUString
const& rName
) override
951 if (nNamespace
== XML_NAMESPACE_MDSSI
&& rName
== "Value")
953 return std::make_unique
<MdssiValueContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_rValue
);
955 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
960 class OOXMLSecParser::DsSignaturePropertyContext
961 : public OOXMLSecParser::ReferencedContextImpl
964 enum class SignatureProperty
{ Unknown
, Date
, Info
};
965 SignatureProperty m_Property
= SignatureProperty::Unknown
;
970 DsSignaturePropertyContext(OOXMLSecParser
& rParser
,
971 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
972 bool const isReferenced
)
973 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
977 virtual void StartElement(
978 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
980 m_Id
= CheckIdAttrReferenced(xAttrs
);
983 virtual void EndElement() override
989 case SignatureProperty::Unknown
:
990 SAL_INFO("xmlsecurity.helper", "Unknown property in ds:Object ignored");
992 case SignatureProperty::Info
:
993 break; // handled by child context
994 case SignatureProperty::Date
:
995 m_rParser
.m_pXSecController
->setDate(m_Id
, m_Value
);
1001 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureProperty");
1005 virtual std::unique_ptr
<Context
> CreateChildContext(
1006 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1007 sal_uInt16
const nNamespace
, OUString
const& rName
) override
1009 if (nNamespace
== XML_NAMESPACE_MDSSI
&& rName
== "SignatureTime")
1011 m_Property
= SignatureProperty::Date
;
1012 return std::make_unique
<MdssiSignatureTimeContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_Value
);
1014 if (nNamespace
== XML_NAMESPACE_MSODIGSIG
&& rName
== "SignatureInfoV1")
1016 return std::make_unique
<MsodigsigSignatureInfoV1Context
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
1018 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
1022 class OOXMLSecParser::DsSignaturePropertiesContext
1023 : public OOXMLSecParser::ReferencedContextImpl
1026 DsSignaturePropertiesContext(OOXMLSecParser
& rParser
,
1027 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1028 bool const isReferenced
)
1029 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
1033 virtual void StartElement(
1034 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
1036 CheckIdAttrReferenced(xAttrs
);
1039 virtual std::unique_ptr
<Context
> CreateChildContext(
1040 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1041 sal_uInt16
const nNamespace
, OUString
const& rName
) override
1043 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "SignatureProperty")
1045 return std::make_unique
<DsSignaturePropertyContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
1047 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
1051 class OOXMLSecParser::DsManifestContext
1052 : public OOXMLSecParser::ReferencedContextImpl
1055 DsManifestContext(OOXMLSecParser
& rParser
,
1056 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1057 bool const isReferenced
)
1058 : ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), isReferenced
)
1062 virtual void StartElement(
1063 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
1065 CheckIdAttrReferenced(xAttrs
);
1070 virtual void EndElement() override
1072 m_rParser
.m_pXSecController
->setReferenceCount();
1076 virtual std::unique_ptr
<Context
> CreateChildContext(
1077 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1078 sal_uInt16
const nNamespace
, OUString
const& rName
) override
1080 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "Reference")
1082 return std::make_unique
<DsReferenceContext
>(m_rParser
, std::move(pOldNamespaceMap
));
1084 // missing: ds:CanonicalizationMethod
1085 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
1089 class OOXMLSecParser::DsObjectContext
1090 : public OOXMLSecParser::ReferencedContextImpl
1092 enum class Mode
{ Default
, ValidSignatureLineImage
, InvalidSignatureLineImage
};
1093 Mode m_Mode
= Mode::Default
;
1097 DsObjectContext(OOXMLSecParser
& rParser
,
1098 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
1099 // init with "false" here - the Signature element can't be referenced by its child
1100 : OOXMLSecParser::ReferencedContextImpl(rParser
, std::move(pOldNamespaceMap
), false)
1104 virtual void StartElement(
1105 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
1107 OUString
const id(CheckIdAttrReferenced(xAttrs
));
1108 if (id
== "idValidSigLnImg")
1110 m_Mode
= Mode::ValidSignatureLineImage
;
1112 else if (id
== "idInvalidSigLnImg")
1114 m_Mode
= Mode::InvalidSignatureLineImage
;
1118 virtual void EndElement() override
1122 case Mode::ValidSignatureLineImage
:
1125 m_rParser
.m_pXSecController
->setValidSignatureImage(m_Value
);
1129 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineValidImage");
1132 case Mode::InvalidSignatureLineImage
:
1135 m_rParser
.m_pXSecController
->setInvalidSignatureImage(m_Value
);
1139 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineInvalidImage");
1147 virtual void Characters(OUString
const& rChars
) override
1152 virtual std::unique_ptr
<Context
> CreateChildContext(
1153 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1154 sal_uInt16
const nNamespace
, OUString
const& rName
) override
1156 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "SignatureProperties")
1158 return std::make_unique
<DsSignaturePropertiesContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
1160 if (nNamespace
== XML_NAMESPACE_XADES132
&& rName
== "QualifyingProperties")
1162 return std::make_unique
<XadesQualifyingPropertiesContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
1164 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "Manifest")
1166 return std::make_unique
<DsManifestContext
>(m_rParser
, std::move(pOldNamespaceMap
), m_isReferenced
);
1168 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
1172 class OOXMLSecParser::DsSignatureContext
1173 : public OOXMLSecParser::Context
1176 DsSignatureContext(OOXMLSecParser
& rParser
,
1177 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
)
1178 : OOXMLSecParser::Context(rParser
, std::move(pOldNamespaceMap
))
1182 virtual void StartElement(
1183 css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
) override
1185 OUString
const ouIdAttr(m_rParser
.HandleIdAttr(xAttrs
));
1186 m_rParser
.m_rXMLSignatureHelper
.StartVerifySignatureElement();
1187 m_rParser
.m_pXSecController
->addSignature();
1188 if (!ouIdAttr
.isEmpty())
1190 m_rParser
.m_pXSecController
->setId( ouIdAttr
);
1194 virtual std::unique_ptr
<Context
> CreateChildContext(
1195 std::optional
<SvXMLNamespaceMap
>&& pOldNamespaceMap
,
1196 sal_uInt16
const nNamespace
, OUString
const& rName
) override
1198 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "SignedInfo")
1200 return std::make_unique
<DsSignedInfoContext
>(m_rParser
, std::move(pOldNamespaceMap
));
1202 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "SignatureValue")
1204 return std::make_unique
<DsSignatureValueContext
>(m_rParser
, std::move(pOldNamespaceMap
));
1206 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "KeyInfo")
1208 return std::make_unique
<DsKeyInfoContext
>(m_rParser
, std::move(pOldNamespaceMap
));
1210 if (nNamespace
== XML_NAMESPACE_DS
&& rName
== "Object")
1212 return std::make_unique
<DsObjectContext
>(m_rParser
, std::move(pOldNamespaceMap
));
1214 return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap
), nNamespace
, rName
);
1219 OOXMLSecParser::OOXMLSecParser(XMLSignatureHelper
& rXMLSignatureHelper
, XSecController
* pXSecController
)
1220 : m_pNamespaceMap(SvXMLNamespaceMap())
1221 , m_pXSecController(pXSecController
)
1222 ,m_rXMLSignatureHelper(rXMLSignatureHelper
)
1224 using namespace xmloff::token
;
1225 m_pNamespaceMap
->Add( GetXMLToken(XML_XML
), GetXMLToken(XML_N_XML
), XML_NAMESPACE_XML
);
1226 m_pNamespaceMap
->Add( u
"_ds"_ustr
, GetXMLToken(XML_N_DS
), XML_NAMESPACE_DS
);
1227 m_pNamespaceMap
->Add( u
"_xades132"_ustr
, GetXMLToken(XML_N_XADES132
), XML_NAMESPACE_XADES132
);
1228 m_pNamespaceMap
->Add( u
"_xades141"_ustr
, GetXMLToken(XML_N_XADES141
), XML_NAMESPACE_XADES141
);
1229 m_pNamespaceMap
->Add( u
"_dc"_ustr
, GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
1230 m_pNamespaceMap
->Add( u
"_mdssi"_ustr
, NS_MDSSI
, XML_NAMESPACE_MDSSI
);
1231 m_pNamespaceMap
->Add( u
"_msodigsig"_ustr
, u
"http://schemas.microsoft.com/office/2006/digsig"_ustr
, XML_NAMESPACE_MSODIGSIG
);
1232 m_pNamespaceMap
->Add( u
"_office_libo"_ustr
,
1233 GetXMLToken(XML_N_LO_EXT
), XML_NAMESPACE_LO_EXT
);
1236 OOXMLSecParser::~OOXMLSecParser()
1240 OUString
OOXMLSecParser::HandleIdAttr(css::uno::Reference
<css::xml::sax::XAttributeList
> const& xAttrs
)
1242 OUString
const aId
= xAttrs
->getValueByName(u
"Id"_ustr
);
1245 m_pXSecController
->collectToVerify(aId
);
1250 void SAL_CALL
OOXMLSecParser::startDocument()
1252 if (m_xNextHandler
.is())
1253 m_xNextHandler
->startDocument();
1256 void SAL_CALL
OOXMLSecParser::endDocument()
1258 if (m_xNextHandler
.is())
1259 m_xNextHandler
->endDocument();
1262 void SAL_CALL
OOXMLSecParser::startElement(const OUString
& rName
, const uno::Reference
<xml::sax::XAttributeList
>& xAttribs
)
1264 assert(m_pNamespaceMap
);
1265 std::optional
<SvXMLNamespaceMap
> pRewindMap(
1266 SvXMLImport::processNSAttributes(m_pNamespaceMap
, nullptr, xAttribs
));
1269 sal_uInt16
const nPrefix(m_pNamespaceMap
->GetKeyByAttrName(rName
, &localName
));
1271 std::unique_ptr
<Context
> pContext
;
1273 if (m_ContextStack
.empty())
1275 if (nPrefix
!= XML_NAMESPACE_DS
|| localName
!= "Signature")
1277 throw css::xml::sax::SAXException(
1278 u
"xmlsecurity: unexpected root element"_ustr
, nullptr,
1282 pContext
.reset(new DsSignatureContext(*this, std::move(pRewindMap
)));
1287 pContext
= m_ContextStack
.top()->CreateChildContext(
1288 std::move(pRewindMap
), nPrefix
, localName
);
1291 m_ContextStack
.push(std::move(pContext
));
1293 m_ContextStack
.top()->StartElement(xAttribs
);
1295 if (m_xNextHandler
.is())
1297 m_xNextHandler
->startElement(rName
, xAttribs
);
1302 void SAL_CALL
OOXMLSecParser::endElement(const OUString
& rName
)
1304 assert(!m_ContextStack
.empty()); // this should be checked by sax parser?
1306 m_ContextStack
.top()->EndElement();
1308 if (m_xNextHandler
.is())
1310 m_xNextHandler
->endElement(rName
);
1313 if (m_ContextStack
.top()->m_pOldNamespaceMap
)
1315 m_pNamespaceMap
= std::move(m_ContextStack
.top()->m_pOldNamespaceMap
);
1317 m_ContextStack
.pop();
1320 void SAL_CALL
OOXMLSecParser::characters(const OUString
& rChars
)
1322 assert(!m_ContextStack
.empty()); // this should be checked by sax parser?
1323 m_ContextStack
.top()->Characters(rChars
);
1325 if (m_xNextHandler
.is())
1326 m_xNextHandler
->characters(rChars
);
1329 void SAL_CALL
OOXMLSecParser::ignorableWhitespace(const OUString
& rWhitespace
)
1331 if (m_xNextHandler
.is())
1332 m_xNextHandler
->ignorableWhitespace(rWhitespace
);
1335 void SAL_CALL
OOXMLSecParser::processingInstruction(const OUString
& rTarget
, const OUString
& rData
)
1337 if (m_xNextHandler
.is())
1338 m_xNextHandler
->processingInstruction(rTarget
, rData
);
1341 void SAL_CALL
OOXMLSecParser::setDocumentLocator(const uno::Reference
<xml::sax::XLocator
>& xLocator
)
1343 if (m_xNextHandler
.is())
1344 m_xNextHandler
->setDocumentLocator(xLocator
);
1347 void SAL_CALL
OOXMLSecParser::initialize(const uno::Sequence
<uno::Any
>& rArguments
)
1349 rArguments
[0] >>= m_xNextHandler
;
1352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */