Get the style color and number just once
[LibreOffice.git] / xmlsecurity / source / helper / xsecctl.cxx
blobd83f0726ca5194bf921adbd07503f98e35085202
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_gpgme.h>
22 #include <utility>
23 #include <xsecctl.hxx>
24 #include <documentsignaturehelper.hxx>
25 #include <framework/saxeventkeeperimpl.hxx>
26 #include <xmlsec/xmldocumentwrapper_xmlsecimpl.hxx>
27 #if HAVE_FEATURE_GPGME
28 # include <gpg/xmlsignature_gpgimpl.hxx>
29 #endif
31 #include <com/sun/star/xml/crypto/sax/XMissionTaker.hpp>
32 #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <com/sun/star/xml/sax/XParser.hpp>
35 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
37 #include <comphelper/attributelist.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <rtl/ref.hxx>
40 #include <sal/log.hxx>
41 #include <unotools/datetime.hxx>
42 #include "ooxmlsecexporter.hxx"
43 #include <UriBindingHelper.hxx>
45 using namespace com::sun::star;
47 namespace
49 const OUString & getDigestURI(sal_Int32 nID)
51 switch( nID )
53 case css::xml::crypto::DigestID::SHA1:
54 return ALGO_XMLDSIGSHA1;
55 case css::xml::crypto::DigestID::SHA256:
56 return ALGO_XMLDSIGSHA256;
57 case css::xml::crypto::DigestID::SHA512:
58 return ALGO_XMLDSIGSHA512;
59 default:
60 return ALGO_XMLDSIGSHA1;
63 OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_Int32 nDigestID)
65 OUString aRet;
67 if (eAlgorithm == svl::crypto::SignatureMethodAlgorithm::ECDSA)
69 switch (nDigestID)
71 case css::xml::crypto::DigestID::SHA1:
72 aRet = ALGO_ECDSASHA1;
73 break;
74 case css::xml::crypto::DigestID::SHA256:
75 aRet = ALGO_ECDSASHA256;
76 break;
77 case css::xml::crypto::DigestID::SHA512:
78 aRet = ALGO_ECDSASHA512;
79 break;
80 default:
81 aRet = ALGO_ECDSASHA1;
82 break;
85 if (!aRet.isEmpty())
86 return aRet;
88 switch (nDigestID)
90 case css::xml::crypto::DigestID::SHA1:
91 return ALGO_RSASHA1;
92 case css::xml::crypto::DigestID::SHA256:
93 return ALGO_RSASHA256;
94 case css::xml::crypto::DigestID::SHA512:
95 return ALGO_RSASHA512;
96 default:
97 return ALGO_RSASHA1;
102 XSecController::XSecController( css::uno::Reference<css::uno::XComponentContext> xCtx )
103 : mxCtx(std::move(xCtx))
104 , m_nNextSecurityId(1)
105 , m_bIsPreviousNodeInitializable(false)
106 , m_bIsSAXEventKeeperConnected(false)
107 , m_bIsCollectingElement(false)
108 , m_bIsBlocking(false)
109 , m_eStatusOfSecurityComponents(InitializationState::UNINITIALIZED)
110 , m_bIsSAXEventKeeperSticky(false)
111 , m_nReservedSignatureId(0)
112 , m_bVerifyCurrentSignature(false)
116 XSecController::~XSecController()
122 * private methods
124 int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const
125 /****** XSecController/findSignatureInfor *************************************
127 * NAME
128 * findSignatureInfor -- find SignatureInformation struct for a particular
129 * signature
131 * SYNOPSIS
132 * index = findSignatureInfor( nSecurityId );
134 * INPUTS
135 * nSecurityId - the signature's id
137 * RESULT
138 * index - the index of the signature, or -1 when no such signature
139 * existing
140 ******************************************************************************/
142 int i;
143 int size = m_vInternalSignatureInformations.size();
145 for (i=0; i<size; ++i)
147 if (m_vInternalSignatureInformations[i].signatureInfor.nSecurityId == nSecurityId)
149 return i;
153 return -1;
156 void XSecController::createXSecComponent( )
157 /****** XSecController/createXSecComponent ************************************
159 * NAME
160 * bResult = createXSecComponent -- creates xml security components
162 * FUNCTION
163 * Creates xml security components, including:
164 * 1. an xml signature bridge component
165 * 2. an XMLDocumentWrapper component
166 * 3. a SAXEventKeeper component
167 ******************************************************************************/
170 * marks all security components are not available.
172 m_eStatusOfSecurityComponents = InitializationState::FAILTOINITIALIZED;
173 m_xXMLSignature = nullptr;
174 m_xXMLDocumentWrapper = nullptr;
175 m_xSAXEventKeeper = nullptr;
177 css::uno::Reference< css::lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
179 #if HAVE_FEATURE_GPGME
180 uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, css::uno::UNO_QUERY );
181 if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
182 m_xXMLSignature.set(new XMLSignature_GpgImpl());
183 else // xmlsec or mscrypt
184 #endif
185 m_xXMLSignature.set(xMCF->createInstanceWithContext(u"com.sun.star.xml.crypto.XMLSignature"_ustr, mxCtx), css::uno::UNO_QUERY);
187 bool bSuccess = m_xXMLSignature.is();
188 if ( bSuccess )
190 * XMLSignature created successfully.
192 m_xXMLDocumentWrapper = new XMLDocumentWrapper_XmlSecImpl();
194 bSuccess &= m_xXMLDocumentWrapper.is();
195 if ( bSuccess )
196 m_xSAXEventKeeper = new SAXEventKeeperImpl();
198 bSuccess &= m_xSAXEventKeeper.is();
200 if (!bSuccess)
202 * SAXEventKeeper created successfully.
204 return;
206 css::uno::Sequence <css::uno::Any> arg{ css::uno::Any(
207 uno::Reference<xml::wrapper::XXMLDocumentWrapper>(m_xXMLDocumentWrapper)) };
208 m_xSAXEventKeeper->initialize(arg);
210 css::uno::Reference< css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener >
211 xStatusChangeListener = this;
213 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
215 m_eStatusOfSecurityComponents = InitializationState::INITIALIZED;
218 bool XSecController::chainOn()
219 /****** XSecController/chainOn ************************************************
221 * NAME
222 * chainOn -- tries to connect the SAXEventKeeper with the SAX chain.
224 * SYNOPSIS
225 * bJustChainingOn = chainOn();
227 * FUNCTION
228 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
229 * creates xml security components, and chains the SAXEventKeeper into
230 * the SAX chain.
231 * Before being chained in, the SAXEventKeeper needs to receive all
232 * missed key SAX events, which can promise the DOM tree buffered by the
233 * SAXEventKeeper has the same structure with the original document.
235 * RESULT
236 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
237 * SAX chain.
239 * NOTES
240 * Sometimes, the last key SAX event can't be transferred to the
241 * SAXEventKeeper together.
242 * For instance, at the time a referenced element is detected, the
243 * startElement event has already been reserved by the ElementStackKeeper.
244 * Meanwhile, an ElementCollector needs to be created before the
245 * SAXEventKeeper receives that startElement event.
246 * So for the SAXEventKeeper, it needs to receive all missed key SAX
247 * events except that startElement event, then adds a new
248 * ElementCollector, then receives that startElement event.
249 ******************************************************************************/
251 bool rc = false;
253 if (!m_bIsSAXEventKeeperSticky && !m_bIsSAXEventKeeperConnected)
255 if ( m_eStatusOfSecurityComponents == InitializationState::UNINITIALIZED )
257 createXSecComponent();
260 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
262 * if all security components are ready, chains on the SAXEventKeeper
266 * disconnect the SAXEventKeeper with its current output handler,
267 * to make sure no SAX event is forwarded during the connecting
268 * phase.
270 m_xSAXEventKeeper->setNextHandler( nullptr );
272 css::uno::Reference< css::xml::sax::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper);
275 * connects the previous document handler on the SAX chain
277 if ( m_xPreviousNodeOnSAXChain.is() )
279 if ( m_bIsPreviousNodeInitializable )
281 css::uno::Reference< css::lang::XInitialization > xInitialization
282 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
284 xInitialization->initialize({ css::uno::Any(xSEKHandler) });
286 else
288 css::uno::Reference< css::xml::sax::XParser > xParser
289 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
290 xParser->setDocumentHandler( xSEKHandler );
295 * connects the next document handler on the SAX chain
297 m_xSAXEventKeeper->setNextHandler(uno::Reference<xml::sax::XDocumentHandler>());
299 m_bIsSAXEventKeeperConnected = true;
301 rc = true;
305 return rc;
308 void XSecController::chainOff()
309 /****** XSecController/chainOff ***********************************************
311 * NAME
312 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
313 ******************************************************************************/
315 if (m_bIsSAXEventKeeperSticky )
316 return;
318 if (!m_bIsSAXEventKeeperConnected)
319 return;
321 m_xSAXEventKeeper->setNextHandler( nullptr );
323 if ( m_xPreviousNodeOnSAXChain.is() )
325 if ( m_bIsPreviousNodeInitializable )
327 css::uno::Reference< css::lang::XInitialization > xInitialization
328 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
330 css::uno::Sequence<css::uno::Any> aArgs{ css::uno::Any(
331 uno::Reference<xml::sax::XDocumentHandler>()) };
332 xInitialization->initialize(aArgs);
334 else
336 css::uno::Reference< css::xml::sax::XParser > xParser(m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
337 xParser->setDocumentHandler(uno::Reference<xml::sax::XDocumentHandler>());
341 m_bIsSAXEventKeeperConnected = false;
344 void XSecController::checkChainingStatus()
345 /****** XSecController/checkChainingStatus ************************************
347 * NAME
348 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
349 * according to the current situation.
351 * SYNOPSIS
352 * checkChainingStatus( );
354 * FUNCTION
355 * The SAXEventKeeper is chained into the SAX chain, when:
356 * 1. some element is being collected, or
357 * 2. the SAX event stream is blocking.
358 * Otherwise, chain off the SAXEventKeeper.
359 ******************************************************************************/
361 if ( m_bIsCollectingElement || m_bIsBlocking )
363 chainOn();
365 else
367 chainOff();
371 void XSecController::initializeSAXChain()
372 /****** XSecController/initializeSAXChain *************************************
374 * NAME
375 * initializeSAXChain -- initializes the SAX chain according to the
376 * current setting.
378 * FUNCTION
379 * Initializes the SAX chain, if the SAXEventKeeper is asked to be always
380 * on the SAX chain, chains it on. Otherwise, starts the
381 * ElementStackKeeper to reserve key SAX events.
382 ******************************************************************************/
384 m_bIsSAXEventKeeperConnected = false;
385 m_bIsCollectingElement = false;
386 m_bIsBlocking = false;
388 chainOff();
391 css::uno::Reference< css::io::XInputStream >
392 XSecController::getObjectInputStream( const OUString& objectURL )
393 /****** XSecController/getObjectInputStream ************************************
395 * NAME
396 * getObjectInputStream -- get a XInputStream interface from a SotStorage
398 * SYNOPSIS
399 * xInputStream = getObjectInputStream( objectURL );
401 * INPUTS
402 * objectURL - the object uri
404 * RESULT
405 * xInputStream - the XInputStream interface
406 ******************************************************************************/
408 css::uno::Reference< css::io::XInputStream > xObjectInputStream;
410 SAL_WARN_IF( !m_xUriBinding.is(), "xmlsecurity.helper", "Need XUriBinding!" );
412 xObjectInputStream = m_xUriBinding->getUriBinding(objectURL);
414 return xObjectInputStream;
418 * public methods
421 sal_Int32 XSecController::getNewSecurityId( )
423 sal_Int32 nId = m_nNextSecurityId;
424 m_nNextSecurityId++;
425 return nId;
428 void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext >& xSecurityContext )
429 /****** XSecController/startMission *******************************************
431 * NAME
432 * startMission -- starts a new security mission.
434 * FUNCTION
435 * get ready for a new mission.
437 * INPUTS
438 * xUriBinding - the Uri binding that provide maps between uris and
439 * XInputStreams
440 * xSecurityContext - the security context component which can provide
441 * cryptoken
442 ******************************************************************************/
444 m_xUriBinding = xUriBinding;
446 m_eStatusOfSecurityComponents = InitializationState::UNINITIALIZED;
447 m_xSecurityContext = xSecurityContext;
449 m_vInternalSignatureInformations.clear();
451 m_bVerifyCurrentSignature = false;
454 void XSecController::setSAXChainConnector(const css::uno::Reference< css::lang::XInitialization >& xInitialization)
455 /****** XSecController/setSAXChainConnector ***********************************
457 * NAME
458 * setSAXChainConnector -- configures the components which will
459 * collaborate with the SAXEventKeeper on the SAX chain.
461 * SYNOPSIS
462 * setSAXChainConnector(xInitialization);
464 * INPUTS
465 * xInitialization - the previous node on the SAX chain
466 ******************************************************************************/
468 m_bIsPreviousNodeInitializable = true;
469 m_xPreviousNodeOnSAXChain = xInitialization;
471 initializeSAXChain( );
474 void XSecController::clearSAXChainConnector()
475 /****** XSecController/clearSAXChainConnector *********************************
477 * NAME
478 * clearSAXChainConnector -- resets the collaborating components.
479 ******************************************************************************/
481 chainOff();
483 m_xPreviousNodeOnSAXChain = nullptr;
486 void XSecController::endMission()
487 /****** XSecController/endMission *********************************************
489 * NAME
490 * endMission -- forces to end all missions
492 * FUNCTION
493 * Deletes all signature information and forces all missions to an end.
494 ******************************************************************************/
496 sal_Int32 size = m_vInternalSignatureInformations.size();
498 for (int i=0; i<size; ++i)
500 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
502 * ResolvedListener only exist when the security components are created.
505 css::uno::Reference< css::xml::crypto::sax::XMissionTaker > xMissionTaker
506 ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, css::uno::UNO_QUERY );
509 * asks the SignatureCreator/SignatureVerifier to release
510 * all resources it uses.
512 xMissionTaker->endMission();
516 m_xUriBinding = nullptr;
517 m_xSecurityContext = nullptr;
520 * free the status change listener reference to this object
522 if (m_xSAXEventKeeper.is())
523 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( nullptr );
526 namespace
528 void writeUnsignedProperties(
529 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
530 const SignatureInformation& signatureInfo)
533 rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
534 pAttributeList->AddAttribute(u"Id"_ustr, "idUnsignedProperties_" + signatureInfo.ouSignatureId);
535 xDocumentHandler->startElement(u"xd:UnsignedProperties"_ustr, uno::Reference<xml::sax::XAttributeList>(pAttributeList));
539 xDocumentHandler->startElement(u"xd:UnsignedSignatureProperties"_ustr, uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
542 xDocumentHandler->startElement(u"xd:CertificateValues"_ustr, uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
545 for (const auto& i: signatureInfo.maEncapsulatedX509Certificates)
547 xDocumentHandler->startElement(u"xd:EncapsulatedX509Certificate"_ustr, uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
548 xDocumentHandler->characters(i);
549 xDocumentHandler->endElement(u"xd:EncapsulatedX509Certificate"_ustr);
553 xDocumentHandler->endElement(u"xd:CertificateValues"_ustr);
556 xDocumentHandler->endElement(u"xd:UnsignedSignatureProperties"_ustr);
559 xDocumentHandler->endElement(u"xd:UnsignedProperties"_ustr);
564 void XSecController::exportSignature(
565 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
566 const SignatureInformation& signatureInfo,
567 bool bXAdESCompliantIfODF )
568 /****** XSecController/exportSignature ****************************************
570 * NAME
571 * exportSignature -- export a signature structure to an XDocumentHandler
573 * SYNOPSIS
574 * exportSignature( xDocumentHandler, signatureInfo);
576 * INPUTS
577 * xDocumentHandler - the document handler to receive the signature
578 * signatureInfo - signature to be exported
579 ******************************************************************************/
581 const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors;
582 rtl::Reference<comphelper::AttributeList> pAttributeList;
585 * Write Signature element
587 pAttributeList = new comphelper::AttributeList();
588 pAttributeList->AddAttribute(
589 u"xmlns"_ustr,
590 NS_XMLDSIG);
592 if (!signatureInfo.ouSignatureId.isEmpty())
594 pAttributeList->AddAttribute(
595 u"Id"_ustr,
596 signatureInfo.ouSignatureId);
599 xDocumentHandler->startElement( u"Signature"_ustr, pAttributeList);
601 /* Write SignedInfo element */
602 xDocumentHandler->startElement(
603 u"SignedInfo"_ustr,
604 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
606 /* Write CanonicalizationMethod element */
607 pAttributeList = new comphelper::AttributeList();
608 pAttributeList->AddAttribute(
609 u"Algorithm"_ustr,
610 ALGO_C14N);
611 xDocumentHandler->startElement( u"CanonicalizationMethod"_ustr, pAttributeList );
612 xDocumentHandler->endElement( u"CanonicalizationMethod"_ustr );
614 /* Write SignatureMethod element */
615 pAttributeList = new comphelper::AttributeList();
617 // TODO: actually roundtrip this value from parsing documentsignatures.xml - entirely
618 // broken to assume this would in any way relate to the 1st reference's digest algo
620 // Assume that all Reference elements use the same DigestMethod:Algorithm, and that the
621 // SignatureMethod:Algorithm should be the corresponding one.
622 pAttributeList->AddAttribute(
623 u"Algorithm"_ustr,
624 getSignatureURI(signatureInfo.eAlgorithmID, vReferenceInfors[0].nDigestID));
625 xDocumentHandler->startElement( u"SignatureMethod"_ustr, pAttributeList );
626 xDocumentHandler->endElement( u"SignatureMethod"_ustr );
628 /* Write Reference element */
629 int j;
630 int refNum = vReferenceInfors.size();
632 for(j=0; j<refNum; ++j)
634 const SignatureReferenceInformation& refInfor = vReferenceInfors[j];
636 pAttributeList = new comphelper::AttributeList();
637 if ( refInfor.nType != SignatureReferenceType::SAMEDOCUMENT )
639 * stream reference
642 pAttributeList->AddAttribute(
643 u"URI"_ustr,
644 refInfor.ouURI);
646 else
648 * same-document reference
651 if (refInfor.ouURI.startsWith("idSignedProperties"))
653 pAttributeList->AddAttribute(u"URI"_ustr, "#idSignedProperties_" + signatureInfo.ouSignatureId);
654 if (bXAdESCompliantIfODF && !refInfor.ouType.isEmpty())
656 // The reference which points to the SignedProperties
657 // shall have this specific type.
658 pAttributeList->AddAttribute(u"Type"_ustr, refInfor.ouType);
661 else
663 pAttributeList->AddAttribute(
664 u"URI"_ustr,
665 "#" + refInfor.ouURI);
669 xDocumentHandler->startElement( u"Reference"_ustr, pAttributeList );
671 /* Write Transforms element */
672 if (refInfor.nType == SignatureReferenceType::XMLSTREAM)
674 * xml stream, so c14n transform is needed
677 xDocumentHandler->startElement(
678 u"Transforms"_ustr,
679 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
681 pAttributeList = new comphelper::AttributeList();
682 pAttributeList->AddAttribute(
683 u"Algorithm"_ustr,
684 ALGO_C14N);
685 xDocumentHandler->startElement(
686 u"Transform"_ustr,
687 pAttributeList );
688 xDocumentHandler->endElement( u"Transform"_ustr );
690 xDocumentHandler->endElement( u"Transforms"_ustr );
693 /* Write DigestMethod element */
694 pAttributeList = new comphelper::AttributeList();
695 pAttributeList->AddAttribute(
696 u"Algorithm"_ustr,
697 getDigestURI(refInfor.nDigestID));
698 xDocumentHandler->startElement(
699 u"DigestMethod"_ustr,
700 pAttributeList );
701 xDocumentHandler->endElement( u"DigestMethod"_ustr );
703 /* Write DigestValue element */
704 xDocumentHandler->startElement(
705 u"DigestValue"_ustr,
706 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
707 xDocumentHandler->characters( refInfor.ouDigestValue );
708 xDocumentHandler->endElement( u"DigestValue"_ustr );
710 xDocumentHandler->endElement( u"Reference"_ustr );
713 xDocumentHandler->endElement( u"SignedInfo"_ustr );
715 /* Write SignatureValue element */
716 xDocumentHandler->startElement(
717 u"SignatureValue"_ustr,
718 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
719 xDocumentHandler->characters( signatureInfo.ouSignatureValue );
720 xDocumentHandler->endElement( u"SignatureValue"_ustr );
722 /* Write KeyInfo element */
723 xDocumentHandler->startElement(
724 u"KeyInfo"_ustr,
725 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
727 // GPG or X509 key?
728 if (!signatureInfo.ouGpgCertificate.isEmpty())
730 pAttributeList = new comphelper::AttributeList();
731 pAttributeList->AddAttribute(u"xmlns:loext"_ustr, NS_LOEXT);
732 /* Write PGPData element */
733 xDocumentHandler->startElement(
734 u"PGPData"_ustr,
735 pAttributeList);
737 /* Write keyid element */
738 xDocumentHandler->startElement(
739 u"PGPKeyID"_ustr,
740 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
741 xDocumentHandler->characters(signatureInfo.ouGpgKeyID);
742 xDocumentHandler->endElement( u"PGPKeyID"_ustr );
744 /* Write PGPKeyPacket element */
745 if (!signatureInfo.ouGpgCertificate.isEmpty())
747 xDocumentHandler->startElement(
748 u"PGPKeyPacket"_ustr,
749 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
750 xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
751 xDocumentHandler->endElement( u"PGPKeyPacket"_ustr );
754 /* Write PGPOwner element */
755 xDocumentHandler->startElement(
756 u"loext:PGPOwner"_ustr,
757 css::uno::Reference< css::xml::sax::XAttributeList >(new comphelper::AttributeList()));
758 xDocumentHandler->characters( signatureInfo.ouGpgOwner );
759 xDocumentHandler->endElement( u"loext:PGPOwner"_ustr );
761 xDocumentHandler->endElement( u"PGPData"_ustr );
763 else
765 assert(signatureInfo.GetSigningCertificate());
766 for (auto const& rData : signatureInfo.X509Datas)
768 /* Write X509Data element */
769 xDocumentHandler->startElement(
770 u"X509Data"_ustr,
771 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
773 for (auto const& it : rData)
775 /* Write X509IssuerSerial element */
776 xDocumentHandler->startElement(
777 u"X509IssuerSerial"_ustr,
778 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
780 /* Write X509IssuerName element */
781 xDocumentHandler->startElement(
782 u"X509IssuerName"_ustr,
783 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
784 xDocumentHandler->characters(it.X509IssuerName);
785 xDocumentHandler->endElement( u"X509IssuerName"_ustr );
787 /* Write X509SerialNumber element */
788 xDocumentHandler->startElement(
789 u"X509SerialNumber"_ustr,
790 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
791 xDocumentHandler->characters(it.X509SerialNumber);
792 xDocumentHandler->endElement( u"X509SerialNumber"_ustr );
794 xDocumentHandler->endElement( u"X509IssuerSerial"_ustr );
796 /* Write X509Certificate element */
797 if (!it.X509Certificate.isEmpty())
799 xDocumentHandler->startElement(
800 u"X509Certificate"_ustr,
801 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
802 xDocumentHandler->characters(it.X509Certificate);
803 xDocumentHandler->endElement( u"X509Certificate"_ustr );
807 xDocumentHandler->endElement( u"X509Data"_ustr );
811 xDocumentHandler->endElement( u"KeyInfo"_ustr );
813 OUString sDate;
815 /* Write Object element */
816 xDocumentHandler->startElement(
817 u"Object"_ustr,
818 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
820 /* Write SignatureProperties element */
821 xDocumentHandler->startElement(
822 u"SignatureProperties"_ustr,
823 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
825 /* Write SignatureProperty element */
826 pAttributeList = new comphelper::AttributeList();
827 pAttributeList->AddAttribute(
828 u"Id"_ustr,
829 signatureInfo.ouDateTimePropertyId);
830 pAttributeList->AddAttribute(
831 u"Target"_ustr,
832 "#" + signatureInfo.ouSignatureId);
833 xDocumentHandler->startElement(
834 u"SignatureProperty"_ustr,
835 pAttributeList);
837 /* Write timestamp element */
839 pAttributeList = new comphelper::AttributeList();
840 pAttributeList->AddAttribute(
841 u"xmlns:dc"_ustr,
842 NS_DC);
844 xDocumentHandler->startElement(
845 u"dc:date"_ustr,
846 pAttributeList);
848 OUStringBuffer buffer;
849 //If the xml signature was already contained in the document,
850 //then we use the original date and time string, rather than the
851 //converted one. This avoids writing a different string due to
852 //e.g. rounding issues and thus breaking the signature.
853 if (!signatureInfo.ouDateTime.isEmpty())
854 buffer = signatureInfo.ouDateTime;
855 else
857 buffer = utl::toISO8601(signatureInfo.stDateTime);
858 // xsd:dateTime must use period as separator for fractional seconds, while
859 // utl::toISO8601 uses comma (as allowed, and even recommended, by ISO8601).
860 buffer.replace(',', '.');
862 sDate = buffer.makeStringAndClear();
863 xDocumentHandler->characters( sDate );
865 xDocumentHandler->endElement(
866 u"dc:date"_ustr);
868 xDocumentHandler->endElement( u"SignatureProperty"_ustr );
871 // Write signature description.
872 if (!signatureInfo.ouDescription.isEmpty())
874 // SignatureProperty element.
875 pAttributeList = new comphelper::AttributeList();
876 pAttributeList->AddAttribute(u"Id"_ustr, signatureInfo.ouDescriptionPropertyId);
877 pAttributeList->AddAttribute(u"Target"_ustr, "#" + signatureInfo.ouSignatureId);
878 xDocumentHandler->startElement(u"SignatureProperty"_ustr, pAttributeList);
881 // Description element.
882 pAttributeList = new comphelper::AttributeList();
883 pAttributeList->AddAttribute(u"xmlns:dc"_ustr, NS_DC);
885 xDocumentHandler->startElement(u"dc:description"_ustr, pAttributeList);
886 xDocumentHandler->characters(signatureInfo.ouDescription);
887 xDocumentHandler->endElement(u"dc:description"_ustr);
890 xDocumentHandler->endElement(u"SignatureProperty"_ustr);
893 xDocumentHandler->endElement( u"SignatureProperties"_ustr );
895 xDocumentHandler->endElement( u"Object"_ustr );
897 // In XAdES, write another Object element for the QualifyingProperties
898 if (bXAdESCompliantIfODF)
900 pAttributeList = new comphelper::AttributeList();
901 pAttributeList->AddAttribute(u"xmlns:xd"_ustr, NS_XD);
902 xDocumentHandler->startElement(
903 u"Object"_ustr,
904 pAttributeList);
906 pAttributeList = new comphelper::AttributeList();
907 pAttributeList->AddAttribute(u"Target"_ustr, "#" + signatureInfo.ouSignatureId);
908 xDocumentHandler->startElement(
909 u"xd:QualifyingProperties"_ustr,
910 pAttributeList);
911 DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate, true);
912 writeUnsignedProperties(xDocumentHandler, signatureInfo);
913 xDocumentHandler->endElement( u"xd:QualifyingProperties"_ustr );
915 xDocumentHandler->endElement( u"Object"_ustr );
918 xDocumentHandler->endElement( u"Signature"_ustr );
921 void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation)
923 OOXMLSecExporter aExporter(mxCtx, xRootStorage, xDocumentHandler, rInformation);
924 aExporter.writeSignature();
927 void XSecController::UpdateSignatureInformation(sal_Int32 const nSecurityId,
928 std::vector<SignatureInformation::X509Data> && rDatas)
930 int const nIndex = findSignatureInfor(nSecurityId);
931 assert(nIndex != -1); // nothing should touch this between parsing and verify
932 m_vInternalSignatureInformations[nIndex].signatureInfor.X509Datas = std::move(rDatas);
935 SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const
937 SignatureInformation aInf( 0 );
938 int nIndex = findSignatureInfor(nSecurityId);
939 SAL_WARN_IF( nIndex == -1, "xmlsecurity.helper", "getSignatureInformation - SecurityId is invalid!" );
940 if ( nIndex != -1)
942 aInf = m_vInternalSignatureInformations[nIndex].signatureInfor;
944 return aInf;
947 SignatureInformations XSecController::getSignatureInformations() const
949 SignatureInformations vInfors;
950 int sigNum = m_vInternalSignatureInformations.size();
952 for (int i=0; i<sigNum; ++i)
954 SignatureInformation si = m_vInternalSignatureInformations[i].signatureInfor;
955 vInfors.push_back(si);
958 return vInfors;
962 * XSAXEventKeeperStatusChangeListener
965 void SAL_CALL XSecController::blockingStatusChanged( sal_Bool isBlocking )
967 m_bIsBlocking = isBlocking;
968 checkChainingStatus();
971 void SAL_CALL XSecController::collectionStatusChanged(
972 sal_Bool isInsideCollectedElement )
974 m_bIsCollectingElement = isInsideCollectedElement;
975 checkChainingStatus();
978 void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/)
984 * XSignatureCreationResultListener
986 void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
988 int index = findSignatureInfor(securityId);
989 assert(index != -1 && "Signature Not Found!");
990 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
991 signatureInfor.nStatus = nResult;
995 * XSignatureVerifyResultListener
997 void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
999 int index = findSignatureInfor(securityId);
1000 assert(index != -1 && "Signature Not Found!");
1001 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
1002 signatureInfor.nStatus = nResult;
1005 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */