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