Bump version to 6.0-36
[LibreOffice.git] / xmlsecurity / source / helper / xsecctl.cxx
blob8cbe75fbef44e5d4c147b2087e533f544225536d
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 #ifdef ANDROID
37 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
38 #endif
39 #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
40 #include <com/sun/star/embed/ElementModes.hpp>
41 #include <com/sun/star/beans/StringPair.hpp>
43 #include <xmloff/attrlist.hxx>
44 #include <rtl/math.hxx>
45 #include <rtl/ref.hxx>
46 #include <unotools/datetime.hxx>
47 #include <comphelper/ofopxmlhelper.hxx>
48 #include <sax/tools/converter.hxx>
49 #include "ooxmlsecexporter.hxx"
50 #include <xmlsignaturehelper2.hxx>
52 namespace cssu = com::sun::star::uno;
53 namespace cssl = com::sun::star::lang;
54 namespace cssxc = com::sun::star::xml::crypto;
55 namespace cssxs = com::sun::star::xml::sax;
56 using namespace com::sun::star;
58 namespace
60 OUString getDigestURI(sal_Int32 nID)
62 switch( nID )
64 case cssxc::DigestID::SHA1:
65 return OUString(ALGO_XMLDSIGSHA1);
66 case cssxc::DigestID::SHA256:
67 return OUString(ALGO_XMLDSIGSHA256);
68 case cssxc::DigestID::SHA512:
69 return OUString(ALGO_XMLDSIGSHA512);
70 default:
71 return OUString(ALGO_XMLDSIGSHA1);
74 OUString getSignatureURI(sal_Int32 nID)
76 switch( nID )
78 case cssxc::DigestID::SHA1:
79 return OUString(ALGO_RSASHA1);
80 case cssxc::DigestID::SHA256:
81 return OUString(ALGO_RSASHA256);
82 case cssxc::DigestID::SHA512:
83 return OUString(ALGO_RSASHA512);
84 default:
85 return OUString(ALGO_RSASHA1);
90 XSecController::XSecController( const cssu::Reference<cssu::XComponentContext>& rxCtx )
91 : mxCtx(rxCtx)
92 , m_nNextSecurityId(1)
93 , m_bIsPreviousNodeInitializable(false)
94 , m_bIsSAXEventKeeperConnected(false)
95 , m_bIsCollectingElement(false)
96 , m_bIsBlocking(false)
97 , m_eStatusOfSecurityComponents(InitializationState::UNINITIALIZED)
98 , m_bIsSAXEventKeeperSticky(false)
99 , m_nReservedSignatureId(0)
100 , m_bVerifyCurrentSignature(false)
104 XSecController::~XSecController()
110 * private methods
112 int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const
113 /****** XSecController/findSignatureInfor *************************************
115 * NAME
116 * findSignatureInfor -- find SignatureInformation struct for a particular
117 * signature
119 * SYNOPSIS
120 * index = findSignatureInfor( nSecurityId );
122 * INPUTS
123 * nSecurityId - the signature's id
125 * RESULT
126 * index - the index of the signature, or -1 when no such signature
127 * existing
128 ******************************************************************************/
130 int i;
131 int size = m_vInternalSignatureInformations.size();
133 for (i=0; i<size; ++i)
135 if (m_vInternalSignatureInformations[i].signatureInfor.nSecurityId == nSecurityId)
137 return i;
141 return -1;
144 void XSecController::createXSecComponent( )
145 /****** XSecController/createXSecComponent ************************************
147 * NAME
148 * bResult = createXSecComponent -- creates xml security components
150 * FUNCTION
151 * Creates xml security components, including:
152 * 1. an xml signature bridge component
153 * 2. an XMLDocumentWrapper component
154 * 3. a SAXEventKeeper component
155 ******************************************************************************/
158 * marks all security components are not available.
160 m_eStatusOfSecurityComponents = InitializationState::FAILTOINITIALIZED;
161 m_xXMLSignature = nullptr;
162 m_xXMLDocumentWrapper = nullptr;
163 m_xSAXEventKeeper = nullptr;
165 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
167 #if HAVE_FEATURE_GPGME
168 uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, cssu::UNO_QUERY );
169 if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
170 m_xXMLSignature.set(new XMLSignature_GpgImpl());
171 else // xmlsec or mscrypt
172 #endif
173 m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), cssu::UNO_QUERY);
175 bool bSuccess = m_xXMLSignature.is();
176 if ( bSuccess )
178 * XMLSignature created successfully.
180 m_xXMLDocumentWrapper = new XMLDocumentWrapper_XmlSecImpl();
182 bSuccess &= m_xXMLDocumentWrapper.is();
183 if ( bSuccess )
184 m_xSAXEventKeeper = new SAXEventKeeperImpl();
186 bSuccess &= m_xSAXEventKeeper.is();
188 if (bSuccess)
190 * SAXEventKeeper created successfully.
193 cssu::Sequence <cssu::Any> arg(1);
194 arg[0] <<= uno::Reference<xml::wrapper::XXMLDocumentWrapper>(m_xXMLDocumentWrapper.get());
195 m_xSAXEventKeeper->initialize(arg);
197 cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >
198 xStatusChangeListener = this;
200 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
202 m_eStatusOfSecurityComponents = InitializationState::INITIALIZED;
206 bool XSecController::chainOn()
207 /****** XSecController/chainOn ************************************************
209 * NAME
210 * chainOn -- tries to connect the SAXEventKeeper with the SAX chain.
212 * SYNOPSIS
213 * bJustChainingOn = chainOn();
215 * FUNCTION
216 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
217 * creates xml security components, and chains the SAXEventKeeper into
218 * the SAX chain.
219 * Before being chained in, the SAXEventKeeper needs to receive all
220 * missed key SAX events, which can promise the DOM tree bufferred by the
221 * SAXEventKeeper has the same structure with the original document.
223 * RESULT
224 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
225 * SAX chain.
227 * NOTES
228 * Sometimes, the last key SAX event can't be transferred to the
229 * SAXEventKeeper together.
230 * For instance, at the time an referenced element is detected, the
231 * startElement event has already been reserved by the ElementStackKeeper.
232 * Meanwhile, an ElementCollector needs to be created before the
233 * SAXEventKeeper receives that startElement event.
234 * So for the SAXEventKeeper, it needs to receive all missed key SAX
235 * events except that startElement event, then adds a new
236 * ElementCollector, then receives that startElement event.
237 ******************************************************************************/
239 bool rc = false;
241 if (!m_bIsSAXEventKeeperSticky && !m_bIsSAXEventKeeperConnected)
243 if ( m_eStatusOfSecurityComponents == InitializationState::UNINITIALIZED )
245 createXSecComponent();
248 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
250 * if all security components are ready, chains on the SAXEventKeeper
254 * disconnect the SAXEventKeeper with its current output handler,
255 * to make sure no SAX event is forwarded during the connecting
256 * phase.
258 m_xSAXEventKeeper->setNextHandler( nullptr );
260 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), cssu::UNO_QUERY);
263 * connects the previous document handler on the SAX chain
265 if ( m_xPreviousNodeOnSAXChain.is() )
267 if ( m_bIsPreviousNodeInitializable )
269 cssu::Reference< cssl::XInitialization > xInitialization
270 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
272 cssu::Sequence<cssu::Any> aArgs( 1 );
273 aArgs[0] <<= xSEKHandler;
274 xInitialization->initialize(aArgs);
276 else
278 cssu::Reference< cssxs::XParser > xParser
279 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
280 xParser->setDocumentHandler( xSEKHandler );
285 * connects the next document handler on the SAX chain
287 m_xSAXEventKeeper->setNextHandler(uno::Reference<xml::sax::XDocumentHandler>());
289 m_bIsSAXEventKeeperConnected = true;
291 rc = true;
295 return rc;
298 void XSecController::chainOff()
299 /****** XSecController/chainOff ***********************************************
301 * NAME
302 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
303 ******************************************************************************/
305 if (!m_bIsSAXEventKeeperSticky )
307 if (m_bIsSAXEventKeeperConnected)
309 m_xSAXEventKeeper->setNextHandler( nullptr );
311 if ( m_xPreviousNodeOnSAXChain.is() )
313 if ( m_bIsPreviousNodeInitializable )
315 cssu::Reference< cssl::XInitialization > xInitialization
316 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
318 cssu::Sequence<cssu::Any> aArgs( 1 );
319 aArgs[0] <<= uno::Reference<xml::sax::XDocumentHandler>();
320 xInitialization->initialize(aArgs);
322 else
324 cssu::Reference< cssxs::XParser > xParser(m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
325 xParser->setDocumentHandler(uno::Reference<xml::sax::XDocumentHandler>());
329 m_bIsSAXEventKeeperConnected = false;
334 void XSecController::checkChainingStatus()
335 /****** XSecController/checkChainingStatus ************************************
337 * NAME
338 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
339 * according to the current situation.
341 * SYNOPSIS
342 * checkChainingStatus( );
344 * FUNCTION
345 * The SAXEventKeeper is chained into the SAX chain, when:
346 * 1. some element is being collected, or
347 * 2. the SAX event stream is blocking.
348 * Otherwise, chain off the SAXEventKeeper.
349 ******************************************************************************/
351 if ( m_bIsCollectingElement || m_bIsBlocking )
353 chainOn();
355 else
357 chainOff();
361 void XSecController::initializeSAXChain()
362 /****** XSecController/initializeSAXChain *************************************
364 * NAME
365 * initializeSAXChain -- initializes the SAX chain according to the
366 * current setting.
368 * FUNCTION
369 * Initializes the SAX chain, if the SAXEventKeeper is asked to be always
370 * on the SAX chain, chains it on. Otherwise, starts the
371 * ElementStackKeeper to reserve key SAX events.
372 ******************************************************************************/
374 m_bIsSAXEventKeeperConnected = false;
375 m_bIsCollectingElement = false;
376 m_bIsBlocking = false;
378 chainOff();
381 cssu::Reference< css::io::XInputStream >
382 XSecController::getObjectInputStream( const OUString& objectURL )
383 /****** XSecController/getObjectInputStream ************************************
385 * NAME
386 * getObjectInputStream -- get a XInputStream interface from a SotStorage
388 * SYNOPSIS
389 * xInputStream = getObjectInputStream( objectURL );
391 * INPUTS
392 * objectURL - the object uri
394 * RESULT
395 * xInputStream - the XInputStream interface
396 ******************************************************************************/
398 cssu::Reference< css::io::XInputStream > xObjectInputStream;
400 SAL_WARN_IF( !m_xUriBinding.is(), "xmlsecurity.helper", "Need XUriBinding!" );
402 xObjectInputStream = m_xUriBinding->getUriBinding(objectURL);
404 return xObjectInputStream;
408 * public methods
411 sal_Int32 XSecController::getNewSecurityId( )
413 sal_Int32 nId = m_nNextSecurityId;
414 m_nNextSecurityId++;
415 return nId;
418 void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const cssu::Reference< cssxc::XXMLSecurityContext >& xSecurityContext )
419 /****** XSecController/startMission *******************************************
421 * NAME
422 * startMission -- starts a new security mission.
424 * FUNCTION
425 * get ready for a new mission.
427 * INPUTS
428 * xUriBinding - the Uri binding that provide maps between uris and
429 * XInputStreams
430 * xSecurityContext - the security context component which can provide
431 * cryptoken
432 ******************************************************************************/
434 m_xUriBinding = xUriBinding;
436 m_eStatusOfSecurityComponents = InitializationState::UNINITIALIZED;
437 m_xSecurityContext = xSecurityContext;
439 m_vInternalSignatureInformations.clear();
441 m_bVerifyCurrentSignature = false;
444 void XSecController::setSAXChainConnector(const cssu::Reference< cssl::XInitialization >& xInitialization)
445 /****** XSecController/setSAXChainConnector ***********************************
447 * NAME
448 * setSAXChainConnector -- configures the components which will
449 * collaborate with the SAXEventKeeper on the SAX chain.
451 * SYNOPSIS
452 * setSAXChainConnector(xInitialization);
454 * INPUTS
455 * xInitialization - the previous node on the SAX chain
456 ******************************************************************************/
458 m_bIsPreviousNodeInitializable = true;
459 m_xPreviousNodeOnSAXChain = xInitialization;
461 initializeSAXChain( );
464 void XSecController::clearSAXChainConnector()
465 /****** XSecController/clearSAXChainConnector *********************************
467 * NAME
468 * clearSAXChainConnector -- resets the collaborating components.
469 ******************************************************************************/
471 chainOff();
473 m_xPreviousNodeOnSAXChain = nullptr;
476 void XSecController::endMission()
477 /****** XSecController/endMission *********************************************
479 * NAME
480 * endMission -- forces to end all missions
482 * FUNCTION
483 * Deletes all signature information and forces all missions to an end.
484 ******************************************************************************/
486 sal_Int32 size = m_vInternalSignatureInformations.size();
488 for (int i=0; i<size; ++i)
490 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
492 * ResolvedListener only exist when the security components are created.
495 cssu::Reference< cssxc::sax::XMissionTaker > xMissionTaker
496 ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, cssu::UNO_QUERY );
499 * asks the SignatureCreator/SignatureVerifier to release
500 * all resources it uses.
502 xMissionTaker->endMission();
506 m_xUriBinding = nullptr;
507 m_xSecurityContext = nullptr;
510 * free the status change listener reference to this object
512 if (m_xSAXEventKeeper.is())
513 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( nullptr );
516 namespace
518 void writeUnsignedProperties(
519 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
520 const SignatureInformation& signatureInfo)
523 rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
524 pAttributeList->AddAttribute("Id", "idUnsignedProperties");
525 xDocumentHandler->startElement("xd:UnsignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
529 xDocumentHandler->startElement("xd:UnsignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
532 xDocumentHandler->startElement("xd:CertificateValues", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
535 for (const auto& i: signatureInfo.maEncapsulatedX509Certificates)
537 xDocumentHandler->startElement("xd:EncapsulatedX509Certificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
538 xDocumentHandler->characters(i);
539 xDocumentHandler->endElement("xd:EncapsulatedX509Certificate");
543 xDocumentHandler->endElement("xd:CertificateValues");
546 xDocumentHandler->endElement("xd:UnsignedSignatureProperties");
549 xDocumentHandler->endElement("xd:UnsignedProperties");
554 void XSecController::exportSignature(
555 const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
556 const SignatureInformation& signatureInfo,
557 bool bXAdESCompliantIfODF )
558 /****** XSecController/exportSignature ****************************************
560 * NAME
561 * exportSignature -- export a signature structure to an XDocumentHandler
563 * SYNOPSIS
564 * exportSignature( xDocumentHandler, signatureInfo);
566 * INPUTS
567 * xDocumentHandler - the document handler to receive the signature
568 * signatureInfo - signature to be exported
569 ******************************************************************************/
571 const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors;
572 SvXMLAttributeList *pAttributeList;
575 * Write Signature element
577 pAttributeList = new SvXMLAttributeList();
578 pAttributeList->AddAttribute(
579 "xmlns",
580 NS_XMLDSIG);
582 if (!signatureInfo.ouSignatureId.isEmpty())
584 pAttributeList->AddAttribute(
585 "Id",
586 signatureInfo.ouSignatureId);
589 xDocumentHandler->startElement( "Signature", cssu::Reference< cssxs::XAttributeList > (pAttributeList));
591 /* Write SignedInfo element */
592 xDocumentHandler->startElement(
593 "SignedInfo",
594 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
596 /* Write CanonicalizationMethod element */
597 pAttributeList = new SvXMLAttributeList();
598 pAttributeList->AddAttribute(
599 "Algorithm",
600 ALGO_C14N);
601 xDocumentHandler->startElement( "CanonicalizationMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
602 xDocumentHandler->endElement( "CanonicalizationMethod" );
604 /* Write SignatureMethod element */
605 pAttributeList = new SvXMLAttributeList();
607 // TODO: actually roundtrip this value from parsing documentsignatures.xml - entirely
608 // broken to assume this would in any way relate to the 1st reference's digest algo
610 // Assume that all Reference elements use the same DigestMethod:Algorithm, and that the
611 // SignatureMethod:Algorithm should be the corresponding one.
612 pAttributeList->AddAttribute(
613 "Algorithm",
614 getSignatureURI(vReferenceInfors[0].nDigestID));
615 xDocumentHandler->startElement( "SignatureMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
616 xDocumentHandler->endElement( "SignatureMethod" );
618 /* Write Reference element */
619 int j;
620 int refNum = vReferenceInfors.size();
622 for(j=0; j<refNum; ++j)
624 const SignatureReferenceInformation& refInfor = vReferenceInfors[j];
626 pAttributeList = new SvXMLAttributeList();
627 if ( refInfor.nType != SignatureReferenceType::SAMEDOCUMENT )
629 * stream reference
632 pAttributeList->AddAttribute(
633 "URI",
634 refInfor.ouURI);
636 else
638 * same-document reference
641 pAttributeList->AddAttribute(
642 "URI",
643 "#" + refInfor.ouURI);
646 xDocumentHandler->startElement( "Reference", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
648 /* Write Transforms element */
649 if (refInfor.nType == SignatureReferenceType::XMLSTREAM)
651 * xml stream, so c14n transform is needed
654 xDocumentHandler->startElement(
655 "Transforms",
656 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
658 pAttributeList = new SvXMLAttributeList();
659 pAttributeList->AddAttribute(
660 "Algorithm",
661 ALGO_C14N);
662 xDocumentHandler->startElement(
663 "Transform",
664 cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
665 xDocumentHandler->endElement( "Transform" );
667 xDocumentHandler->endElement( "Transforms" );
670 /* Write DigestMethod element */
671 pAttributeList = new SvXMLAttributeList();
672 pAttributeList->AddAttribute(
673 "Algorithm",
674 getDigestURI(refInfor.nDigestID));
675 xDocumentHandler->startElement(
676 "DigestMethod",
677 cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
678 xDocumentHandler->endElement( "DigestMethod" );
680 /* Write DigestValue element */
681 xDocumentHandler->startElement(
682 "DigestValue",
683 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
684 xDocumentHandler->characters( refInfor.ouDigestValue );
685 xDocumentHandler->endElement( "DigestValue" );
687 xDocumentHandler->endElement( "Reference" );
690 xDocumentHandler->endElement( "SignedInfo" );
692 /* Write SignatureValue element */
693 xDocumentHandler->startElement(
694 "SignatureValue",
695 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
696 xDocumentHandler->characters( signatureInfo.ouSignatureValue );
697 xDocumentHandler->endElement( "SignatureValue" );
699 /* Write KeyInfo element */
700 xDocumentHandler->startElement(
701 "KeyInfo",
702 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
704 // GPG or X509 key?
705 if (!signatureInfo.ouGpgCertificate.isEmpty())
707 pAttributeList = new SvXMLAttributeList();
708 pAttributeList->AddAttribute("xmlns:loext", NS_LOEXT);
709 /* Write PGPData element */
710 xDocumentHandler->startElement(
711 "PGPData",
712 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
714 /* Write keyid element */
715 xDocumentHandler->startElement(
716 "PGPKeyID",
717 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
718 xDocumentHandler->characters( signatureInfo.ouCertDigest );
719 xDocumentHandler->endElement( "PGPKeyID" );
721 /* Write PGPKeyPacket element */
722 if (!signatureInfo.ouGpgCertificate.isEmpty())
724 xDocumentHandler->startElement(
725 "PGPKeyPacket",
726 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
727 xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
728 xDocumentHandler->endElement( "PGPKeyPacket" );
731 /* Write PGPOwner element */
732 xDocumentHandler->startElement(
733 "loext:PGPOwner",
734 cssu::Reference< cssxs::XAttributeList >(new SvXMLAttributeList()));
735 xDocumentHandler->characters( signatureInfo.ouGpgOwner );
736 xDocumentHandler->endElement( "loext:PGPOwner" );
738 xDocumentHandler->endElement( "PGPData" );
740 else
742 /* Write X509Data element */
743 xDocumentHandler->startElement(
744 "X509Data",
745 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
747 /* Write X509IssuerSerial element */
748 xDocumentHandler->startElement(
749 "X509IssuerSerial",
750 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
752 /* Write X509IssuerName element */
753 xDocumentHandler->startElement(
754 "X509IssuerName",
755 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
756 xDocumentHandler->characters( signatureInfo.ouX509IssuerName );
757 xDocumentHandler->endElement( "X509IssuerName" );
759 /* Write X509SerialNumber element */
760 xDocumentHandler->startElement(
761 "X509SerialNumber",
762 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
763 xDocumentHandler->characters( signatureInfo.ouX509SerialNumber );
764 xDocumentHandler->endElement( "X509SerialNumber" );
766 xDocumentHandler->endElement( "X509IssuerSerial" );
768 /* Write X509Certificate element */
769 if (!signatureInfo.ouX509Certificate.isEmpty())
771 xDocumentHandler->startElement(
772 "X509Certificate",
773 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
774 xDocumentHandler->characters( signatureInfo.ouX509Certificate );
775 xDocumentHandler->endElement( "X509Certificate" );
778 xDocumentHandler->endElement( "X509Data" );
781 xDocumentHandler->endElement( "KeyInfo" );
783 OUString sDate;
785 /* Write Object element */
786 xDocumentHandler->startElement(
787 "Object",
788 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
790 /* Write SignatureProperties element */
791 xDocumentHandler->startElement(
792 "SignatureProperties",
793 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
795 /* Write SignatureProperty element */
796 pAttributeList = new SvXMLAttributeList();
797 pAttributeList->AddAttribute(
798 "Id",
799 signatureInfo.ouPropertyId);
800 pAttributeList->AddAttribute(
801 "Target",
802 "#" + signatureInfo.ouSignatureId);
803 xDocumentHandler->startElement(
804 "SignatureProperty",
805 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
807 /* Write timestamp element */
809 pAttributeList = new SvXMLAttributeList();
810 pAttributeList->AddAttribute(
811 "xmlns:dc",
812 NS_DC);
814 xDocumentHandler->startElement(
815 "dc:date",
816 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
818 OUStringBuffer buffer;
819 //If the xml signature was already contained in the document,
820 //then we use the original date and time string, rather then the
821 //converted one. This avoids writing a different string due to
822 //e.g. rounding issues and thus breaking the signature.
823 if (!signatureInfo.ouDateTime.isEmpty())
824 buffer = signatureInfo.ouDateTime;
825 else
827 buffer = utl::toISO8601(signatureInfo.stDateTime);
828 // xsd:dateTime must use period as separator for fractional seconds, while
829 // utl::toISO8601 uses comma (as allowed, and even recommended, by ISO8601).
830 buffer.replace(',', '.');
832 sDate = buffer.makeStringAndClear();
833 xDocumentHandler->characters( sDate );
835 xDocumentHandler->endElement(
836 "dc:date");
838 xDocumentHandler->endElement( "SignatureProperty" );
840 if (!signatureInfo.ouSignatureLineId.isEmpty())
842 pAttributeList = new SvXMLAttributeList();
843 pAttributeList->AddAttribute(
844 "xmlns:loext",
845 "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0");
846 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
848 xDocumentHandler->startElement(
849 "SignatureProperty",
850 cssu::Reference<cssxs::XAttributeList>(pAttributeList));
852 // Write SignatureLineId element
853 xDocumentHandler->startElement(
854 "loext:SignatureLineId",
855 cssu::Reference<cssxs::XAttributeList>(new SvXMLAttributeList()));
856 xDocumentHandler->characters(signatureInfo.ouSignatureLineId);
857 xDocumentHandler->endElement("loext:SignatureLineId");
859 xDocumentHandler->endElement("SignatureProperty");
863 // Write signature description.
864 if (!signatureInfo.ouDescription.isEmpty())
866 // SignatureProperty element.
867 pAttributeList = new SvXMLAttributeList();
868 pAttributeList->AddAttribute("Id", signatureInfo.ouDescriptionPropertyId);
869 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
870 xDocumentHandler->startElement("SignatureProperty", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
873 // Description element.
874 pAttributeList = new SvXMLAttributeList();
875 pAttributeList->AddAttribute("xmlns:dc", NS_DC);
877 xDocumentHandler->startElement("dc:description", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
878 xDocumentHandler->characters(signatureInfo.ouDescription);
879 xDocumentHandler->endElement("dc:description");
882 xDocumentHandler->endElement("SignatureProperty");
885 xDocumentHandler->endElement( "SignatureProperties" );
887 xDocumentHandler->endElement( "Object" );
889 // In XAdES, write another Object element for the QualifyingProperties
890 if (bXAdESCompliantIfODF)
892 pAttributeList = new SvXMLAttributeList();
893 pAttributeList->AddAttribute("xmlns:xd", NS_XD);
894 xDocumentHandler->startElement(
895 "Object",
896 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
898 pAttributeList = new SvXMLAttributeList();
899 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
900 xDocumentHandler->startElement(
901 "xd:QualifyingProperties",
902 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
903 DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate);
904 writeUnsignedProperties(xDocumentHandler, signatureInfo);
905 xDocumentHandler->endElement( "xd:QualifyingProperties" );
907 xDocumentHandler->endElement( "Object" );
910 xDocumentHandler->endElement( "Signature" );
913 void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation)
915 OOXMLSecExporter aExporter(mxCtx, xRootStorage, xDocumentHandler, rInformation);
916 aExporter.writeSignature();
919 SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const
921 SignatureInformation aInf( 0 );
922 int nIndex = findSignatureInfor(nSecurityId);
923 SAL_WARN_IF( nIndex == -1, "xmlsecurity.helper", "getSignatureInformation - SecurityId is invalid!" );
924 if ( nIndex != -1)
926 aInf = m_vInternalSignatureInformations[nIndex].signatureInfor;
928 return aInf;
931 SignatureInformations XSecController::getSignatureInformations() const
933 SignatureInformations vInfors;
934 int sigNum = m_vInternalSignatureInformations.size();
936 for (int i=0; i<sigNum; ++i)
938 SignatureInformation si = m_vInternalSignatureInformations[i].signatureInfor;
939 vInfors.push_back(si);
942 return vInfors;
946 * XSAXEventKeeperStatusChangeListener
949 void SAL_CALL XSecController::blockingStatusChanged( sal_Bool isBlocking )
951 m_bIsBlocking = isBlocking;
952 checkChainingStatus();
955 void SAL_CALL XSecController::collectionStatusChanged(
956 sal_Bool isInsideCollectedElement )
958 m_bIsCollectingElement = isInsideCollectedElement;
959 checkChainingStatus();
962 void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/)
968 * XSignatureCreationResultListener
970 void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
972 int index = findSignatureInfor(securityId);
973 assert(index != -1 && "Signature Not Found!");
974 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
975 signatureInfor.nStatus = nResult;
979 * XSignatureVerifyResultListener
981 void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
983 int index = findSignatureInfor(securityId);
984 assert(index != -1 && "Signature Not Found!");
985 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
986 signatureInfor.nStatus = nResult;
989 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */