Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / xmlsecurity / source / helper / xsecverify.cxx
blob1f7fa9ac8ca8d99f22cd1f33f18578c70f3c34e5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_gpgme.h>
22 #include <xsecctl.hxx>
23 #include "xsecparser.hxx"
24 #include "ooxmlsecparser.hxx"
25 #include <framework/signatureverifierimpl.hxx>
26 #include <framework/saxeventkeeperimpl.hxx>
27 #include <gpg/xmlsignature_gpgimpl.hxx>
28 #include <gpg/SEInitializer.hxx>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
32 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
33 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
34 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
35 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
36 #include <com/sun/star/graphic/GraphicProvider.hpp>
37 #include <com/sun/star/embed/StorageFormats.hpp>
38 #include <sal/log.hxx>
39 #include <unotools/datetime.hxx>
40 #include <comphelper/base64.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <comphelper/seqstream.hxx>
44 namespace com::sun::star::graphic { class XGraphic; }
46 using namespace css;
47 using namespace css::uno;
48 using namespace css::beans;
49 namespace cssu = com::sun::star::uno;
50 namespace cssl = com::sun::star::lang;
51 namespace cssxc = com::sun::star::xml::crypto;
52 namespace cssxs = com::sun::star::xml::sax;
54 /* protected: for signature verify */
55 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
56 sal_Int32 nSecurityId)
58 if ( m_eStatusOfSecurityComponents != InitializationState::INITIALIZED )
60 return nullptr;
63 sal_Int32 nIdOfSignatureElementCollector;
64 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
66 nIdOfSignatureElementCollector =
67 m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, false);
69 m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
72 * create a SignatureVerifier
74 xReferenceResolvedListener = new SignatureVerifierImpl;
76 cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
78 cssu::Sequence<cssu::Any> args(5);
79 args[0] <<= OUString::number(nSecurityId);
80 args[1] <<= uno::Reference<xml::crypto::sax::XSecuritySAXEventKeeper>(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), uno::UNO_QUERY);
81 args[2] <<= OUString::number(nIdOfSignatureElementCollector);
82 args[3] <<= m_xSecurityContext;
83 args[4] <<= m_xXMLSignature;
84 xInitialization->initialize(args);
86 cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster >
87 signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
89 signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this );
91 m_xSAXEventKeeper->addReferenceResolvedListener(
92 nIdOfSignatureElementCollector,
93 xReferenceResolvedListener);
95 cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
96 keyCollector->setKeyId(0);
98 return xReferenceResolvedListener;
101 void XSecController::addSignature()
103 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
104 sal_Int32 nSignatureId = 0;
107 if (m_bVerifyCurrentSignature)
109 chainOn();
110 xReferenceResolvedListener = prepareSignatureToRead( m_nReservedSignatureId );
111 m_bVerifyCurrentSignature = false;
112 nSignatureId = m_nReservedSignatureId;
115 InternalSignatureInformation isi( nSignatureId, xReferenceResolvedListener );
116 m_vInternalSignatureInformations.push_back( isi );
119 void XSecController::setSignatureMethod(svl::crypto::SignatureMethodAlgorithm eAlgorithmID)
121 if (m_vInternalSignatureInformations.empty())
122 return;
124 m_vInternalSignatureInformations.back().signatureInfor.eAlgorithmID = eAlgorithmID;
127 void XSecController::switchGpgSignature()
129 #if HAVE_FEATURE_GPGME
130 // swap signature verifier for the Gpg one
131 m_xXMLSignature.set(new XMLSignature_GpgImpl());
132 if (!m_vInternalSignatureInformations.empty())
134 SignatureVerifierImpl* pImpl=
135 dynamic_cast<SignatureVerifierImpl*>(
136 m_vInternalSignatureInformations.back().xReferenceResolvedListener.get());
137 if (pImpl)
139 css::uno::Reference<css::xml::crypto::XSEInitializer> xGpgSEInitializer(
140 new SEInitializerGpg());
141 pImpl->updateSignature(new XMLSignature_GpgImpl(),
142 xGpgSEInitializer->createSecurityContext(OUString()));
145 #else
146 (void) this;
147 #endif
150 void XSecController::addReference( const OUString& ouUri, sal_Int32 nDigestID, const OUString& ouType )
152 if (m_vInternalSignatureInformations.empty())
154 SAL_INFO("xmlsecurity.helper","XSecController::addReference: no signature");
155 return;
157 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
158 isi.addReference(SignatureReferenceType::SAMEDOCUMENT, nDigestID, ouUri, -1, ouType );
161 void XSecController::addStreamReference(
162 const OUString& ouUri,
163 bool isBinary,
164 sal_Int32 nDigestID )
166 SignatureReferenceType type = (isBinary?SignatureReferenceType::BINARYSTREAM:SignatureReferenceType::XMLSTREAM);
168 if (m_vInternalSignatureInformations.empty())
170 SAL_INFO("xmlsecurity.helper","XSecController::addStreamReference: no signature");
171 return;
173 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
175 if ( isi.xReferenceResolvedListener.is() )
178 * get the input stream
180 cssu::Reference< css::io::XInputStream > xObjectInputStream
181 = getObjectInputStream( ouUri );
183 if ( xObjectInputStream.is() )
185 cssu::Reference<cssxc::XUriBinding> xUriBinding
186 (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
187 xUriBinding->setUriBinding(ouUri, xObjectInputStream);
191 isi.addReference(type, nDigestID, ouUri, -1, OUString());
194 void XSecController::setReferenceCount() const
196 if (m_vInternalSignatureInformations.empty())
198 SAL_INFO("xmlsecurity.helper","XSecController::setReferenceCount: no signature");
199 return;
201 const InternalSignatureInformation &isi =
202 m_vInternalSignatureInformations.back();
204 if ( isi.xReferenceResolvedListener.is() )
206 const SignatureReferenceInformations &refInfors = isi.signatureInfor.vSignatureReferenceInfors;
208 int refNum = refInfors.size();
209 sal_Int32 referenceCount = 0;
211 for(int i=0 ; i<refNum; ++i)
213 if (refInfors[i].nType == SignatureReferenceType::SAMEDOCUMENT )
215 * same-document reference
218 referenceCount++;
222 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
223 (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
224 xReferenceCollector->setReferenceCount( referenceCount );
228 void XSecController::setX509IssuerName( OUString const & ouX509IssuerName )
230 if (m_vInternalSignatureInformations.empty())
232 SAL_INFO("xmlsecurity.helper","XSecController::setX509IssuerName: no signature");
233 return;
235 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
236 isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
239 void XSecController::setX509SerialNumber( OUString const & ouX509SerialNumber )
241 if (m_vInternalSignatureInformations.empty())
243 SAL_INFO("xmlsecurity.helper","XSecController::setX509SerialNumber: no signature");
244 return;
246 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
247 isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
250 void XSecController::setX509Certificate( OUString const & ouX509Certificate )
252 if (m_vInternalSignatureInformations.empty())
254 SAL_INFO("xmlsecurity.helper","XSecController::setX509Certificate: no signature");
255 return;
257 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
258 isi.signatureInfor.ouX509Certificate = ouX509Certificate;
261 void XSecController::setSignatureValue( OUString const & ouSignatureValue )
263 if (m_vInternalSignatureInformations.empty())
265 SAL_INFO("xmlsecurity.helper","XSecController::setSignatureValue: no signature");
266 return;
268 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
269 isi.signatureInfor.ouSignatureValue = ouSignatureValue;
272 void XSecController::setDigestValue( sal_Int32 nDigestID, OUString const & ouDigestValue )
274 if (m_vInternalSignatureInformations.empty())
276 SAL_INFO("xmlsecurity.helper","XSecController::setDigestValue: no signature");
277 return;
279 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
280 if (isi.signatureInfor.vSignatureReferenceInfors.empty())
282 SAL_INFO("xmlsecurity.helper","XSecController::setDigestValue: no signature reference");
283 return;
285 SignatureReferenceInformation &reference =
286 isi.signatureInfor.vSignatureReferenceInfors.back();
287 reference.nDigestID = nDigestID;
288 reference.ouDigestValue = ouDigestValue;
291 void XSecController::setGpgKeyID( OUString const & ouKeyID )
293 if (m_vInternalSignatureInformations.empty())
295 SAL_INFO("xmlsecurity.helper","XSecController::setGpgKeyID: no signature");
296 return;
298 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
299 isi.signatureInfor.ouGpgKeyID = ouKeyID;
302 void XSecController::setGpgCertificate( OUString const & ouGpgCert )
304 if (m_vInternalSignatureInformations.empty())
306 SAL_INFO("xmlsecurity.helper","XSecController::setGpgCertificate: no signature");
307 return;
309 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
310 isi.signatureInfor.ouGpgCertificate = ouGpgCert;
313 void XSecController::setGpgOwner( OUString const & ouGpgOwner )
315 if (m_vInternalSignatureInformations.empty())
317 SAL_INFO("xmlsecurity.helper","XSecController::setGpgOwner: no signature");
318 return;
320 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
321 isi.signatureInfor.ouGpgOwner = ouGpgOwner;
324 void XSecController::setDate( OUString const & ouDate )
326 if (m_vInternalSignatureInformations.empty())
328 SAL_INFO("xmlsecurity.helper","XSecController::setDate: no signature");
329 return;
331 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
332 (void)utl::ISO8601parseDateTime( ouDate, isi.signatureInfor.stDateTime);
333 isi.signatureInfor.ouDateTime = ouDate;
336 void XSecController::setDescription(const OUString& rDescription)
338 if (m_vInternalSignatureInformations.empty())
339 return;
341 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
342 rInformation.signatureInfor.ouDescription = rDescription;
345 void XSecController::setSignatureBytes(const uno::Sequence<sal_Int8>& rBytes)
347 if (m_vInternalSignatureInformations.empty())
348 return;
350 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
351 rInformation.signatureInfor.aSignatureBytes = rBytes;
354 void XSecController::setCertDigest(const OUString& rCertDigest)
356 if (m_vInternalSignatureInformations.empty())
357 return;
359 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
360 rInformation.signatureInfor.ouCertDigest = rCertDigest;
363 namespace {
364 Reference<css::graphic::XGraphic> lcl_getGraphicFromString(const OUString& rImage)
366 Sequence<sal_Int8> seq;
367 comphelper::Base64::decode(seq, rImage);
369 Reference< graphic::XGraphic > xGraphic;
370 if( !seq.hasElements() )
371 return Reference<css::graphic::XGraphic>();
373 Reference< graphic::XGraphicProvider > xGraphicProvider(
374 graphic::GraphicProvider::create(comphelper::getProcessComponentContext()) );
375 Reference< io::XInputStream > xInputStream( new ::comphelper::SequenceInputStream( seq ) );
377 Sequence< PropertyValue > aArgs( 1 );
378 aArgs[ 0 ].Name = "InputStream";
379 aArgs[ 0 ].Value <<= xInputStream;
380 xGraphic = xGraphicProvider->queryGraphic(aArgs);
382 return xGraphic;
386 void XSecController::setValidSignatureImage(const OUString& rValidSigImg)
388 if (m_vInternalSignatureInformations.empty() || rValidSigImg.isEmpty())
389 return;
391 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
392 rInformation.signatureInfor.aValidSignatureImage = lcl_getGraphicFromString(rValidSigImg);
395 void XSecController::setInvalidSignatureImage(const OUString& rInvalidSigImg)
397 if (m_vInternalSignatureInformations.empty() || rInvalidSigImg.isEmpty())
398 return;
400 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
401 rInformation.signatureInfor.aInvalidSignatureImage = lcl_getGraphicFromString(rInvalidSigImg);
404 void XSecController::setSignatureLineId(const OUString& rSignatureLineId)
406 if (m_vInternalSignatureInformations.empty())
407 return;
409 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
410 rInformation.signatureInfor.ouSignatureLineId = rSignatureLineId;
413 void XSecController::addEncapsulatedX509Certificate(const OUString& rEncapsulatedX509Certificate)
415 if (m_vInternalSignatureInformations.empty())
416 return;
418 if (rEncapsulatedX509Certificate.isEmpty())
419 return;
421 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
422 rInformation.signatureInfor.maEncapsulatedX509Certificates.insert(rEncapsulatedX509Certificate);
425 void XSecController::setId( OUString const & ouId )
427 if (m_vInternalSignatureInformations.empty())
429 SAL_INFO("xmlsecurity.helper","XSecController::setId: no signature");
430 return;
432 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
433 isi.signatureInfor.ouSignatureId = ouId;
436 void XSecController::setPropertyId( OUString const & ouPropertyId )
438 if (m_vInternalSignatureInformations.empty())
440 SAL_INFO("xmlsecurity.helper","XSecController::setPropertyId: no signature");
441 return;
443 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
445 if (isi.signatureInfor.ouPropertyId.isEmpty())
447 // <SignatureProperty> ID attribute is for the date.
448 isi.signatureInfor.ouPropertyId = ouPropertyId;
450 else
452 // <SignatureProperty> ID attribute is for the description.
453 isi.signatureInfor.ouDescriptionPropertyId = ouPropertyId;
457 /* public: for signature verify */
458 void XSecController::collectToVerify( const OUString& referenceId )
460 /* SAL_WARN_IF( !m_xSAXEventKeeper.is(), "xmlsecurity", "the SAXEventKeeper is NULL" ); */
462 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
464 * if all security components are ready, verify the signature.
467 bool bJustChainingOn = false;
468 cssu::Reference< cssxs::XDocumentHandler > xHandler;
470 int i,j;
471 int sigNum = m_vInternalSignatureInformations.size();
473 for (i=0; i<sigNum; ++i)
475 InternalSignatureInformation& isi = m_vInternalSignatureInformations[i];
476 SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors;
477 int refNum = vReferenceInfors.size();
479 for (j=0; j<refNum; ++j)
481 SignatureReferenceInformation &refInfor = vReferenceInfors[j];
483 if (refInfor.ouURI == referenceId)
485 if (chainOn())
487 bJustChainingOn = true;
488 xHandler = m_xSAXEventKeeper->setNextHandler(nullptr);
491 sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
492 cssxc::sax::ElementMarkPriority_BEFOREMODIFY, false );
494 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
495 ( isi.xReferenceResolvedListener, cssu::UNO_QUERY );
497 m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
498 m_xSAXEventKeeper->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
499 xReferenceCollector->setReferenceId( nKeeperId );
501 isi.vKeeperIds[j] = nKeeperId;
502 break;
507 if ( bJustChainingOn )
509 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), cssu::UNO_QUERY);
510 m_xSAXEventKeeper->setNextHandler(xHandler);
515 void XSecController::addSignature( sal_Int32 nSignatureId )
517 SAL_WARN_IF( !m_xSecParser.is(), "xmlsecurity.helper", "No XSecParser initialized" );
519 m_nReservedSignatureId = nSignatureId;
520 m_bVerifyCurrentSignature = true;
523 cssu::Reference< cssxs::XDocumentHandler > const & XSecController::createSignatureReader(XMLSignatureHelper& rXMLSignatureHelper, sal_Int32 nType)
525 if (nType == embed::StorageFormats::OFOPXML)
526 m_xSecParser = new OOXMLSecParser(rXMLSignatureHelper, this);
527 else
528 m_xSecParser = new XSecParser(rXMLSignatureHelper, this);
529 cssu::Reference< cssl::XInitialization > xInitialization(m_xSecParser, uno::UNO_QUERY);
531 setSAXChainConnector(xInitialization);
533 return m_xSecParser;
536 void XSecController::releaseSignatureReader()
538 clearSAXChainConnector( );
539 m_xSecParser.clear();
542 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */