Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / xmlsecurity / source / helper / xsecctl.cxx
blob1d9906f27ed3ba0bd1dde3204f0b375eab8c449f
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/ElementMarkPriority.hpp>
31 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
32 #include <com/sun/star/xml/crypto/sax/XMissionTaker.hpp>
33 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
34 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeBroadcaster.hpp>
35 #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
36 #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
37 #include <com/sun/star/embed/ElementModes.hpp>
38 #include <com/sun/star/beans/StringPair.hpp>
40 #include <xmloff/attrlist.hxx>
41 #include <rtl/math.hxx>
42 #include <rtl/ref.hxx>
43 #include <unotools/datetime.hxx>
44 #include <comphelper/ofopxmlhelper.hxx>
45 #include <sax/tools/converter.hxx>
46 #include "ooxmlsecexporter.hxx"
47 #include <xmlsignaturehelper2.hxx>
49 namespace cssu = com::sun::star::uno;
50 namespace cssl = com::sun::star::lang;
51 namespace cssxc = com::sun::star::xml::crypto;
52 namespace cssxs = com::sun::star::xml::sax;
53 using namespace com::sun::star;
55 namespace
57 OUString getDigestURI(sal_Int32 nID)
59 switch( nID )
61 case cssxc::DigestID::SHA1:
62 return OUString(ALGO_XMLDSIGSHA1);
63 case cssxc::DigestID::SHA256:
64 return OUString(ALGO_XMLDSIGSHA256);
65 case cssxc::DigestID::SHA512:
66 return OUString(ALGO_XMLDSIGSHA512);
67 default:
68 return OUString(ALGO_XMLDSIGSHA1);
71 OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_Int32 nDigestID)
73 OUString aRet;
75 if (eAlgorithm == svl::crypto::SignatureMethodAlgorithm::ECDSA)
77 switch (nDigestID)
79 case cssxc::DigestID::SHA1:
80 aRet = ALGO_ECDSASHA1;
81 break;
82 case cssxc::DigestID::SHA256:
83 aRet = ALGO_ECDSASHA256;
84 break;
85 case cssxc::DigestID::SHA512:
86 aRet = ALGO_ECDSASHA512;
87 break;
88 default:
89 aRet = ALGO_ECDSASHA1;
90 break;
93 if (!aRet.isEmpty())
94 return aRet;
96 switch (nDigestID)
98 case cssxc::DigestID::SHA1:
99 return OUString(ALGO_RSASHA1);
100 case cssxc::DigestID::SHA256:
101 return OUString(ALGO_RSASHA256);
102 case cssxc::DigestID::SHA512:
103 return OUString(ALGO_RSASHA512);
104 default:
105 return OUString(ALGO_RSASHA1);
110 XSecController::XSecController( const cssu::Reference<cssu::XComponentContext>& rxCtx )
111 : mxCtx(rxCtx)
112 , m_nNextSecurityId(1)
113 , m_bIsPreviousNodeInitializable(false)
114 , m_bIsSAXEventKeeperConnected(false)
115 , m_bIsCollectingElement(false)
116 , m_bIsBlocking(false)
117 , m_eStatusOfSecurityComponents(InitializationState::UNINITIALIZED)
118 , m_bIsSAXEventKeeperSticky(false)
119 , m_nReservedSignatureId(0)
120 , m_bVerifyCurrentSignature(false)
124 XSecController::~XSecController()
130 * private methods
132 int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const
133 /****** XSecController/findSignatureInfor *************************************
135 * NAME
136 * findSignatureInfor -- find SignatureInformation struct for a particular
137 * signature
139 * SYNOPSIS
140 * index = findSignatureInfor( nSecurityId );
142 * INPUTS
143 * nSecurityId - the signature's id
145 * RESULT
146 * index - the index of the signature, or -1 when no such signature
147 * existing
148 ******************************************************************************/
150 int i;
151 int size = m_vInternalSignatureInformations.size();
153 for (i=0; i<size; ++i)
155 if (m_vInternalSignatureInformations[i].signatureInfor.nSecurityId == nSecurityId)
157 return i;
161 return -1;
164 void XSecController::createXSecComponent( )
165 /****** XSecController/createXSecComponent ************************************
167 * NAME
168 * bResult = createXSecComponent -- creates xml security components
170 * FUNCTION
171 * Creates xml security components, including:
172 * 1. an xml signature bridge component
173 * 2. an XMLDocumentWrapper component
174 * 3. a SAXEventKeeper component
175 ******************************************************************************/
178 * marks all security components are not available.
180 m_eStatusOfSecurityComponents = InitializationState::FAILTOINITIALIZED;
181 m_xXMLSignature = nullptr;
182 m_xXMLDocumentWrapper = nullptr;
183 m_xSAXEventKeeper = nullptr;
185 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
187 #if HAVE_FEATURE_GPGME
188 uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, cssu::UNO_QUERY );
189 if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
190 m_xXMLSignature.set(new XMLSignature_GpgImpl());
191 else // xmlsec or mscrypt
192 #endif
193 m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), cssu::UNO_QUERY);
195 bool bSuccess = m_xXMLSignature.is();
196 if ( bSuccess )
198 * XMLSignature created successfully.
200 m_xXMLDocumentWrapper = new XMLDocumentWrapper_XmlSecImpl();
202 bSuccess &= m_xXMLDocumentWrapper.is();
203 if ( bSuccess )
204 m_xSAXEventKeeper = new SAXEventKeeperImpl();
206 bSuccess &= m_xSAXEventKeeper.is();
208 if (bSuccess)
210 * SAXEventKeeper created successfully.
213 cssu::Sequence <cssu::Any> arg(1);
214 arg[0] <<= uno::Reference<xml::wrapper::XXMLDocumentWrapper>(m_xXMLDocumentWrapper.get());
215 m_xSAXEventKeeper->initialize(arg);
217 cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >
218 xStatusChangeListener = this;
220 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
222 m_eStatusOfSecurityComponents = InitializationState::INITIALIZED;
226 bool XSecController::chainOn()
227 /****** XSecController/chainOn ************************************************
229 * NAME
230 * chainOn -- tries to connect the SAXEventKeeper with the SAX chain.
232 * SYNOPSIS
233 * bJustChainingOn = chainOn();
235 * FUNCTION
236 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
237 * creates xml security components, and chains the SAXEventKeeper into
238 * the SAX chain.
239 * Before being chained in, the SAXEventKeeper needs to receive all
240 * missed key SAX events, which can promise the DOM tree bufferred by the
241 * SAXEventKeeper has the same structure with the original document.
243 * RESULT
244 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
245 * SAX chain.
247 * NOTES
248 * Sometimes, the last key SAX event can't be transferred to the
249 * SAXEventKeeper together.
250 * For instance, at the time an referenced element is detected, the
251 * startElement event has already been reserved by the ElementStackKeeper.
252 * Meanwhile, an ElementCollector needs to be created before the
253 * SAXEventKeeper receives that startElement event.
254 * So for the SAXEventKeeper, it needs to receive all missed key SAX
255 * events except that startElement event, then adds a new
256 * ElementCollector, then receives that startElement event.
257 ******************************************************************************/
259 bool rc = false;
261 if (!m_bIsSAXEventKeeperSticky && !m_bIsSAXEventKeeperConnected)
263 if ( m_eStatusOfSecurityComponents == InitializationState::UNINITIALIZED )
265 createXSecComponent();
268 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
270 * if all security components are ready, chains on the SAXEventKeeper
274 * disconnect the SAXEventKeeper with its current output handler,
275 * to make sure no SAX event is forwarded during the connecting
276 * phase.
278 m_xSAXEventKeeper->setNextHandler( nullptr );
280 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), cssu::UNO_QUERY);
283 * connects the previous document handler on the SAX chain
285 if ( m_xPreviousNodeOnSAXChain.is() )
287 if ( m_bIsPreviousNodeInitializable )
289 cssu::Reference< cssl::XInitialization > xInitialization
290 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
292 cssu::Sequence<cssu::Any> aArgs( 1 );
293 aArgs[0] <<= xSEKHandler;
294 xInitialization->initialize(aArgs);
296 else
298 cssu::Reference< cssxs::XParser > xParser
299 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
300 xParser->setDocumentHandler( xSEKHandler );
305 * connects the next document handler on the SAX chain
307 m_xSAXEventKeeper->setNextHandler(uno::Reference<xml::sax::XDocumentHandler>());
309 m_bIsSAXEventKeeperConnected = true;
311 rc = true;
315 return rc;
318 void XSecController::chainOff()
319 /****** XSecController/chainOff ***********************************************
321 * NAME
322 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
323 ******************************************************************************/
325 if (!m_bIsSAXEventKeeperSticky )
327 if (m_bIsSAXEventKeeperConnected)
329 m_xSAXEventKeeper->setNextHandler( nullptr );
331 if ( m_xPreviousNodeOnSAXChain.is() )
333 if ( m_bIsPreviousNodeInitializable )
335 cssu::Reference< cssl::XInitialization > xInitialization
336 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
338 cssu::Sequence<cssu::Any> aArgs( 1 );
339 aArgs[0] <<= uno::Reference<xml::sax::XDocumentHandler>();
340 xInitialization->initialize(aArgs);
342 else
344 cssu::Reference< cssxs::XParser > xParser(m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
345 xParser->setDocumentHandler(uno::Reference<xml::sax::XDocumentHandler>());
349 m_bIsSAXEventKeeperConnected = false;
354 void XSecController::checkChainingStatus()
355 /****** XSecController/checkChainingStatus ************************************
357 * NAME
358 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
359 * according to the current situation.
361 * SYNOPSIS
362 * checkChainingStatus( );
364 * FUNCTION
365 * The SAXEventKeeper is chained into the SAX chain, when:
366 * 1. some element is being collected, or
367 * 2. the SAX event stream is blocking.
368 * Otherwise, chain off the SAXEventKeeper.
369 ******************************************************************************/
371 if ( m_bIsCollectingElement || m_bIsBlocking )
373 chainOn();
375 else
377 chainOff();
381 void XSecController::initializeSAXChain()
382 /****** XSecController/initializeSAXChain *************************************
384 * NAME
385 * initializeSAXChain -- initializes the SAX chain according to the
386 * current setting.
388 * FUNCTION
389 * Initializes the SAX chain, if the SAXEventKeeper is asked to be always
390 * on the SAX chain, chains it on. Otherwise, starts the
391 * ElementStackKeeper to reserve key SAX events.
392 ******************************************************************************/
394 m_bIsSAXEventKeeperConnected = false;
395 m_bIsCollectingElement = false;
396 m_bIsBlocking = false;
398 chainOff();
401 cssu::Reference< css::io::XInputStream >
402 XSecController::getObjectInputStream( const OUString& objectURL )
403 /****** XSecController/getObjectInputStream ************************************
405 * NAME
406 * getObjectInputStream -- get a XInputStream interface from a SotStorage
408 * SYNOPSIS
409 * xInputStream = getObjectInputStream( objectURL );
411 * INPUTS
412 * objectURL - the object uri
414 * RESULT
415 * xInputStream - the XInputStream interface
416 ******************************************************************************/
418 cssu::Reference< css::io::XInputStream > xObjectInputStream;
420 SAL_WARN_IF( !m_xUriBinding.is(), "xmlsecurity.helper", "Need XUriBinding!" );
422 xObjectInputStream = m_xUriBinding->getUriBinding(objectURL);
424 return xObjectInputStream;
428 * public methods
431 sal_Int32 XSecController::getNewSecurityId( )
433 sal_Int32 nId = m_nNextSecurityId;
434 m_nNextSecurityId++;
435 return nId;
438 void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const cssu::Reference< cssxc::XXMLSecurityContext >& xSecurityContext )
439 /****** XSecController/startMission *******************************************
441 * NAME
442 * startMission -- starts a new security mission.
444 * FUNCTION
445 * get ready for a new mission.
447 * INPUTS
448 * xUriBinding - the Uri binding that provide maps between uris and
449 * XInputStreams
450 * xSecurityContext - the security context component which can provide
451 * cryptoken
452 ******************************************************************************/
454 m_xUriBinding = xUriBinding;
456 m_eStatusOfSecurityComponents = InitializationState::UNINITIALIZED;
457 m_xSecurityContext = xSecurityContext;
459 m_vInternalSignatureInformations.clear();
461 m_bVerifyCurrentSignature = false;
464 void XSecController::setSAXChainConnector(const cssu::Reference< cssl::XInitialization >& xInitialization)
465 /****** XSecController/setSAXChainConnector ***********************************
467 * NAME
468 * setSAXChainConnector -- configures the components which will
469 * collaborate with the SAXEventKeeper on the SAX chain.
471 * SYNOPSIS
472 * setSAXChainConnector(xInitialization);
474 * INPUTS
475 * xInitialization - the previous node on the SAX chain
476 ******************************************************************************/
478 m_bIsPreviousNodeInitializable = true;
479 m_xPreviousNodeOnSAXChain = xInitialization;
481 initializeSAXChain( );
484 void XSecController::clearSAXChainConnector()
485 /****** XSecController/clearSAXChainConnector *********************************
487 * NAME
488 * clearSAXChainConnector -- resets the collaborating components.
489 ******************************************************************************/
491 chainOff();
493 m_xPreviousNodeOnSAXChain = nullptr;
496 void XSecController::endMission()
497 /****** XSecController/endMission *********************************************
499 * NAME
500 * endMission -- forces to end all missions
502 * FUNCTION
503 * Deletes all signature information and forces all missions to an end.
504 ******************************************************************************/
506 sal_Int32 size = m_vInternalSignatureInformations.size();
508 for (int i=0; i<size; ++i)
510 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
512 * ResolvedListener only exist when the security components are created.
515 cssu::Reference< cssxc::sax::XMissionTaker > xMissionTaker
516 ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, cssu::UNO_QUERY );
519 * asks the SignatureCreator/SignatureVerifier to release
520 * all resources it uses.
522 xMissionTaker->endMission();
526 m_xUriBinding = nullptr;
527 m_xSecurityContext = nullptr;
530 * free the status change listener reference to this object
532 if (m_xSAXEventKeeper.is())
533 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( nullptr );
536 namespace
538 void writeUnsignedProperties(
539 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
540 const SignatureInformation& signatureInfo)
543 rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
544 pAttributeList->AddAttribute("Id", "idUnsignedProperties");
545 xDocumentHandler->startElement("xd:UnsignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
549 xDocumentHandler->startElement("xd:UnsignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
552 xDocumentHandler->startElement("xd:CertificateValues", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
555 for (const auto& i: signatureInfo.maEncapsulatedX509Certificates)
557 xDocumentHandler->startElement("xd:EncapsulatedX509Certificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
558 xDocumentHandler->characters(i);
559 xDocumentHandler->endElement("xd:EncapsulatedX509Certificate");
563 xDocumentHandler->endElement("xd:CertificateValues");
566 xDocumentHandler->endElement("xd:UnsignedSignatureProperties");
569 xDocumentHandler->endElement("xd:UnsignedProperties");
574 void XSecController::exportSignature(
575 const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
576 const SignatureInformation& signatureInfo,
577 bool bXAdESCompliantIfODF )
578 /****** XSecController/exportSignature ****************************************
580 * NAME
581 * exportSignature -- export a signature structure to an XDocumentHandler
583 * SYNOPSIS
584 * exportSignature( xDocumentHandler, signatureInfo);
586 * INPUTS
587 * xDocumentHandler - the document handler to receive the signature
588 * signatureInfo - signature to be exported
589 ******************************************************************************/
591 const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors;
592 SvXMLAttributeList *pAttributeList;
595 * Write Signature element
597 pAttributeList = new SvXMLAttributeList();
598 pAttributeList->AddAttribute(
599 "xmlns",
600 NS_XMLDSIG);
602 if (!signatureInfo.ouSignatureId.isEmpty())
604 pAttributeList->AddAttribute(
605 "Id",
606 signatureInfo.ouSignatureId);
609 xDocumentHandler->startElement( "Signature", cssu::Reference< cssxs::XAttributeList > (pAttributeList));
611 /* Write SignedInfo element */
612 xDocumentHandler->startElement(
613 "SignedInfo",
614 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
616 /* Write CanonicalizationMethod element */
617 pAttributeList = new SvXMLAttributeList();
618 pAttributeList->AddAttribute(
619 "Algorithm",
620 ALGO_C14N);
621 xDocumentHandler->startElement( "CanonicalizationMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
622 xDocumentHandler->endElement( "CanonicalizationMethod" );
624 /* Write SignatureMethod element */
625 pAttributeList = new SvXMLAttributeList();
627 // TODO: actually roundtrip this value from parsing documentsignatures.xml - entirely
628 // broken to assume this would in any way relate to the 1st reference's digest algo
630 // Assume that all Reference elements use the same DigestMethod:Algorithm, and that the
631 // SignatureMethod:Algorithm should be the corresponding one.
632 pAttributeList->AddAttribute(
633 "Algorithm",
634 getSignatureURI(signatureInfo.eAlgorithmID, vReferenceInfors[0].nDigestID));
635 xDocumentHandler->startElement( "SignatureMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
636 xDocumentHandler->endElement( "SignatureMethod" );
638 /* Write Reference element */
639 int j;
640 int refNum = vReferenceInfors.size();
642 for(j=0; j<refNum; ++j)
644 const SignatureReferenceInformation& refInfor = vReferenceInfors[j];
646 pAttributeList = new SvXMLAttributeList();
647 if ( refInfor.nType != SignatureReferenceType::SAMEDOCUMENT )
649 * stream reference
652 pAttributeList->AddAttribute(
653 "URI",
654 refInfor.ouURI);
656 else
658 * same-document reference
661 pAttributeList->AddAttribute(
662 "URI",
663 "#" + refInfor.ouURI);
666 xDocumentHandler->startElement( "Reference", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
668 /* Write Transforms element */
669 if (refInfor.nType == SignatureReferenceType::XMLSTREAM)
671 * xml stream, so c14n transform is needed
674 xDocumentHandler->startElement(
675 "Transforms",
676 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
678 pAttributeList = new SvXMLAttributeList();
679 pAttributeList->AddAttribute(
680 "Algorithm",
681 ALGO_C14N);
682 xDocumentHandler->startElement(
683 "Transform",
684 cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
685 xDocumentHandler->endElement( "Transform" );
687 xDocumentHandler->endElement( "Transforms" );
690 /* Write DigestMethod element */
691 pAttributeList = new SvXMLAttributeList();
692 pAttributeList->AddAttribute(
693 "Algorithm",
694 getDigestURI(refInfor.nDigestID));
695 xDocumentHandler->startElement(
696 "DigestMethod",
697 cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
698 xDocumentHandler->endElement( "DigestMethod" );
700 /* Write DigestValue element */
701 xDocumentHandler->startElement(
702 "DigestValue",
703 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
704 xDocumentHandler->characters( refInfor.ouDigestValue );
705 xDocumentHandler->endElement( "DigestValue" );
707 xDocumentHandler->endElement( "Reference" );
710 xDocumentHandler->endElement( "SignedInfo" );
712 /* Write SignatureValue element */
713 xDocumentHandler->startElement(
714 "SignatureValue",
715 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
716 xDocumentHandler->characters( signatureInfo.ouSignatureValue );
717 xDocumentHandler->endElement( "SignatureValue" );
719 /* Write KeyInfo element */
720 xDocumentHandler->startElement(
721 "KeyInfo",
722 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
724 // GPG or X509 key?
725 if (!signatureInfo.ouGpgCertificate.isEmpty())
727 pAttributeList = new SvXMLAttributeList();
728 pAttributeList->AddAttribute("xmlns:loext", NS_LOEXT);
729 /* Write PGPData element */
730 xDocumentHandler->startElement(
731 "PGPData",
732 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
734 /* Write keyid element */
735 xDocumentHandler->startElement(
736 "PGPKeyID",
737 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
738 xDocumentHandler->characters( signatureInfo.ouCertDigest );
739 xDocumentHandler->endElement( "PGPKeyID" );
741 /* Write PGPKeyPacket element */
742 if (!signatureInfo.ouGpgCertificate.isEmpty())
744 xDocumentHandler->startElement(
745 "PGPKeyPacket",
746 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
747 xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
748 xDocumentHandler->endElement( "PGPKeyPacket" );
751 /* Write PGPOwner element */
752 xDocumentHandler->startElement(
753 "loext:PGPOwner",
754 cssu::Reference< cssxs::XAttributeList >(new SvXMLAttributeList()));
755 xDocumentHandler->characters( signatureInfo.ouGpgOwner );
756 xDocumentHandler->endElement( "loext:PGPOwner" );
758 xDocumentHandler->endElement( "PGPData" );
760 else
762 /* Write X509Data element */
763 xDocumentHandler->startElement(
764 "X509Data",
765 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
767 /* Write X509IssuerSerial element */
768 xDocumentHandler->startElement(
769 "X509IssuerSerial",
770 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
772 /* Write X509IssuerName element */
773 xDocumentHandler->startElement(
774 "X509IssuerName",
775 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
776 xDocumentHandler->characters( signatureInfo.ouX509IssuerName );
777 xDocumentHandler->endElement( "X509IssuerName" );
779 /* Write X509SerialNumber element */
780 xDocumentHandler->startElement(
781 "X509SerialNumber",
782 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
783 xDocumentHandler->characters( signatureInfo.ouX509SerialNumber );
784 xDocumentHandler->endElement( "X509SerialNumber" );
786 xDocumentHandler->endElement( "X509IssuerSerial" );
788 /* Write X509Certificate element */
789 if (!signatureInfo.ouX509Certificate.isEmpty())
791 xDocumentHandler->startElement(
792 "X509Certificate",
793 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
794 xDocumentHandler->characters( signatureInfo.ouX509Certificate );
795 xDocumentHandler->endElement( "X509Certificate" );
798 xDocumentHandler->endElement( "X509Data" );
801 xDocumentHandler->endElement( "KeyInfo" );
803 OUString sDate;
805 /* Write Object element */
806 xDocumentHandler->startElement(
807 "Object",
808 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
810 /* Write SignatureProperties element */
811 xDocumentHandler->startElement(
812 "SignatureProperties",
813 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
815 /* Write SignatureProperty element */
816 pAttributeList = new SvXMLAttributeList();
817 pAttributeList->AddAttribute(
818 "Id",
819 signatureInfo.ouPropertyId);
820 pAttributeList->AddAttribute(
821 "Target",
822 "#" + signatureInfo.ouSignatureId);
823 xDocumentHandler->startElement(
824 "SignatureProperty",
825 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
827 /* Write timestamp element */
829 pAttributeList = new SvXMLAttributeList();
830 pAttributeList->AddAttribute(
831 "xmlns:dc",
832 NS_DC);
834 xDocumentHandler->startElement(
835 "dc:date",
836 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
838 OUStringBuffer buffer;
839 //If the xml signature was already contained in the document,
840 //then we use the original date and time string, rather then the
841 //converted one. This avoids writing a different string due to
842 //e.g. rounding issues and thus breaking the signature.
843 if (!signatureInfo.ouDateTime.isEmpty())
844 buffer = signatureInfo.ouDateTime;
845 else
847 buffer = utl::toISO8601(signatureInfo.stDateTime);
848 // xsd:dateTime must use period as separator for fractional seconds, while
849 // utl::toISO8601 uses comma (as allowed, and even recommended, by ISO8601).
850 buffer.replace(',', '.');
852 sDate = buffer.makeStringAndClear();
853 xDocumentHandler->characters( sDate );
855 xDocumentHandler->endElement(
856 "dc:date");
858 xDocumentHandler->endElement( "SignatureProperty" );
861 // Write signature description.
862 if (!signatureInfo.ouDescription.isEmpty())
864 // SignatureProperty element.
865 pAttributeList = new SvXMLAttributeList();
866 pAttributeList->AddAttribute("Id", signatureInfo.ouDescriptionPropertyId);
867 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
868 xDocumentHandler->startElement("SignatureProperty", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
871 // Description element.
872 pAttributeList = new SvXMLAttributeList();
873 pAttributeList->AddAttribute("xmlns:dc", NS_DC);
875 xDocumentHandler->startElement("dc:description", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
876 xDocumentHandler->characters(signatureInfo.ouDescription);
877 xDocumentHandler->endElement("dc:description");
880 xDocumentHandler->endElement("SignatureProperty");
883 xDocumentHandler->endElement( "SignatureProperties" );
885 xDocumentHandler->endElement( "Object" );
887 // In XAdES, write another Object element for the QualifyingProperties
888 if (bXAdESCompliantIfODF)
890 pAttributeList = new SvXMLAttributeList();
891 pAttributeList->AddAttribute("xmlns:xd", NS_XD);
892 xDocumentHandler->startElement(
893 "Object",
894 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
896 pAttributeList = new SvXMLAttributeList();
897 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
898 xDocumentHandler->startElement(
899 "xd:QualifyingProperties",
900 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
901 DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate, true);
902 writeUnsignedProperties(xDocumentHandler, signatureInfo);
903 xDocumentHandler->endElement( "xd:QualifyingProperties" );
905 xDocumentHandler->endElement( "Object" );
908 xDocumentHandler->endElement( "Signature" );
911 void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation)
913 OOXMLSecExporter aExporter(mxCtx, xRootStorage, xDocumentHandler, rInformation);
914 aExporter.writeSignature();
917 SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const
919 SignatureInformation aInf( 0 );
920 int nIndex = findSignatureInfor(nSecurityId);
921 SAL_WARN_IF( nIndex == -1, "xmlsecurity.helper", "getSignatureInformation - SecurityId is invalid!" );
922 if ( nIndex != -1)
924 aInf = m_vInternalSignatureInformations[nIndex].signatureInfor;
926 return aInf;
929 SignatureInformations XSecController::getSignatureInformations() const
931 SignatureInformations vInfors;
932 int sigNum = m_vInternalSignatureInformations.size();
934 for (int i=0; i<sigNum; ++i)
936 SignatureInformation si = m_vInternalSignatureInformations[i].signatureInfor;
937 vInfors.push_back(si);
940 return vInfors;
944 * XSAXEventKeeperStatusChangeListener
947 void SAL_CALL XSecController::blockingStatusChanged( sal_Bool isBlocking )
949 m_bIsBlocking = isBlocking;
950 checkChainingStatus();
953 void SAL_CALL XSecController::collectionStatusChanged(
954 sal_Bool isInsideCollectedElement )
956 m_bIsCollectingElement = isInsideCollectedElement;
957 checkChainingStatus();
960 void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/)
966 * XSignatureCreationResultListener
968 void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
970 int index = findSignatureInfor(securityId);
971 assert(index != -1 && "Signature Not Found!");
972 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
973 signatureInfor.nStatus = nResult;
977 * XSignatureVerifyResultListener
979 void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
981 int index = findSignatureInfor(securityId);
982 assert(index != -1 && "Signature Not Found!");
983 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
984 signatureInfor.nStatus = nResult;
987 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */