1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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>
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
;
48 OUString
getDigestURI(sal_Int32 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
;
59 return ALGO_XMLDSIGSHA1
;
62 OUString
getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm
, sal_Int32 nDigestID
)
66 if (eAlgorithm
== svl::crypto::SignatureMethodAlgorithm::ECDSA
)
70 case css::xml::crypto::DigestID::SHA1
:
71 aRet
= ALGO_ECDSASHA1
;
73 case css::xml::crypto::DigestID::SHA256
:
74 aRet
= ALGO_ECDSASHA256
;
76 case css::xml::crypto::DigestID::SHA512
:
77 aRet
= ALGO_ECDSASHA512
;
80 aRet
= ALGO_ECDSASHA1
;
89 case css::xml::crypto::DigestID::SHA1
:
91 case css::xml::crypto::DigestID::SHA256
:
92 return ALGO_RSASHA256
;
93 case css::xml::crypto::DigestID::SHA512
:
94 return ALGO_RSASHA512
;
101 XSecController::XSecController( const css::uno::Reference
<css::uno::XComponentContext
>& 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()
123 int XSecController::findSignatureInfor( sal_Int32 nSecurityId
) const
124 /****** XSecController/findSignatureInfor *************************************
127 * findSignatureInfor -- find SignatureInformation struct for a particular
131 * index = findSignatureInfor( nSecurityId );
134 * nSecurityId - the signature's id
137 * index - the index of the signature, or -1 when no such signature
139 ******************************************************************************/
142 int size
= m_vInternalSignatureInformations
.size();
144 for (i
=0; i
<size
; ++i
)
146 if (m_vInternalSignatureInformations
[i
].signatureInfor
.nSecurityId
== nSecurityId
)
155 void XSecController::createXSecComponent( )
156 /****** XSecController/createXSecComponent ************************************
159 * bResult = createXSecComponent -- creates xml security components
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
184 m_xXMLSignature
.set(xMCF
->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx
), css::uno::UNO_QUERY
);
186 bool bSuccess
= m_xXMLSignature
.is();
189 * XMLSignature created successfully.
191 m_xXMLDocumentWrapper
= new XMLDocumentWrapper_XmlSecImpl();
193 bSuccess
&= m_xXMLDocumentWrapper
.is();
195 m_xSAXEventKeeper
= new SAXEventKeeperImpl();
197 bSuccess
&= m_xSAXEventKeeper
.is();
201 * SAXEventKeeper created successfully.
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 ************************************************
221 * chainOn -- tries to connect the SAXEventKeeper with the SAX chain.
224 * bJustChainingOn = chainOn();
227 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
228 * creates xml security components, and chains the SAXEventKeeper into
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.
235 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
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 ******************************************************************************/
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
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
);
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;
309 void XSecController::chainOff()
310 /****** XSecController/chainOff ***********************************************
313 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
314 ******************************************************************************/
316 if (m_bIsSAXEventKeeperSticky
)
319 if (!m_bIsSAXEventKeeperConnected
)
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
);
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 ************************************
349 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
350 * according to the current situation.
353 * checkChainingStatus( );
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
)
372 void XSecController::initializeSAXChain()
373 /****** XSecController/initializeSAXChain *************************************
376 * initializeSAXChain -- initializes the SAX chain according to the
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;
392 css::uno::Reference
< css::io::XInputStream
>
393 XSecController::getObjectInputStream( const OUString
& objectURL
)
394 /****** XSecController/getObjectInputStream ************************************
397 * getObjectInputStream -- get a XInputStream interface from a SotStorage
400 * xInputStream = getObjectInputStream( objectURL );
403 * objectURL - the object uri
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
;
422 sal_Int32
XSecController::getNewSecurityId( )
424 sal_Int32 nId
= m_nNextSecurityId
;
429 void XSecController::startMission(const rtl::Reference
<UriBindingHelper
>& xUriBinding
, const css::uno::Reference
< css::xml::crypto::XXMLSecurityContext
>& xSecurityContext
)
430 /****** XSecController/startMission *******************************************
433 * startMission -- starts a new security mission.
436 * get ready for a new mission.
439 * xUriBinding - the Uri binding that provide maps between uris and
441 * xSecurityContext - the security context component which can provide
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 ***********************************
459 * setSAXChainConnector -- configures the components which will
460 * collaborate with the SAXEventKeeper on the SAX chain.
463 * setSAXChainConnector(xInitialization);
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 *********************************
479 * clearSAXChainConnector -- resets the collaborating components.
480 ******************************************************************************/
484 m_xPreviousNodeOnSAXChain
= nullptr;
487 void XSecController::endMission()
488 /****** XSecController/endMission *********************************************
491 * endMission -- forces to end all missions
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 );
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 ****************************************
572 * exportSignature -- export a signature structure to an XDocumentHandler
575 * exportSignature( xDocumentHandler, signatureInfo);
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(
593 if (!signatureInfo
.ouSignatureId
.isEmpty())
595 pAttributeList
->AddAttribute(
597 signatureInfo
.ouSignatureId
);
600 xDocumentHandler
->startElement( "Signature", css::uno::Reference
< css::xml::sax::XAttributeList
> (pAttributeList
));
602 /* Write SignedInfo element */
603 xDocumentHandler
->startElement(
605 css::uno::Reference
< css::xml::sax::XAttributeList
> (new SvXMLAttributeList()));
607 /* Write CanonicalizationMethod element */
608 pAttributeList
= new SvXMLAttributeList();
609 pAttributeList
->AddAttribute(
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(
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 */
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
)
643 pAttributeList
->AddAttribute(
649 * same-document reference
652 pAttributeList
->AddAttribute(
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",
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(
675 css::uno::Reference
< css::xml::sax::XAttributeList
> (new SvXMLAttributeList()));
677 pAttributeList
= new SvXMLAttributeList();
678 pAttributeList
->AddAttribute(
681 xDocumentHandler
->startElement(
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(
693 getDigestURI(refInfor
.nDigestID
));
694 xDocumentHandler
->startElement(
696 css::uno::Reference
< css::xml::sax::XAttributeList
> (pAttributeList
) );
697 xDocumentHandler
->endElement( "DigestMethod" );
699 /* Write DigestValue element */
700 xDocumentHandler
->startElement(
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(
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(
721 css::uno::Reference
< css::xml::sax::XAttributeList
> (new SvXMLAttributeList()));
724 if (!signatureInfo
.ouGpgCertificate
.isEmpty())
726 pAttributeList
= new SvXMLAttributeList();
727 pAttributeList
->AddAttribute("xmlns:loext", NS_LOEXT
);
728 /* Write PGPData element */
729 xDocumentHandler
->startElement(
731 css::uno::Reference
< css::xml::sax::XAttributeList
> (pAttributeList
));
733 /* Write keyid element */
734 xDocumentHandler
->startElement(
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(
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(
753 css::uno::Reference
< css::xml::sax::XAttributeList
>(new SvXMLAttributeList()));
754 xDocumentHandler
->characters( signatureInfo
.ouGpgOwner
);
755 xDocumentHandler
->endElement( "loext:PGPOwner" );
757 xDocumentHandler
->endElement( "PGPData" );
761 assert(signatureInfo
.GetSigningCertificate());
762 for (auto const& rData
: signatureInfo
.X509Datas
)
764 /* Write X509Data element */
765 xDocumentHandler
->startElement(
767 css::uno::Reference
< css::xml::sax::XAttributeList
> (new SvXMLAttributeList()));
769 for (auto const& it
: rData
)
771 /* Write X509IssuerSerial element */
772 xDocumentHandler
->startElement(
774 css::uno::Reference
< css::xml::sax::XAttributeList
> (new SvXMLAttributeList()));
776 /* Write X509IssuerName element */
777 xDocumentHandler
->startElement(
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(
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(
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" );
811 /* Write Object element */
812 xDocumentHandler
->startElement(
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(
825 signatureInfo
.ouDateTimePropertyId
);
826 pAttributeList
->AddAttribute(
828 "#" + signatureInfo
.ouSignatureId
);
829 xDocumentHandler
->startElement(
831 css::uno::Reference
< css::xml::sax::XAttributeList
> (pAttributeList
));
833 /* Write timestamp element */
835 pAttributeList
= new SvXMLAttributeList();
836 pAttributeList
->AddAttribute(
840 xDocumentHandler
->startElement(
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
;
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(
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(
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!" );
939 aInf
= m_vInternalSignatureInformations
[nIndex
].signatureInfor
;
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
);
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: */