LibreOffice Module xmlsecurity (master) 1
xsecctl.cxx
Go to the documentation of this file.
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.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_gpgme.h>
21
22#include <utility>
23#include <xsecctl.hxx>
27#if HAVE_FEATURE_GPGME
29#endif
30
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>
36
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>
44
45using namespace com::sun::star;
46
47namespace
48{
49OUString getDigestURI(sal_Int32 nID)
50{
51 switch( nID )
52 {
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;
59 default:
60 return ALGO_XMLDSIGSHA1;
61 }
62}
63OUString getSignatureURI(svl::crypto::SignatureMethodAlgorithm eAlgorithm, sal_Int32 nDigestID)
64{
65 OUString aRet;
66
68 {
69 switch (nDigestID)
70 {
71 case css::xml::crypto::DigestID::SHA1:
72 aRet = ALGO_ECDSASHA1;
73 break;
74 case css::xml::crypto::DigestID::SHA256:
75 aRet = ALGO_ECDSASHA256;
76 break;
77 case css::xml::crypto::DigestID::SHA512:
78 aRet = ALGO_ECDSASHA512;
79 break;
80 default:
81 aRet = ALGO_ECDSASHA1;
82 break;
83 }
84 }
85 if (!aRet.isEmpty())
86 return aRet;
87
88 switch (nDigestID)
89 {
90 case css::xml::crypto::DigestID::SHA1:
91 return ALGO_RSASHA1;
92 case css::xml::crypto::DigestID::SHA256:
93 return ALGO_RSASHA256;
94 case css::xml::crypto::DigestID::SHA512:
95 return ALGO_RSASHA512;
96 default:
97 return ALGO_RSASHA1;
98 }
99}
100}
101
102XSecController::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)
113{
114}
115
117{
118}
119
120
121/*
122 * private methods
123 */
124int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const
125/****** XSecController/findSignatureInfor *************************************
126 *
127 * NAME
128 * findSignatureInfor -- find SignatureInformation struct for a particular
129 * signature
130 *
131 * SYNOPSIS
132 * index = findSignatureInfor( nSecurityId );
133 *
134 * INPUTS
135 * nSecurityId - the signature's id
136 *
137 * RESULT
138 * index - the index of the signature, or -1 when no such signature
139 * existing
140 ******************************************************************************/
141{
142 int i;
143 int size = m_vInternalSignatureInformations.size();
144
145 for (i=0; i<size; ++i)
146 {
147 if (m_vInternalSignatureInformations[i].signatureInfor.nSecurityId == nSecurityId)
148 {
149 return i;
150 }
151 }
152
153 return -1;
154}
155
157/****** XSecController/createXSecComponent ************************************
158 *
159 * NAME
160 * bResult = createXSecComponent -- creates xml security components
161 *
162 * FUNCTION
163 * Creates xml security components, including:
164 * 1. an xml signature bridge component
165 * 2. an XMLDocumentWrapper component
166 * 3. a SAXEventKeeper component
167 ******************************************************************************/
168{
169 /*
170 * marks all security components are not available.
171 */
173 m_xXMLSignature = nullptr;
174 m_xXMLDocumentWrapper = nullptr;
175 m_xSAXEventKeeper = nullptr;
176
177 css::uno::Reference< css::lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
178
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")
183 else // xmlsec or mscrypt
184#endif
185 m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), css::uno::UNO_QUERY);
186
187 bool bSuccess = m_xXMLSignature.is();
188 if ( bSuccess )
189 /*
190 * XMLSignature created successfully.
191 */
193
194 bSuccess &= m_xXMLDocumentWrapper.is();
195 if ( bSuccess )
197
198 bSuccess &= m_xSAXEventKeeper.is();
199
200 if (!bSuccess)
201 /*
202 * SAXEventKeeper created successfully.
203 */
204 return;
205
206 css::uno::Sequence <css::uno::Any> arg{ css::uno::Any(
207 uno::Reference<xml::wrapper::XXMLDocumentWrapper>(m_xXMLDocumentWrapper)) };
208 m_xSAXEventKeeper->initialize(arg);
209
210 css::uno::Reference< css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener >
211 xStatusChangeListener = this;
212
213 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
214
216}
217
219/****** XSecController/chainOn ************************************************
220 *
221 * NAME
222 * chainOn -- tries to connect the SAXEventKeeper with the SAX chain.
223 *
224 * SYNOPSIS
225 * bJustChainingOn = chainOn();
226 *
227 * FUNCTION
228 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
229 * creates xml security components, and chains the SAXEventKeeper into
230 * the SAX chain.
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.
234 *
235 * RESULT
236 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
237 * SAX chain.
238 *
239 * NOTES
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 ******************************************************************************/
250{
251 bool rc = false;
252
254 {
256 {
258 }
259
261 /*
262 * if all security components are ready, chains on the SAXEventKeeper
263 */
264 {
265 /*
266 * disconnect the SAXEventKeeper with its current output handler,
267 * to make sure no SAX event is forwarded during the connecting
268 * phase.
269 */
270 m_xSAXEventKeeper->setNextHandler( nullptr );
271
272 css::uno::Reference< css::xml::sax::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper);
273
274 /*
275 * connects the previous document handler on the SAX chain
276 */
277 if ( m_xPreviousNodeOnSAXChain.is() )
278 {
280 {
281 css::uno::Reference< css::lang::XInitialization > xInitialization
282 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
283
284 xInitialization->initialize({ css::uno::Any(xSEKHandler) });
285 }
286 else
287 {
288 css::uno::Reference< css::xml::sax::XParser > xParser
289 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
290 xParser->setDocumentHandler( xSEKHandler );
291 }
292 }
293
294 /*
295 * connects the next document handler on the SAX chain
296 */
297 m_xSAXEventKeeper->setNextHandler(uno::Reference<xml::sax::XDocumentHandler>());
298
300
301 rc = true;
302 }
303 }
304
305 return rc;
306}
307
309/****** XSecController/chainOff ***********************************************
310 *
311 * NAME
312 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
313 ******************************************************************************/
314{
316 return;
317
319 return;
320
321 m_xSAXEventKeeper->setNextHandler( nullptr );
322
323 if ( m_xPreviousNodeOnSAXChain.is() )
324 {
326 {
327 css::uno::Reference< css::lang::XInitialization > xInitialization
328 (m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
329
330 css::uno::Sequence<css::uno::Any> aArgs{ css::uno::Any(
331 uno::Reference<xml::sax::XDocumentHandler>()) };
332 xInitialization->initialize(aArgs);
333 }
334 else
335 {
336 css::uno::Reference< css::xml::sax::XParser > xParser(m_xPreviousNodeOnSAXChain, css::uno::UNO_QUERY);
337 xParser->setDocumentHandler(uno::Reference<xml::sax::XDocumentHandler>());
338 }
339 }
340
342}
343
345/****** XSecController/checkChainingStatus ************************************
346 *
347 * NAME
348 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
349 * according to the current situation.
350 *
351 * SYNOPSIS
352 * checkChainingStatus( );
353 *
354 * FUNCTION
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 ******************************************************************************/
360{
362 {
363 chainOn();
364 }
365 else
366 {
367 chainOff();
368 }
369}
370
372/****** XSecController/initializeSAXChain *************************************
373 *
374 * NAME
375 * initializeSAXChain -- initializes the SAX chain according to the
376 * current setting.
377 *
378 * FUNCTION
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 ******************************************************************************/
383{
386 m_bIsBlocking = false;
387
388 chainOff();
389}
390
391css::uno::Reference< css::io::XInputStream >
392 XSecController::getObjectInputStream( const OUString& objectURL )
393/****** XSecController/getObjectInputStream ************************************
394 *
395 * NAME
396 * getObjectInputStream -- get a XInputStream interface from a SotStorage
397 *
398 * SYNOPSIS
399 * xInputStream = getObjectInputStream( objectURL );
400 *
401 * INPUTS
402 * objectURL - the object uri
403 *
404 * RESULT
405 * xInputStream - the XInputStream interface
406 ******************************************************************************/
407{
408 css::uno::Reference< css::io::XInputStream > xObjectInputStream;
409
410 SAL_WARN_IF( !m_xUriBinding.is(), "xmlsecurity.helper", "Need XUriBinding!" );
411
412 xObjectInputStream = m_xUriBinding->getUriBinding(objectURL);
413
414 return xObjectInputStream;
415}
416
417/*
418 * public methods
419 */
420
422{
423 sal_Int32 nId = m_nNextSecurityId;
425 return nId;
426}
427
428void XSecController::startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext >& xSecurityContext )
429/****** XSecController/startMission *******************************************
430 *
431 * NAME
432 * startMission -- starts a new security mission.
433 *
434 * FUNCTION
435 * get ready for a new mission.
436 *
437 * INPUTS
438 * xUriBinding - the Uri binding that provide maps between uris and
439 * XInputStreams
440 * xSecurityContext - the security context component which can provide
441 * cryptoken
442 ******************************************************************************/
443{
444 m_xUriBinding = xUriBinding;
445
447 m_xSecurityContext = xSecurityContext;
448
450
452}
453
454void XSecController::setSAXChainConnector(const css::uno::Reference< css::lang::XInitialization >& xInitialization)
455/****** XSecController/setSAXChainConnector ***********************************
456 *
457 * NAME
458 * setSAXChainConnector -- configures the components which will
459 * collaborate with the SAXEventKeeper on the SAX chain.
460 *
461 * SYNOPSIS
462 * setSAXChainConnector(xInitialization);
463 *
464 * INPUTS
465 * xInitialization - the previous node on the SAX chain
466 ******************************************************************************/
467{
469 m_xPreviousNodeOnSAXChain = xInitialization;
470
472}
473
475/****** XSecController/clearSAXChainConnector *********************************
476 *
477 * NAME
478 * clearSAXChainConnector -- resets the collaborating components.
479 ******************************************************************************/
480{
481 chainOff();
482
484}
485
487/****** XSecController/endMission *********************************************
488 *
489 * NAME
490 * endMission -- forces to end all missions
491 *
492 * FUNCTION
493 * Deletes all signature information and forces all missions to an end.
494 ******************************************************************************/
495{
496 sal_Int32 size = m_vInternalSignatureInformations.size();
497
498 for (int i=0; i<size; ++i)
499 {
501 /*
502 * ResolvedListener only exist when the security components are created.
503 */
504 {
505 css::uno::Reference< css::xml::crypto::sax::XMissionTaker > xMissionTaker
506 ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, css::uno::UNO_QUERY );
507
508 /*
509 * asks the SignatureCreator/SignatureVerifier to release
510 * all resources it uses.
511 */
512 xMissionTaker->endMission();
513 }
514 }
515
516 m_xUriBinding = nullptr;
517 m_xSecurityContext = nullptr;
518
519 /*
520 * free the status change listener reference to this object
521 */
522 if (m_xSAXEventKeeper.is())
523 m_xSAXEventKeeper->addSAXEventKeeperStatusChangeListener( nullptr );
524}
525
526namespace
527{
528void writeUnsignedProperties(
529 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
530 const SignatureInformation& signatureInfo)
531{
532 {
534 pAttributeList->AddAttribute("Id", "idUnsignedProperties_" + signatureInfo.ouSignatureId);
535 xDocumentHandler->startElement("xd:UnsignedProperties", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
536 }
537
538 {
539 xDocumentHandler->startElement("xd:UnsignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
540
541 {
542 xDocumentHandler->startElement("xd:CertificateValues", uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
543
544 {
545 for (const auto& i: signatureInfo.maEncapsulatedX509Certificates)
546 {
547 xDocumentHandler->startElement("xd:EncapsulatedX509Certificate", uno::Reference<xml::sax::XAttributeList>(new comphelper::AttributeList()));
548 xDocumentHandler->characters(i);
549 xDocumentHandler->endElement("xd:EncapsulatedX509Certificate");
550 }
551 }
552
553 xDocumentHandler->endElement("xd:CertificateValues");
554 }
555
556 xDocumentHandler->endElement("xd:UnsignedSignatureProperties");
557 }
558
559 xDocumentHandler->endElement("xd:UnsignedProperties");
560}
561
562}
563
565 const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler,
566 const SignatureInformation& signatureInfo,
567 bool bXAdESCompliantIfODF )
568/****** XSecController/exportSignature ****************************************
569 *
570 * NAME
571 * exportSignature -- export a signature structure to an XDocumentHandler
572 *
573 * SYNOPSIS
574 * exportSignature( xDocumentHandler, signatureInfo);
575 *
576 * INPUTS
577 * xDocumentHandler - the document handler to receive the signature
578 * signatureInfo - signature to be exported
579 ******************************************************************************/
580{
581 const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors;
583
584 /*
585 * Write Signature element
586 */
587 pAttributeList = new comphelper::AttributeList();
588 pAttributeList->AddAttribute(
589 "xmlns",
590 NS_XMLDSIG);
591
592 if (!signatureInfo.ouSignatureId.isEmpty())
593 {
594 pAttributeList->AddAttribute(
595 "Id",
596 signatureInfo.ouSignatureId);
597 }
598
599 xDocumentHandler->startElement( "Signature", pAttributeList);
600 {
601 /* Write SignedInfo element */
602 xDocumentHandler->startElement(
603 "SignedInfo",
604 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
605 {
606 /* Write CanonicalizationMethod element */
607 pAttributeList = new comphelper::AttributeList();
608 pAttributeList->AddAttribute(
609 "Algorithm",
610 ALGO_C14N);
611 xDocumentHandler->startElement( "CanonicalizationMethod", pAttributeList );
612 xDocumentHandler->endElement( "CanonicalizationMethod" );
613
614 /* Write SignatureMethod element */
615 pAttributeList = new comphelper::AttributeList();
616
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
619
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(
623 "Algorithm",
624 getSignatureURI(signatureInfo.eAlgorithmID, vReferenceInfors[0].nDigestID));
625 xDocumentHandler->startElement( "SignatureMethod", pAttributeList );
626 xDocumentHandler->endElement( "SignatureMethod" );
627
628 /* Write Reference element */
629 int j;
630 int refNum = vReferenceInfors.size();
631
632 for(j=0; j<refNum; ++j)
633 {
634 const SignatureReferenceInformation& refInfor = vReferenceInfors[j];
635
636 pAttributeList = new comphelper::AttributeList();
637 if ( refInfor.nType != SignatureReferenceType::SAMEDOCUMENT )
638 /*
639 * stream reference
640 */
641 {
642 pAttributeList->AddAttribute(
643 "URI",
644 refInfor.ouURI);
645 }
646 else
647 /*
648 * same-document reference
649 */
650 {
651 if (refInfor.ouURI.startsWith("idSignedProperties"))
652 {
653 pAttributeList->AddAttribute("URI", "#idSignedProperties_" + signatureInfo.ouSignatureId);
654 if (bXAdESCompliantIfODF && !refInfor.ouType.isEmpty())
655 {
656 // The reference which points to the SignedProperties
657 // shall have this specific type.
658 pAttributeList->AddAttribute("Type", refInfor.ouType);
659 }
660 }
661 else
662 {
663 pAttributeList->AddAttribute(
664 "URI",
665 "#" + refInfor.ouURI);
666 }
667 }
668
669 xDocumentHandler->startElement( "Reference", pAttributeList );
670 {
671 /* Write Transforms element */
672 if (refInfor.nType == SignatureReferenceType::XMLSTREAM)
673 /*
674 * xml stream, so c14n transform is needed
675 */
676 {
677 xDocumentHandler->startElement(
678 "Transforms",
679 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
680 {
681 pAttributeList = new comphelper::AttributeList();
682 pAttributeList->AddAttribute(
683 "Algorithm",
684 ALGO_C14N);
685 xDocumentHandler->startElement(
686 "Transform",
687 pAttributeList );
688 xDocumentHandler->endElement( "Transform" );
689 }
690 xDocumentHandler->endElement( "Transforms" );
691 }
692
693 /* Write DigestMethod element */
694 pAttributeList = new comphelper::AttributeList();
695 pAttributeList->AddAttribute(
696 "Algorithm",
697 getDigestURI(refInfor.nDigestID));
698 xDocumentHandler->startElement(
699 "DigestMethod",
700 pAttributeList );
701 xDocumentHandler->endElement( "DigestMethod" );
702
703 /* Write DigestValue element */
704 xDocumentHandler->startElement(
705 "DigestValue",
706 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
707 xDocumentHandler->characters( refInfor.ouDigestValue );
708 xDocumentHandler->endElement( "DigestValue" );
709 }
710 xDocumentHandler->endElement( "Reference" );
711 }
712 }
713 xDocumentHandler->endElement( "SignedInfo" );
714
715 /* Write SignatureValue element */
716 xDocumentHandler->startElement(
717 "SignatureValue",
718 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
719 xDocumentHandler->characters( signatureInfo.ouSignatureValue );
720 xDocumentHandler->endElement( "SignatureValue" );
721
722 /* Write KeyInfo element */
723 xDocumentHandler->startElement(
724 "KeyInfo",
725 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
726 {
727 // GPG or X509 key?
728 if (!signatureInfo.ouGpgCertificate.isEmpty())
729 {
730 pAttributeList = new comphelper::AttributeList();
731 pAttributeList->AddAttribute("xmlns:loext", NS_LOEXT);
732 /* Write PGPData element */
733 xDocumentHandler->startElement(
734 "PGPData",
735 pAttributeList);
736 {
737 /* Write keyid element */
738 xDocumentHandler->startElement(
739 "PGPKeyID",
740 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
741 xDocumentHandler->characters(signatureInfo.ouGpgKeyID);
742 xDocumentHandler->endElement( "PGPKeyID" );
743
744 /* Write PGPKeyPacket element */
745 if (!signatureInfo.ouGpgCertificate.isEmpty())
746 {
747 xDocumentHandler->startElement(
748 "PGPKeyPacket",
749 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
750 xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
751 xDocumentHandler->endElement( "PGPKeyPacket" );
752 }
753
754 /* Write PGPOwner element */
755 xDocumentHandler->startElement(
756 "loext:PGPOwner",
757 css::uno::Reference< css::xml::sax::XAttributeList >(new comphelper::AttributeList()));
758 xDocumentHandler->characters( signatureInfo.ouGpgOwner );
759 xDocumentHandler->endElement( "loext:PGPOwner" );
760 }
761 xDocumentHandler->endElement( "PGPData" );
762 }
763 else
764 {
765 assert(signatureInfo.GetSigningCertificate());
766 for (auto const& rData : signatureInfo.X509Datas)
767 {
768 /* Write X509Data element */
769 xDocumentHandler->startElement(
770 "X509Data",
771 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
772 {
773 for (auto const& it : rData)
774 {
775 /* Write X509IssuerSerial element */
776 xDocumentHandler->startElement(
777 "X509IssuerSerial",
778 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
779 {
780 /* Write X509IssuerName element */
781 xDocumentHandler->startElement(
782 "X509IssuerName",
783 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
784 xDocumentHandler->characters(it.X509IssuerName);
785 xDocumentHandler->endElement( "X509IssuerName" );
786
787 /* Write X509SerialNumber element */
788 xDocumentHandler->startElement(
789 "X509SerialNumber",
790 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
791 xDocumentHandler->characters(it.X509SerialNumber);
792 xDocumentHandler->endElement( "X509SerialNumber" );
793 }
794 xDocumentHandler->endElement( "X509IssuerSerial" );
795
796 /* Write X509Certificate element */
797 if (!it.X509Certificate.isEmpty())
798 {
799 xDocumentHandler->startElement(
800 "X509Certificate",
801 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
802 xDocumentHandler->characters(it.X509Certificate);
803 xDocumentHandler->endElement( "X509Certificate" );
804 }
805 }
806 }
807 xDocumentHandler->endElement( "X509Data" );
808 }
809 }
810 }
811 xDocumentHandler->endElement( "KeyInfo" );
812
813 OUString sDate;
814
815 /* Write Object element */
816 xDocumentHandler->startElement(
817 "Object",
818 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
819 {
820 /* Write SignatureProperties element */
821 xDocumentHandler->startElement(
822 "SignatureProperties",
823 css::uno::Reference< css::xml::sax::XAttributeList > (new comphelper::AttributeList()));
824 {
825 /* Write SignatureProperty element */
826 pAttributeList = new comphelper::AttributeList();
827 pAttributeList->AddAttribute(
828 "Id",
829 signatureInfo.ouDateTimePropertyId);
830 pAttributeList->AddAttribute(
831 "Target",
832 "#" + signatureInfo.ouSignatureId);
833 xDocumentHandler->startElement(
834 "SignatureProperty",
835 pAttributeList);
836 {
837 /* Write timestamp element */
838
839 pAttributeList = new comphelper::AttributeList();
840 pAttributeList->AddAttribute(
841 "xmlns:dc",
842 NS_DC);
843
844 xDocumentHandler->startElement(
845 "dc:date",
846 pAttributeList);
847
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;
855 else
856 {
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(',', '.');
861 }
862 sDate = buffer.makeStringAndClear();
863 xDocumentHandler->characters( sDate );
864
865 xDocumentHandler->endElement(
866 "dc:date");
867 }
868 xDocumentHandler->endElement( "SignatureProperty" );
869 }
870
871 // Write signature description.
872 if (!signatureInfo.ouDescription.isEmpty())
873 {
874 // SignatureProperty element.
875 pAttributeList = new comphelper::AttributeList();
876 pAttributeList->AddAttribute("Id", signatureInfo.ouDescriptionPropertyId);
877 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
878 xDocumentHandler->startElement("SignatureProperty", pAttributeList);
879
880 {
881 // Description element.
882 pAttributeList = new comphelper::AttributeList();
883 pAttributeList->AddAttribute("xmlns:dc", NS_DC);
884
885 xDocumentHandler->startElement("dc:description", pAttributeList);
886 xDocumentHandler->characters(signatureInfo.ouDescription);
887 xDocumentHandler->endElement("dc:description");
888 }
889
890 xDocumentHandler->endElement("SignatureProperty");
891 }
892
893 xDocumentHandler->endElement( "SignatureProperties" );
894 }
895 xDocumentHandler->endElement( "Object" );
896
897 // In XAdES, write another Object element for the QualifyingProperties
898 if (bXAdESCompliantIfODF)
899 {
900 pAttributeList = new comphelper::AttributeList();
901 pAttributeList->AddAttribute("xmlns:xd", NS_XD);
902 xDocumentHandler->startElement(
903 "Object",
904 pAttributeList);
905 {
906 pAttributeList = new comphelper::AttributeList();
907 pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
908 xDocumentHandler->startElement(
909 "xd:QualifyingProperties",
910 pAttributeList);
911 DocumentSignatureHelper::writeSignedProperties(xDocumentHandler, signatureInfo, sDate, true);
912 writeUnsignedProperties(xDocumentHandler, signatureInfo);
913 xDocumentHandler->endElement( "xd:QualifyingProperties" );
914 }
915 xDocumentHandler->endElement( "Object" );
916 }
917 }
918 xDocumentHandler->endElement( "Signature" );
919}
920
921void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation)
922{
923 OOXMLSecExporter aExporter(mxCtx, xRootStorage, xDocumentHandler, rInformation);
924 aExporter.writeSignature();
925}
926
927void XSecController::UpdateSignatureInformation(sal_Int32 const nSecurityId,
928 std::vector<SignatureInformation::X509Data> && rDatas)
929{
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);
933}
934
936{
937 SignatureInformation aInf( 0 );
938 int nIndex = findSignatureInfor(nSecurityId);
939 SAL_WARN_IF( nIndex == -1, "xmlsecurity.helper", "getSignatureInformation - SecurityId is invalid!" );
940 if ( nIndex != -1)
941 {
942 aInf = m_vInternalSignatureInformations[nIndex].signatureInfor;
943 }
944 return aInf;
945}
946
948{
949 SignatureInformations vInfors;
950 int sigNum = m_vInternalSignatureInformations.size();
951
952 for (int i=0; i<sigNum; ++i)
953 {
955 vInfors.push_back(si);
956 }
957
958 return vInfors;
959}
960
961/*
962 * XSAXEventKeeperStatusChangeListener
963 */
964
966{
967 m_bIsBlocking = isBlocking;
969}
970
972 sal_Bool isInsideCollectedElement )
973{
974 m_bIsCollectingElement = isInsideCollectedElement;
976}
977
978void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/)
979{
980
981}
982
983/*
984 * XSignatureCreationResultListener
985 */
986void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
987{
988 int index = findSignatureInfor(securityId);
989 assert(index != -1 && "Signature Not Found!");
990 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
991 signatureInfor.nStatus = nResult;
992}
993
994/*
995 * XSignatureVerifyResultListener
996 */
997void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
998{
999 int index = findSignatureInfor(securityId);
1000 assert(index != -1 && "Signature Not Found!");
1001 SignatureInformation& signatureInfor = m_vInternalSignatureInformations.at(index).signatureInfor;
1002 signatureInfor.nStatus = nResult;
1003}
1004
1005/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Writes a single OOXML digital signature.
NAME XMLDocumentWrapper_XmlSecImpl – Class to manipulate a libxml2 document.
bool m_bIsSAXEventKeeperSticky
Definition: xsecctl.hxx:199
rtl::Reference< SAXEventKeeperImpl > m_xSAXEventKeeper
Definition: xsecctl.hxx:124
enum XSecController::InitializationState m_eStatusOfSecurityComponents
virtual void SAL_CALL collectionStatusChanged(sal_Bool isInsideCollectedElement) override
Definition: xsecctl.cxx:971
css::uno::Reference< css::uno::XInterface > m_xPreviousNodeOnSAXChain
Definition: xsecctl.hxx:156
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > m_xSecurityContext
Definition: xsecctl.hxx:134
css::uno::Reference< css::xml::crypto::XXMLSignature > m_xXMLSignature
Definition: xsecctl.hxx:129
bool m_bIsCollectingElement
Definition: xsecctl.hxx:175
css::uno::Reference< css::uno::XComponentContext > mxCtx
Definition: xsecctl.hxx:114
std::vector< InternalSignatureInformation > m_vInternalSignatureInformations
Definition: xsecctl.hxx:147
void createXSecComponent()
Definition: xsecctl.cxx:156
void clearSAXChainConnector()
Definition: xsecctl.cxx:474
void endMission()
Definition: xsecctl.cxx:486
bool m_bIsPreviousNodeInitializable
Definition: xsecctl.hxx:162
virtual void SAL_CALL blockingStatusChanged(sal_Bool isBlocking) override
Definition: xsecctl.cxx:965
void exportOOXMLSignature(const css::uno::Reference< css::embed::XStorage > &xRootStorage, const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler, const SignatureInformation &rInformation)
Exports an OOXML signature, called by WriteOOXMLSignature().
Definition: xsecctl.cxx:921
virtual void SAL_CALL signatureVerified(sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult) override
Definition: xsecctl.cxx:997
virtual void SAL_CALL bufferStatusChanged(sal_Bool isBufferEmpty) override
Definition: xsecctl.cxx:978
SignatureInformation getSignatureInformation(sal_Int32 nSecurityId) const
Definition: xsecctl.cxx:935
bool chainOn()
Definition: xsecctl.cxx:218
bool m_bVerifyCurrentSignature
Definition: xsecctl.hxx:215
void checkChainingStatus()
Definition: xsecctl.cxx:344
virtual void SAL_CALL signatureCreated(sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult) override
Definition: xsecctl.cxx:986
void startMission(const rtl::Reference< UriBindingHelper > &xUriBinding, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext > &xSecurityContext)
Definition: xsecctl.cxx:428
static void exportSignature(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler, const SignatureInformation &signatureInfo, bool bXAdESCompliantIfODF)
Definition: xsecctl.cxx:564
bool m_bIsBlocking
Definition: xsecctl.hxx:182
void setSAXChainConnector(const css::uno::Reference< css::lang::XInitialization > &xInitialization)
Definition: xsecctl.cxx:454
void UpdateSignatureInformation(sal_Int32 nSecurityId, std::vector< SignatureInformation::X509Data > &&rDatas)
only verify can figure out which X509Data is the signing certificate
Definition: xsecctl.cxx:927
void chainOff()
Definition: xsecctl.cxx:308
sal_Int32 getNewSecurityId()
Definition: xsecctl.cxx:421
XSecController(css::uno::Reference< css::uno::XComponentContext > xCtx)
Definition: xsecctl.cxx:102
bool m_bIsSAXEventKeeperConnected
Definition: xsecctl.hxx:168
virtual ~XSecController() override
Definition: xsecctl.cxx:116
rtl::Reference< XMLDocumentWrapper_XmlSecImpl > m_xXMLDocumentWrapper
Definition: xsecctl.hxx:119
rtl::Reference< UriBindingHelper > m_xUriBinding
Definition: xsecctl.hxx:220
css::uno::Reference< css::io::XInputStream > getObjectInputStream(const OUString &objectURL)
Definition: xsecctl.cxx:392
int findSignatureInfor(sal_Int32 nSecurityId) const
Definition: xsecctl.cxx:124
void initializeSAXChain()
Definition: xsecctl.cxx:371
SignatureInformations getSignatureInformations() const
Definition: xsecctl.cxx:947
sal_Int32 m_nNextSecurityId
Definition: xsecctl.hxx:142
sal_Int32 nIndex
Reference< XComponentContext > mxCtx
#define SAL_WARN_IF(condition, area, stream)
void writeSignedProperties(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler, const SignatureInformation &signatureInfo, const OUString &sDate, const bool bWriteSignatureLineData)
size
int i
index
OUString toISO8601(const css::util::DateTime &rDateTime)
sal_Int16 nId
::std::vector< SignatureReferenceInformation > SignatureReferenceInformations
::std::vector< SignatureInformation > SignatureInformations
SignatureReferenceInformations vSignatureReferenceInfors
css::xml::crypto::SecurityOperationStatus nStatus
std::vector< X509Data > X509Datas
OUString ouDateTimePropertyId
svl::crypto::SignatureMethodAlgorithm eAlgorithmID
std::set< OUString > maEncapsulatedX509Certificates
OUString ouDescriptionPropertyId
X509CertInfo const * GetSigningCertificate() const
css::util::DateTime stDateTime
SignatureReferenceType nType
unsigned char sal_Bool
constexpr OUStringLiteral ALGO_XMLDSIGSHA512
Definition: xsecctl.hxx:60
constexpr OUStringLiteral NS_XMLDSIG
Definition: xsecctl.hxx:45
constexpr OUStringLiteral ALGO_RSASHA1
Definition: xsecctl.hxx:52
constexpr OUStringLiteral NS_XD
Definition: xsecctl.hxx:47
constexpr OUStringLiteral ALGO_XMLDSIGSHA256
Definition: xsecctl.hxx:59
constexpr OUStringLiteral ALGO_ECDSASHA512
Definition: xsecctl.hxx:57
constexpr OUStringLiteral NS_LOEXT
Definition: xsecctl.hxx:49
constexpr OUStringLiteral NS_DC
Definition: xsecctl.hxx:46
constexpr OUStringLiteral ALGO_RSASHA256
Definition: xsecctl.hxx:53
constexpr OUStringLiteral ALGO_ECDSASHA1
Definition: xsecctl.hxx:55
constexpr OUStringLiteral ALGO_C14N
Definition: xsecctl.hxx:51
constexpr OUStringLiteral ALGO_XMLDSIGSHA1
Definition: xsecctl.hxx:58
constexpr OUStringLiteral ALGO_ECDSASHA256
Definition: xsecctl.hxx:56
constexpr OUStringLiteral ALGO_RSASHA512
Definition: xsecctl.hxx:54