nss: upgrade to release 3.73
[LibreOffice.git] / xmlsecurity / source / helper / xsecctl.cxx
blob3f18d109494d57f8c28e7102eccb8aecc063236b
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 <xsecctl.hxx>
23 #include <documentsignaturehelper.hxx>
24 #include <framework/saxeventkeeperimpl.hxx>
25 #include <xmlsec/xmldocumentwrapper_xmlsecimpl.hxx>
26 #if HAVE_FEATURE_GPGME
27 # include <gpg/xmlsignature_gpgimpl.hxx>
28 #endif
30 #include <com/sun/star/xml/crypto/sax/XMissionTaker.hpp>
31 #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
32 #include <com/sun/star/uno/XComponentContext.hpp>
33 #include <com/sun/star/xml/sax/XParser.hpp>
34 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
36 #include <xmloff/attrlist.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <rtl/ref.hxx>
39 #include <sal/log.hxx>
40 #include <unotools/datetime.hxx>
41 #include "ooxmlsecexporter.hxx"
42 #include <xmlsignaturehelper2.hxx>
44 using namespace com::sun::star;
46 namespace
48 OUString getDigestURI(sal_Int32 nID)
50 switch( nID )
52 case css::xml::crypto::DigestID::SHA1:
53 return ALGO_XMLDSIGSHA1;
54 case css::xml::crypto::DigestID::SHA256:
55 return ALGO_XMLDSIGSHA256;
56 case css::xml::crypto::DigestID::SHA512:
57 return ALGO_XMLDSIGSHA512;
58 default:
59 return ALGO_XMLDSIGSHA1;
62 OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_Int32 nDigestID)
64 OUString aRet;
66 if (eAlgorithm == svl::crypto::SignatureMethodAlgorithm::ECDSA)
68 switch (nDigestID)
70 case css::xml::crypto::DigestID::SHA1:
71 aRet = ALGO_ECDSASHA1;
72 break;
73 case css::xml::crypto::DigestID::SHA256:
74 aRet = ALGO_ECDSASHA256;
75 break;
76 case css::xml::crypto::DigestID::SHA512:
77 aRet = ALGO_ECDSASHA512;
78 break;
79 default:
80 aRet = ALGO_ECDSASHA1;
81 break;
84 if (!aRet.isEmpty())
85 return aRet;
87 switch (nDigestID)
89 case css::xml::crypto::DigestID::SHA1:
90 return ALGO_RSASHA1;
91 case css::xml::crypto::DigestID::SHA256:
92 return ALGO_RSASHA256;
93 case css::xml::crypto::DigestID::SHA512:
94 return ALGO_RSASHA512;
95 default:
96 return ALGO_RSASHA1;
101 XSecController::XSecController( const css::uno::Reference<css::uno::XComponentContext>& rxCtx )
102 : mxCtx(rxCtx)
103 , m_nNextSecurityId(1)
104 , m_bIsPreviousNodeInitializable(false)
105 , m_bIsSAXEventKeeperConnected(false)
106 , m_bIsCollectingElement(false)
107 , m_bIsBlocking(false)
108 , m_eStatusOfSecurityComponents(InitializationState::UNINITIALIZED)
109 , m_bIsSAXEventKeeperSticky(false)
110 , m_nReservedSignatureId(0)
111 , m_bVerifyCurrentSignature(false)
115 XSecController::~XSecController()
121 * private methods
123 int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const
124 /****** XSecController/findSignatureInfor *************************************
126 * NAME
127 * findSignatureInfor -- find SignatureInformation struct for a particular
128 * signature
130 * SYNOPSIS
131 * index = findSignatureInfor( nSecurityId );
133 * INPUTS
134 * nSecurityId - the signature's id
136 * RESULT
137 * index - the index of the signature, or -1 when no such signature
138 * existing
139 ******************************************************************************/
141 int i;
142 int size = m_vInternalSignatureInformations.size();
144 for (i=0; i<size; ++i)
146 if (m_vInternalSignatureInformations[i].signatureInfor.nSecurityId == nSecurityId)
148 return i;
152 return -1;
155 void XSecController::createXSecComponent( )
156 /****** XSecController/createXSecComponent ************************************
158 * NAME
159 * bResult = createXSecComponent -- creates xml security components
161 * FUNCTION
162 * Creates xml security components, including:
163 * 1. an xml signature bridge component
164 * 2. an XMLDocumentWrapper component
165 * 3. a SAXEventKeeper component
166 ******************************************************************************/
169 * marks all security components are not available.
171 m_eStatusOfSecurityComponents = InitializationState::FAILTOINITIALIZED;
172 m_xXMLSignature = nullptr;
173 m_xXMLDocumentWrapper = nullptr;
174 m_xSAXEventKeeper = nullptr;
176 css::uno::Reference< css::lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
178 #if HAVE_FEATURE_GPGME
179 uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, css::uno::UNO_QUERY );
180 if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
181 m_xXMLSignature.set(new XMLSignature_GpgImpl());
182 else // xmlsec or mscrypt
183 #endif
184 m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), css::uno::UNO_QUERY);
186 bool bSuccess = m_xXMLSignature.is();
187 if ( bSuccess )
189 * XMLSignature created successfully.
191 m_xXMLDocumentWrapper = new XMLDocumentWrapper_XmlSecImpl();
193 bSuccess &= m_xXMLDocumentWrapper.is();
194 if ( bSuccess )
195 m_xSAXEventKeeper = new SAXEventKeeperImpl();
197 bSuccess &= m_xSAXEventKeeper.is();
199 if (!bSuccess)
201 * SAXEventKeeper created successfully.
203 return;
205 css::uno::Sequence <css::uno::Any> arg(1);
206 arg[0] <<= uno::Reference<xml::wrapper::XXMLDocumentWrapper>(m_xXMLDocumentWrapper.get());
207 m_xSAXEventKeeper->initialize(arg);
209 css::uno::Reference< css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener >
210 xStatusChangeListener = this;
212 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
214 m_eStatusOfSecurityComponents = InitializationState::INITIALIZED;
217 bool XSecController::chainOn()
218 /****** XSecController/chainOn ************************************************
220 * NAME
221 * chainOn -- tries to connect the SAXEventKeeper with the SAX chain.
223 * SYNOPSIS
224 * bJustChainingOn = chainOn();
226 * FUNCTION
227 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
228 * creates xml security components, and chains the SAXEventKeeper into
229 * the SAX chain.
230 * Before being chained in, the SAXEventKeeper needs to receive all
231 * missed key SAX events, which can promise the DOM tree buffered by the
232 * SAXEventKeeper has the same structure with the original document.
234 * RESULT
235 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
236 * SAX chain.
238 * NOTES
239 * Sometimes, the last key SAX event can't be transferred to the
240 * SAXEventKeeper together.
241 * For instance, at the time a referenced element is detected, the
242 * startElement event has already been reserved by the ElementStackKeeper.
243 * Meanwhile, an ElementCollector needs to be created before the
244 * SAXEventKeeper receives that startElement event.
245 * So for the SAXEventKeeper, it needs to receive all missed key SAX
246 * events except that startElement event, then adds a new
247 * ElementCollector, then receives that startElement event.
248 ******************************************************************************/
250 bool rc = false;
252 if (!m_bIsSAXEventKeeperSticky && !m_bIsSAXEventKeeperConnected)
254 if ( m_eStatusOfSecurityComponents == InitializationState::UNINITIALIZED )
256 createXSecComponent();
259 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
261 * if all security components are ready, chains on the SAXEventKeeper
265 * disconnect the SAXEventKeeper with its current output handler,
266 * to make sure no SAX event is forwarded during the connecting
267 * phase.
269 m_xSAXEventKeeper->setNextHandler( nullptr );
271 css::uno::Reference< css::xml::sax::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), css::uno::UNO_QUERY);
274 * connects the previous document handler on the SAX chain
276 if ( m_xPreviousNodeOnSAXChain.is() )
278 if ( m_bIsPreviousNodeInitializable )
280 css::uno::Reference< css::lang::XInitialization > xInitialization
281 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
283 css::uno::Sequence<css::uno::Any> aArgs( 1 );
284 aArgs[0] <<= xSEKHandler;
285 xInitialization->initialize(aArgs);
287 else
289 css::uno::Reference< css::xml::sax::XParser > xParser
290 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
291 xParser->setDocumentHandler( xSEKHandler );
296 * connects the next document handler on the SAX chain
298 m_xSAXEventKeeper->setNextHandler(uno::Reference<xml::sax::XDocumentHandler>());
300 m_bIsSAXEventKeeperConnected = true;
302 rc = true;
306 return rc;
309 void XSecController::chainOff()
310 /****** XSecController/chainOff ***********************************************
312 * NAME
313 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
314 ******************************************************************************/
316 if (m_bIsSAXEventKeeperSticky )
317 return;
319 if (!m_bIsSAXEventKeeperConnected)
320 return;
322 m_xSAXEventKeeper->setNextHandler( nullptr );
324 if ( m_xPreviousNodeOnSAXChain.is() )
326 if ( m_bIsPreviousNodeInitializable )
328 css::uno::Reference< css::lang::XInitialization > xInitialization
329 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
331 css::uno::Sequence<css::uno::Any> aArgs( 1 );
332 aArgs[0] <<= uno::Reference<xml::sax::XDocumentHandler>();
333 xInitialization->initialize(aArgs);
335 else
337 css::uno::Reference< css::xml::sax::XParser > xParser(m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
338 xParser->setDocumentHandler(uno::Reference<xml::sax::XDocumentHandler>());
342 m_bIsSAXEventKeeperConnected = false;
345 void XSecController::checkChainingStatus()
346 /****** XSecController/checkChainingStatus ************************************
348 * NAME
349 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
350 * according to the current situation.
352 * SYNOPSIS
353 * checkChainingStatus( );
355 * FUNCTION
356 * The SAXEventKeeper is chained into the SAX chain, when:
357 * 1. some element is being collected, or
358 * 2. the SAX event stream is blocking.
359 * Otherwise, chain off the SAXEventKeeper.
360 ******************************************************************************/
362 if ( m_bIsCollectingElement || m_bIsBlocking )
364 chainOn();
366 else
368 chainOff();
372 void XSecController::initializeSAXChain()
373 /****** XSecController/initializeSAXChain *************************************
375 * NAME
376 * initializeSAXChain -- initializes the SAX chain according to the
377 * current setting.
379 * FUNCTION
380 * Initializes the SAX chain, if the SAXEventKeeper is asked to be always
381 * on the SAX chain, chains it on. Otherwise, starts the
382 * ElementStackKeeper to reserve key SAX events.
383 ******************************************************************************/
385 m_bIsSAXEventKeeperConnected = false;
386 m_bIsCollectingElement = false;
387 m_bIsBlocking = false;
389 chainOff();
392 css::uno::Reference< css::io::XInputStream >
393 XSecController::getObjectInputStream( const OUString& objectURL )
394 /****** XSecController/getObjectInputStream ************************************
396 * NAME
397 * getObjectInputStream -- get a XInputStream interface from a SotStorage
399 * SYNOPSIS
400 * xInputStream = getObjectInputStream( objectURL );
402 * INPUTS
403 * objectURL - the object uri
405 * RESULT
406 * xInputStream - the XInputStream interface
407 ******************************************************************************/
409 css::uno::Reference< css::io::XInputStream > xObjectInputStream;
411 SAL_WARN_IF( !m_xUriBinding.is(), "xmlsecurity.helper", "Need XUriBinding!" );
413 xObjectInputStream = m_xUriBinding->getUriBinding(objectURL);
415 return xObjectInputStream;
419 * public methods
422 sal_Int32 XSecController::getNewSecurityId( )
424 sal_Int32 nId = m_nNextSecurityId;
425 m_nNextSecurityId++;
426 return nId;
429 void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext >& xSecurityContext )
430 /****** XSecController/startMission *******************************************
432 * NAME
433 * startMission -- starts a new security mission.
435 * FUNCTION
436 * get ready for a new mission.
438 * INPUTS
439 * xUriBinding - the Uri binding that provide maps between uris and
440 * XInputStreams
441 * xSecurityContext - the security context component which can provide
442 * cryptoken
443 ******************************************************************************/
445 m_xUriBinding = xUriBinding;
447 m_eStatusOfSecurityComponents = InitializationState::UNINITIALIZED;
448 m_xSecurityContext = xSecurityContext;
450 m_vInternalSignatureInformations.clear();
452 m_bVerifyCurrentSignature = false;
455 void XSecController::setSAXChainConnector(const css::uno::Reference< css::lang::XInitialization >& xInitialization)
456 /****** XSecController/setSAXChainConnector ***********************************
458 * NAME
459 * setSAXChainConnector -- configures the components which will
460 * collaborate with the SAXEventKeeper on the SAX chain.
462 * SYNOPSIS
463 * setSAXChainConnector(xInitialization);
465 * INPUTS
466 * xInitialization - the previous node on the SAX chain
467 ******************************************************************************/
469 m_bIsPreviousNodeInitializable = true;
470 m_xPreviousNodeOnSAXChain = xInitialization;
472 initializeSAXChain( );
475 void XSecController::clearSAXChainConnector()
476 /****** XSecController/clearSAXChainConnector *********************************
478 * NAME
479 * clearSAXChainConnector -- resets the collaborating components.
480 ******************************************************************************/
482 chainOff();
484 m_xPreviousNodeOnSAXChain = nullptr;
487 void XSecController::endMission()
488 /****** XSecController/endMission *********************************************
490 * NAME
491 * endMission -- forces to end all missions
493 * FUNCTION
494 * Deletes all signature information and forces all missions to an end.
495 ******************************************************************************/
497 sal_Int32 size = m_vInternalSignatureInformations.size();
499 for (int i=0; i<size; ++i)
501 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
503 * ResolvedListener only exist when the security components are created.
506 css::uno::Reference< css::xml::crypto::sax::XMissionTaker > xMissionTaker
507 ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, css::uno::UNO_QUERY );
510 * asks the SignatureCreator/SignatureVerifier to release
511 * all resources it uses.
513 xMissionTaker->endMission();
517 m_xUriBinding = nullptr;
518 m_xSecurityContext = nullptr;
521 * free the status change listener reference to this object
523 if (m_xSAXEventKeeper.is())
524 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( nullptr );
527 namespace
529 void writeUnsignedProperties(
530 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
531 const SignatureInformation& signatureInfo)
534 rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
535 pAttributeList->AddAttribute("Id", "idUnsignedProperties");
536 xDocumentHandler->startElement("xd:UnsignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
540 xDocumentHandler->startElement("xd:UnsignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
543 xDocumentHandler->startElement("xd:CertificateValues", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
546 for (const auto& i: signatureInfo.maEncapsulatedX509Certificates)
548 xDocumentHandler->startElement("xd:EncapsulatedX509Certificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
549 xDocumentHandler->characters(i);
550 xDocumentHandler->endElement("xd:EncapsulatedX509Certificate");
554 xDocumentHandler->endElement("xd:CertificateValues");
557 xDocumentHandler->endElement("xd:UnsignedSignatureProperties");
560 xDocumentHandler->endElement("xd:UnsignedProperties");
565 void XSecController::exportSignature(
566 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
567 const SignatureInformation& signatureInfo,
568 bool bXAdESCompliantIfODF )
569 /****** XSecController/exportSignature ****************************************
571 * NAME
572 * exportSignature -- export a signature structure to an XDocumentHandler
574 * SYNOPSIS
575 * exportSignature( xDocumentHandler, signatureInfo);
577 * INPUTS
578 * xDocumentHandler - the document handler to receive the signature
579 * signatureInfo - signature to be exported
580 ******************************************************************************/
582 const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors;
583 SvXMLAttributeList *pAttributeList;
586 * Write Signature element
588 pAttributeList = new SvXMLAttributeList();
589 pAttributeList->AddAttribute(
590 "xmlns",
591 NS_XMLDSIG);
593 if (!signatureInfo.ouSignatureId.isEmpty())
595 pAttributeList->AddAttribute(
596 "Id",
597 signatureInfo.ouSignatureId);
600 xDocumentHandler->startElement( "Signature", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
602 /* Write SignedInfo element */
603 xDocumentHandler->startElement(
604 "SignedInfo",
605 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
607 /* Write CanonicalizationMethod element */
608 pAttributeList = new SvXMLAttributeList();
609 pAttributeList->AddAttribute(
610 "Algorithm",
611 ALGO_C14N);
612 xDocumentHandler->startElement( "CanonicalizationMethod", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
613 xDocumentHandler->endElement( "CanonicalizationMethod" );
615 /* Write SignatureMethod element */
616 pAttributeList = new SvXMLAttributeList();
618 // TODO: actually roundtrip this value from parsing documentsignatures.xml - entirely
619 // broken to assume this would in any way relate to the 1st reference's digest algo
621 // Assume that all Reference elements use the same DigestMethod:Algorithm, and that the
622 // SignatureMethod:Algorithm should be the corresponding one.
623 pAttributeList->AddAttribute(
624 "Algorithm",
625 getSignatureURI(signatureInfo.eAlgorithmID, vReferenceInfors[0].nDigestID));
626 xDocumentHandler->startElement( "SignatureMethod", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
627 xDocumentHandler->endElement( "SignatureMethod" );
629 /* Write Reference element */
630 int j;
631 int refNum = vReferenceInfors.size();
633 for(j=0; j<refNum; ++j)
635 const SignatureReferenceInformation& refInfor = vReferenceInfors[j];
637 pAttributeList = new SvXMLAttributeList();
638 if ( refInfor.nType != SignatureReferenceType::SAMEDOCUMENT )
640 * stream reference
643 pAttributeList->AddAttribute(
644 "URI",
645 refInfor.ouURI);
647 else
649 * same-document reference
652 pAttributeList->AddAttribute(
653 "URI",
654 "#" + refInfor.ouURI);
656 if (bXAdESCompliantIfODF && refInfor.ouURI == "idSignedProperties" && !refInfor.ouType.isEmpty())
658 // The reference which points to the SignedProperties
659 // shall have this specific type.
660 pAttributeList->AddAttribute("Type",
661 refInfor.ouType);
665 xDocumentHandler->startElement( "Reference", css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
667 /* Write Transforms element */
668 if (refInfor.nType == SignatureReferenceType::XMLSTREAM)
670 * xml stream, so c14n transform is needed
673 xDocumentHandler->startElement(
674 "Transforms",
675 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
677 pAttributeList = new SvXMLAttributeList();
678 pAttributeList->AddAttribute(
679 "Algorithm",
680 ALGO_C14N);
681 xDocumentHandler->startElement(
682 "Transform",
683 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
684 xDocumentHandler->endElement( "Transform" );
686 xDocumentHandler->endElement( "Transforms" );
689 /* Write DigestMethod element */
690 pAttributeList = new SvXMLAttributeList();
691 pAttributeList->AddAttribute(
692 "Algorithm",
693 getDigestURI(refInfor.nDigestID));
694 xDocumentHandler->startElement(
695 "DigestMethod",
696 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList) );
697 xDocumentHandler->endElement( "DigestMethod" );
699 /* Write DigestValue element */
700 xDocumentHandler->startElement(
701 "DigestValue",
702 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
703 xDocumentHandler->characters( refInfor.ouDigestValue );
704 xDocumentHandler->endElement( "DigestValue" );
706 xDocumentHandler->endElement( "Reference" );
709 xDocumentHandler->endElement( "SignedInfo" );
711 /* Write SignatureValue element */
712 xDocumentHandler->startElement(
713 "SignatureValue",
714 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
715 xDocumentHandler->characters( signatureInfo.ouSignatureValue );
716 xDocumentHandler->endElement( "SignatureValue" );
718 /* Write KeyInfo element */
719 xDocumentHandler->startElement(
720 "KeyInfo",
721 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
723 // GPG or X509 key?
724 if (!signatureInfo.ouGpgCertificate.isEmpty())
726 pAttributeList = new SvXMLAttributeList();
727 pAttributeList->AddAttribute("xmlns:loext", NS_LOEXT);
728 /* Write PGPData element */
729 xDocumentHandler->startElement(
730 "PGPData",
731 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
733 /* Write keyid element */
734 xDocumentHandler->startElement(
735 "PGPKeyID",
736 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
737 xDocumentHandler->characters(signatureInfo.ouGpgKeyID);
738 xDocumentHandler->endElement( "PGPKeyID" );
740 /* Write PGPKeyPacket element */
741 if (!signatureInfo.ouGpgCertificate.isEmpty())
743 xDocumentHandler->startElement(
744 "PGPKeyPacket",
745 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
746 xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
747 xDocumentHandler->endElement( "PGPKeyPacket" );
750 /* Write PGPOwner element */
751 xDocumentHandler->startElement(
752 "loext:PGPOwner",
753 css::uno::Reference< css::xml::sax::XAttributeList >(new SvXMLAttributeList()));
754 xDocumentHandler->characters( signatureInfo.ouGpgOwner );
755 xDocumentHandler->endElement( "loext:PGPOwner" );
757 xDocumentHandler->endElement( "PGPData" );
759 else
761 assert(signatureInfo.GetSigningCertificate());
762 for (auto const& rData : signatureInfo.X509Datas)
764 /* Write X509Data element */
765 xDocumentHandler->startElement(
766 "X509Data",
767 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
769 for (auto const& it : rData)
771 /* Write X509IssuerSerial element */
772 xDocumentHandler->startElement(
773 "X509IssuerSerial",
774 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
776 /* Write X509IssuerName element */
777 xDocumentHandler->startElement(
778 "X509IssuerName",
779 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
780 xDocumentHandler->characters(it.X509IssuerName);
781 xDocumentHandler->endElement( "X509IssuerName" );
783 /* Write X509SerialNumber element */
784 xDocumentHandler->startElement(
785 "X509SerialNumber",
786 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
787 xDocumentHandler->characters(it.X509SerialNumber);
788 xDocumentHandler->endElement( "X509SerialNumber" );
790 xDocumentHandler->endElement( "X509IssuerSerial" );
792 /* Write X509Certificate element */
793 if (!it.X509Certificate.isEmpty())
795 xDocumentHandler->startElement(
796 "X509Certificate",
797 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
798 xDocumentHandler->characters(it.X509Certificate);
799 xDocumentHandler->endElement( "X509Certificate" );
803 xDocumentHandler->endElement( "X509Data" );
807 xDocumentHandler->endElement( "KeyInfo" );
809 OUString sDate;
811 /* Write Object element */
812 xDocumentHandler->startElement(
813 "Object",
814 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
816 /* Write SignatureProperties element */
817 xDocumentHandler->startElement(
818 "SignatureProperties",
819 css::uno::Reference< css::xml::sax::XAttributeList > (new SvXMLAttributeList()));
821 /* Write SignatureProperty element */
822 pAttributeList = new SvXMLAttributeList();
823 pAttributeList->AddAttribute(
824 "Id",
825 signatureInfo.ouDateTimePropertyId);
826 pAttributeList->AddAttribute(
827 "Target",
828 "#" + signatureInfo.ouSignatureId);
829 xDocumentHandler->startElement(
830 "SignatureProperty",
831 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
833 /* Write timestamp element */
835 pAttributeList = new SvXMLAttributeList();
836 pAttributeList->AddAttribute(
837 "xmlns:dc",
838 NS_DC);
840 xDocumentHandler->startElement(
841 "dc:date",
842 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
844 OUStringBuffer buffer;
845 //If the xml signature was already contained in the document,
846 //then we use the original date and time string, rather than the
847 //converted one. This avoids writing a different string due to
848 //e.g. rounding issues and thus breaking the signature.
849 if (!signatureInfo.ouDateTime.isEmpty())
850 buffer = signatureInfo.ouDateTime;
851 else
853 buffer = utl::toISO8601(signatureInfo.stDateTime);
854 // xsd:dateTime must use period as separator for fractional seconds, while
855 // utl::toISO8601 uses comma (as allowed, and even recommended, by ISO8601).
856 buffer.replace(',', '.');
858 sDate = buffer.makeStringAndClear();
859 xDocumentHandler->characters( sDate );
861 xDocumentHandler->endElement(
862 "dc:date");
864 xDocumentHandler->endElement( "SignatureProperty" );
867 // Write signature description.
868 if (!signatureInfo.ouDescription.isEmpty())
870 // SignatureProperty element.
871 pAttributeList = new SvXMLAttributeList();
872 pAttributeList->AddAttribute("Id", signatureInfo.ouDescriptionPropertyId);
873 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
874 xDocumentHandler->startElement("SignatureProperty", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
877 // Description element.
878 pAttributeList = new SvXMLAttributeList();
879 pAttributeList->AddAttribute("xmlns:dc", NS_DC);
881 xDocumentHandler->startElement("dc:description", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
882 xDocumentHandler->characters(signatureInfo.ouDescription);
883 xDocumentHandler->endElement("dc:description");
886 xDocumentHandler->endElement("SignatureProperty");
889 xDocumentHandler->endElement( "SignatureProperties" );
891 xDocumentHandler->endElement( "Object" );
893 // In XAdES, write another Object element for the QualifyingProperties
894 if (bXAdESCompliantIfODF)
896 pAttributeList = new SvXMLAttributeList();
897 pAttributeList->AddAttribute("xmlns:xd", NS_XD);
898 xDocumentHandler->startElement(
899 "Object",
900 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
902 pAttributeList = new SvXMLAttributeList();
903 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
904 xDocumentHandler->startElement(
905 "xd:QualifyingProperties",
906 css::uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
907 DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate, true);
908 writeUnsignedProperties(xDocumentHandler, signatureInfo);
909 xDocumentHandler->endElement( "xd:QualifyingProperties" );
911 xDocumentHandler->endElement( "Object" );
914 xDocumentHandler->endElement( "Signature" );
917 void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation)
919 OOXMLSecExporter aExporter(mxCtx, xRootStorage, xDocumentHandler, rInformation);
920 aExporter.writeSignature();
923 void XSecController::UpdateSignatureInformation(sal_Int32 const nSecurityId,
924 std::vector<SignatureInformation::X509Data> const& rDatas)
926 SignatureInformation aInf( 0 );
927 int const nIndex = findSignatureInfor(nSecurityId);
928 assert(nIndex != -1); // nothing should touch this between parsing and verify
929 m_vInternalSignatureInformations[nIndex].signatureInfor.X509Datas = rDatas;
932 SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const
934 SignatureInformation aInf( 0 );
935 int nIndex = findSignatureInfor(nSecurityId);
936 SAL_WARN_IF( nIndex == -1, "xmlsecurity.helper", "getSignatureInformation - SecurityId is invalid!" );
937 if ( nIndex != -1)
939 aInf = m_vInternalSignatureInformations[nIndex].signatureInfor;
941 return aInf;
944 SignatureInformations XSecController::getSignatureInformations() const
946 SignatureInformations vInfors;
947 int sigNum = m_vInternalSignatureInformations.size();
949 for (int i=0; i<sigNum; ++i)
951 SignatureInformation si = m_vInternalSignatureInformations[i].signatureInfor;
952 vInfors.push_back(si);
955 return vInfors;
959 * XSAXEventKeeperStatusChangeListener
962 void SAL_CALL XSecController::blockingStatusChanged( sal_Bool isBlocking )
964 m_bIsBlocking = isBlocking;
965 checkChainingStatus();
968 void SAL_CALL XSecController::collectionStatusChanged(
969 sal_Bool isInsideCollectedElement )
971 m_bIsCollectingElement = isInsideCollectedElement;
972 checkChainingStatus();
975 void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/)
981 * XSignatureCreationResultListener
983 void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
985 int index = findSignatureInfor(securityId);
986 assert(index != -1 && "Signature Not Found!");
987 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
988 signatureInfor.nStatus = nResult;
992 * XSignatureVerifyResultListener
994 void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
996 int index = findSignatureInfor(securityId);
997 assert(index != -1 && "Signature Not Found!");
998 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
999 signatureInfor.nStatus = nResult;
1002 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */