tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / xmlsecurity / source / helper / ooxmlsecparser.cxx
blobff1802e02943fd8d325b31af37085f05448cd29b
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 */
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
27 protected:
28 friend class OOXMLSecParser;
29 OOXMLSecParser & m_rParser;
30 private:
31 std::optional<SvXMLNamespaceMap> m_pOldNamespaceMap;
33 public:
34 Context(OOXMLSecParser& rParser,
35 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap)
36 : m_rParser(rParser)
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
64 // to the schema.)
65 class OOXMLSecParser::UnknownContext
66 : public OOXMLSecParser::Context
68 public:
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));
91 /**
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
104 protected:
105 bool m_isReferenced;
107 public:
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;
123 return id;
127 class OOXMLSecParser::DsX509CertificateContext
128 : public OOXMLSecParser::Context
130 private:
131 OUString & m_rValue;
133 public:
134 DsX509CertificateContext(OOXMLSecParser& rParser,
135 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
136 OUString& rValue)
137 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
138 , m_rValue(rValue)
142 virtual void Characters(OUString const& rChars) override
144 m_rValue += rChars;
148 class OOXMLSecParser::DsX509SerialNumberContext
149 : public OOXMLSecParser::Context
151 private:
152 OUString & m_rValue;
154 public:
155 DsX509SerialNumberContext(OOXMLSecParser& rParser,
156 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
157 OUString& rValue)
158 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
159 , m_rValue(rValue)
163 virtual void Characters(OUString const& rChars) override
165 m_rValue += rChars;
169 class OOXMLSecParser::DsX509IssuerNameContext
170 : public OOXMLSecParser::Context
172 private:
173 OUString & m_rValue;
175 public:
176 DsX509IssuerNameContext(OOXMLSecParser& rParser,
177 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
178 OUString& rValue)
179 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
180 , m_rValue(rValue)
184 virtual void Characters(OUString const& rChars) override
186 m_rValue += rChars;
190 class OOXMLSecParser::DsX509IssuerSerialContext
191 : public OOXMLSecParser::Context
193 private:
194 OUString & m_rX509IssuerName;
195 OUString & m_rX509SerialNumber;
197 public:
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
228 private:
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;
234 public:
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
268 public:
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
301 private:
302 OUString m_Value;
304 public:
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
324 m_Value += rChars;
328 class OOXMLSecParser::DsDigestValueContext
329 : public OOXMLSecParser::Context
331 private:
332 OUString & m_rValue;
334 public:
335 DsDigestValueContext(OOXMLSecParser& rParser,
336 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
337 OUString & rValue)
338 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
339 , m_rValue(rValue)
343 virtual void StartElement(
344 css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override
346 m_rValue.clear();
349 virtual void Characters(OUString const& rChars) override
351 m_rValue += rChars;
355 class OOXMLSecParser::DsDigestMethodContext
356 : public OOXMLSecParser::Context
358 private:
359 sal_Int32 & m_rReferenceDigestID;
361 public:
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())
377 return;
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;
389 else
390 m_rReferenceDigestID = 0;
394 class OOXMLSecParser::DsTransformContext
395 : public OOXMLSecParser::Context
397 private:
398 bool & m_rIsC14N;
400 public:
401 DsTransformContext(OOXMLSecParser& rParser,
402 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
403 bool& rIsC14N)
404 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
405 , m_rIsC14N(rIsC14N)
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)
416 m_rIsC14N = true;
421 class OOXMLSecParser::DsTransformsContext
422 : public OOXMLSecParser::Context
424 private:
425 bool & m_rIsC14N;
427 public:
428 DsTransformsContext(OOXMLSecParser& rParser,
429 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
430 bool& rIsC14N)
431 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
432 , m_rIsC14N(rIsC14N)
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
451 private:
452 OUString m_URI;
453 OUString m_Type;
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;
460 public:
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);
487 else
489 if (m_IsC14N) // this is determined by nested ds:Transform
491 m_rParser.m_pXSecController->addStreamReference(m_URI, false, m_nReferenceDigestID);
493 else
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
528 public:
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
550 public:
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
588 private:
589 OUString & m_rDigestValue;
590 sal_Int32 & m_rReferenceDigestID;
592 public:
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
621 private:
622 sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
623 OUString m_CertDigest;
624 OUString m_X509IssuerName;
625 OUString m_X509SerialNumber;
627 public:
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
637 if (m_isReferenced)
639 m_rParser.m_pXSecController->setX509CertDigest(m_CertDigest, m_nReferenceDigestID, m_X509IssuerName, m_X509SerialNumber);
641 else
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
666 public:
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
689 private:
690 OUString m_Value;
692 public:
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
702 if (m_isReferenced)
704 m_rParser.m_pXSecController->setDate(u""_ustr, m_Value);
706 else
708 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SigningTime");
712 virtual void Characters(OUString const& rChars) override
714 m_Value += rChars;
718 class OOXMLSecParser::XadesSignedSignaturePropertiesContext
719 : public OOXMLSecParser::ReferencedContextImpl
721 public:
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
755 public:
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
785 public:
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
815 private:
816 OUString & m_rValue;
818 public:
819 MsodigsigSetupIDContext(OOXMLSecParser& rParser,
820 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
821 OUString& rValue)
822 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
823 , m_rValue(rValue)
827 virtual void Characters(OUString const& rChars) override
829 m_rValue += rChars;
833 class OOXMLSecParser::MsodigsigSignatureCommentsContext
834 : public OOXMLSecParser::Context
836 private:
837 OUString & m_rValue;
839 public:
840 MsodigsigSignatureCommentsContext(OOXMLSecParser& rParser,
841 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
842 OUString& rValue)
843 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
844 , m_rValue(rValue)
848 virtual void Characters(OUString const& rChars) override
850 m_rValue += rChars;
854 class OOXMLSecParser::MsodigsigSignatureInfoV1Context
855 : public OOXMLSecParser::ReferencedContextImpl
857 private:
858 OUString m_SetupID;
859 OUString m_SignatureComments;
861 public:
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
892 if (m_isReferenced)
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);
904 else
906 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureInfoV1");
911 class OOXMLSecParser::MdssiValueContext
912 : public OOXMLSecParser::Context
914 private:
915 OUString & m_rValue;
917 public:
918 MdssiValueContext(OOXMLSecParser& rParser,
919 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
920 OUString& rValue)
921 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
922 , m_rValue(rValue)
926 virtual void Characters(OUString const& rChars) override
928 m_rValue += rChars;
932 class OOXMLSecParser::MdssiSignatureTimeContext
933 : public OOXMLSecParser::Context
935 private:
936 OUString & m_rValue;
938 public:
939 MdssiSignatureTimeContext(OOXMLSecParser& rParser,
940 std::optional<SvXMLNamespaceMap>&& pOldNamespaceMap,
941 OUString& rValue)
942 : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
943 , m_rValue(rValue)
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
963 private:
964 enum class SignatureProperty { Unknown, Date, Info };
965 SignatureProperty m_Property = SignatureProperty::Unknown;
966 OUString m_Id;
967 OUString m_Value;
969 public:
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
985 if (m_isReferenced)
987 switch (m_Property)
989 case SignatureProperty::Unknown:
990 SAL_INFO("xmlsecurity.helper", "Unknown property in ds:Object ignored");
991 break;
992 case SignatureProperty::Info:
993 break; // handled by child context
994 case SignatureProperty::Date:
995 m_rParser.m_pXSecController->setDate(m_Id, m_Value);
996 break;
999 else
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
1025 public:
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
1054 public:
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);
1068 #if 0
1070 virtual void EndElement() override
1072 m_rParser.m_pXSecController->setReferenceCount();
1074 #endif
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;
1094 OUString m_Value;
1096 public:
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
1120 switch (m_Mode)
1122 case Mode::ValidSignatureLineImage:
1123 if (m_isReferenced)
1125 m_rParser.m_pXSecController->setValidSignatureImage(m_Value);
1127 else
1129 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineValidImage");
1131 break;
1132 case Mode::InvalidSignatureLineImage:
1133 if (m_isReferenced)
1135 m_rParser.m_pXSecController->setInvalidSignatureImage(m_Value);
1137 else
1139 SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineInvalidImage");
1141 break;
1142 case Mode::Default:
1143 break;
1147 virtual void Characters(OUString const& rChars) override
1149 m_Value += rChars;
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
1175 public:
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);
1243 if (!aId.isEmpty())
1245 m_pXSecController->collectToVerify(aId);
1247 return 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));
1268 OUString localName;
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,
1279 css::uno::Any());
1282 pContext.reset(new DsSignatureContext(*this, std::move(pRewindMap)));
1285 else
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: */