Bump version to 6.0-36
[LibreOffice.git] / xmlsecurity / source / helper / xsecverify.cxx
blob1cece7fb4b8b1be78d5f306e2d4e4f204f6a6cc9
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/XReferenceResolvedBroadcaster.hpp>
34 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
35 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
36 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
37 #include <com/sun/star/graphic/XGraphic.hpp>
38 #include <com/sun/star/graphic/GraphicProvider.hpp>
39 #include <com/sun/star/xml/sax/SAXParseException.hpp>
40 #include <com/sun/star/embed/StorageFormats.hpp>
41 #include <sal/log.hxx>
42 #include <unotools/datetime.hxx>
43 #include <comphelper/base64.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <comphelper/sequence.hxx>
46 #include <comphelper/seqstream.hxx>
48 using namespace css;
49 using namespace css::uno;
50 using namespace css::beans;
51 namespace cssu = com::sun::star::uno;
52 namespace cssl = com::sun::star::lang;
53 namespace cssxc = com::sun::star::xml::crypto;
54 namespace cssxs = com::sun::star::xml::sax;
56 /* protected: for signature verify */
57 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
58 sal_Int32 nSecurityId)
60 if ( m_eStatusOfSecurityComponents != InitializationState::INITIALIZED )
62 return nullptr;
65 sal_Int32 nIdOfSignatureElementCollector;
66 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
68 nIdOfSignatureElementCollector =
69 m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, false);
71 m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
74 * create a SignatureVerifier
76 xReferenceResolvedListener = new SignatureVerifierImpl;
78 cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
80 cssu::Sequence<cssu::Any> args(5);
81 args[0] <<= OUString::number(nSecurityId);
82 args[1] <<= uno::Reference<xml::crypto::sax::XSecuritySAXEventKeeper>(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), uno::UNO_QUERY);
83 args[2] <<= OUString::number(nIdOfSignatureElementCollector);
84 args[3] <<= m_xSecurityContext;
85 args[4] <<= m_xXMLSignature;
86 xInitialization->initialize(args);
88 cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster >
89 signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
91 signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this );
93 m_xSAXEventKeeper->addReferenceResolvedListener(
94 nIdOfSignatureElementCollector,
95 xReferenceResolvedListener);
97 cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
98 keyCollector->setKeyId(0);
100 return xReferenceResolvedListener;
103 void XSecController::addSignature()
105 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener = nullptr;
106 sal_Int32 nSignatureId = 0;
109 if (m_bVerifyCurrentSignature)
111 chainOn();
112 xReferenceResolvedListener = prepareSignatureToRead( m_nReservedSignatureId );
113 m_bVerifyCurrentSignature = false;
114 nSignatureId = m_nReservedSignatureId;
117 InternalSignatureInformation isi( nSignatureId, xReferenceResolvedListener );
118 m_vInternalSignatureInformations.push_back( isi );
121 void XSecController::switchGpgSignature()
123 #if HAVE_FEATURE_GPGME
124 // swap signature verifier for the Gpg one
125 m_xXMLSignature.set(new XMLSignature_GpgImpl());
126 if (!m_vInternalSignatureInformations.empty())
128 SignatureVerifierImpl* pImpl=
129 dynamic_cast<SignatureVerifierImpl*>(
130 m_vInternalSignatureInformations.back().xReferenceResolvedListener.get());
131 if (pImpl)
133 css::uno::Reference<css::xml::crypto::XSEInitializer> xGpgSEInitializer(
134 new SEInitializerGpg());
135 pImpl->updateSignature(new XMLSignature_GpgImpl(),
136 xGpgSEInitializer->createSecurityContext(OUString()));
139 #else
140 (void) this;
141 #endif
144 void XSecController::addReference( const OUString& ouUri, sal_Int32 nDigestID )
146 if (m_vInternalSignatureInformations.empty())
148 SAL_INFO("xmlsecurity.helper","XSecController::addReference: no signature");
149 return;
151 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
152 isi.addReference(SignatureReferenceType::SAMEDOCUMENT, nDigestID, ouUri, -1 );
155 void XSecController::addStreamReference(
156 const OUString& ouUri,
157 bool isBinary,
158 sal_Int32 nDigestID )
160 SignatureReferenceType type = (isBinary?SignatureReferenceType::BINARYSTREAM:SignatureReferenceType::XMLSTREAM);
162 if (m_vInternalSignatureInformations.empty())
164 SAL_INFO("xmlsecurity.helper","XSecController::addStreamReference: no signature");
165 return;
167 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
169 if ( isi.xReferenceResolvedListener.is() )
172 * get the input stream
174 cssu::Reference< css::io::XInputStream > xObjectInputStream
175 = getObjectInputStream( ouUri );
177 if ( xObjectInputStream.is() )
179 cssu::Reference<cssxc::XUriBinding> xUriBinding
180 (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
181 xUriBinding->setUriBinding(ouUri, xObjectInputStream);
185 isi.addReference(type, nDigestID, ouUri, -1);
188 void XSecController::setReferenceCount() const
190 if (m_vInternalSignatureInformations.empty())
192 SAL_INFO("xmlsecurity.helper","XSecController::setReferenceCount: no signature");
193 return;
195 const InternalSignatureInformation &isi =
196 m_vInternalSignatureInformations.back();
198 if ( isi.xReferenceResolvedListener.is() )
200 const SignatureReferenceInformations &refInfors = isi.signatureInfor.vSignatureReferenceInfors;
202 int refNum = refInfors.size();
203 sal_Int32 referenceCount = 0;
205 for(int i=0 ; i<refNum; ++i)
207 if (refInfors[i].nType == SignatureReferenceType::SAMEDOCUMENT )
209 * same-document reference
212 referenceCount++;
216 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
217 (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
218 xReferenceCollector->setReferenceCount( referenceCount );
222 void XSecController::setX509IssuerName( OUString const & ouX509IssuerName )
224 if (m_vInternalSignatureInformations.empty())
226 SAL_INFO("xmlsecurity.helper","XSecController::setX509IssuerName: no signature");
227 return;
229 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
230 isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
233 void XSecController::setX509SerialNumber( OUString const & ouX509SerialNumber )
235 if (m_vInternalSignatureInformations.empty())
237 SAL_INFO("xmlsecurity.helper","XSecController::setX509SerialNumber: no signature");
238 return;
240 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
241 isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
244 void XSecController::setX509Certificate( OUString const & ouX509Certificate )
246 if (m_vInternalSignatureInformations.empty())
248 SAL_INFO("xmlsecurity.helper","XSecController::setX509Certificate: no signature");
249 return;
251 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
252 isi.signatureInfor.ouX509Certificate = ouX509Certificate;
255 void XSecController::setSignatureValue( OUString const & ouSignatureValue )
257 if (m_vInternalSignatureInformations.empty())
259 SAL_INFO("xmlsecurity.helper","XSecController::setSignatureValue: no signature");
260 return;
262 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
263 isi.signatureInfor.ouSignatureValue = ouSignatureValue;
266 void XSecController::setDigestValue( sal_Int32 nDigestID, OUString const & ouDigestValue )
268 if (m_vInternalSignatureInformations.empty())
270 SAL_INFO("xmlsecurity.helper","XSecController::setDigestValue: no signature");
271 return;
273 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
274 if (isi.signatureInfor.vSignatureReferenceInfors.empty())
276 SAL_INFO("xmlsecurity.helper","XSecController::setDigestValue: no signature reference");
277 return;
279 SignatureReferenceInformation &reference =
280 isi.signatureInfor.vSignatureReferenceInfors.back();
281 reference.nDigestID = nDigestID;
282 reference.ouDigestValue = ouDigestValue;
285 void XSecController::setGpgKeyID( OUString const & ouKeyID )
287 if (m_vInternalSignatureInformations.empty())
289 SAL_INFO("xmlsecurity.helper","XSecController::setGpgKeyID: no signature");
290 return;
292 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
293 isi.signatureInfor.ouGpgKeyID = ouKeyID;
296 void XSecController::setGpgCertificate( OUString const & ouGpgCert )
298 if (m_vInternalSignatureInformations.empty())
300 SAL_INFO("xmlsecurity.helper","XSecController::setGpgCertificate: no signature");
301 return;
303 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
304 isi.signatureInfor.ouGpgCertificate = ouGpgCert;
307 void XSecController::setGpgOwner( OUString const & ouGpgOwner )
309 if (m_vInternalSignatureInformations.empty())
311 SAL_INFO("xmlsecurity.helper","XSecController::setGpgOwner: no signature");
312 return;
314 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
315 isi.signatureInfor.ouGpgOwner = ouGpgOwner;
318 void XSecController::setDate( OUString const & ouDate )
320 if (m_vInternalSignatureInformations.empty())
322 SAL_INFO("xmlsecurity.helper","XSecController::setDate: no signature");
323 return;
325 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
326 (void)utl::ISO8601parseDateTime( ouDate, isi.signatureInfor.stDateTime);
327 isi.signatureInfor.ouDateTime = ouDate;
330 void XSecController::setDescription(const OUString& rDescription)
332 if (m_vInternalSignatureInformations.empty())
333 return;
335 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
336 rInformation.signatureInfor.ouDescription = rDescription;
339 void XSecController::setSignatureBytes(const uno::Sequence<sal_Int8>& rBytes)
341 if (m_vInternalSignatureInformations.empty())
342 return;
344 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
345 rInformation.signatureInfor.aSignatureBytes = rBytes;
348 void XSecController::setCertDigest(const OUString& rCertDigest)
350 if (m_vInternalSignatureInformations.empty())
351 return;
353 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
354 rInformation.signatureInfor.ouCertDigest = rCertDigest;
357 namespace {
358 Reference<css::graphic::XGraphic> lcl_getGraphicFromString(const OUString& rImage)
360 Sequence<sal_Int8> seq;
361 comphelper::Base64::decode(seq, rImage);
363 Reference< graphic::XGraphic > xGraphic;
364 if( !seq.hasElements() )
365 return Reference<css::graphic::XGraphic>();
367 Reference< graphic::XGraphicProvider > xGraphicProvider(
368 graphic::GraphicProvider::create(comphelper::getProcessComponentContext()) );
369 Reference< io::XInputStream > xInputStream( new ::comphelper::SequenceInputStream( seq ) );
371 Sequence< PropertyValue > aArgs( 1 );
372 aArgs[ 0 ].Name = "InputStream";
373 aArgs[ 0 ].Value <<= xInputStream;
374 xGraphic = xGraphicProvider->queryGraphic(aArgs);
376 return xGraphic;
380 void XSecController::setValidSignatureImage(const OUString& rValidSigImg)
382 if (m_vInternalSignatureInformations.empty() || rValidSigImg.isEmpty())
383 return;
385 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
386 rInformation.signatureInfor.aValidSignatureImage = lcl_getGraphicFromString(rValidSigImg);
389 void XSecController::setInvalidSignatureImage(const OUString& rInvalidSigImg)
391 if (m_vInternalSignatureInformations.empty() || rInvalidSigImg.isEmpty())
392 return;
394 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
395 rInformation.signatureInfor.aInvalidSignatureImage = lcl_getGraphicFromString(rInvalidSigImg);
398 void XSecController::setSignatureLineId(const OUString& rSignatureLineId)
400 if (m_vInternalSignatureInformations.empty())
401 return;
403 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
404 rInformation.signatureInfor.ouSignatureLineId = rSignatureLineId;
407 void XSecController::addEncapsulatedX509Certificate(const OUString& rEncapsulatedX509Certificate)
409 if (m_vInternalSignatureInformations.empty())
410 return;
412 if (rEncapsulatedX509Certificate.isEmpty())
413 return;
415 InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
416 rInformation.signatureInfor.maEncapsulatedX509Certificates.insert(rEncapsulatedX509Certificate);
419 void XSecController::setId( OUString const & ouId )
421 if (m_vInternalSignatureInformations.empty())
423 SAL_INFO("xmlsecurity.helper","XSecController::setId: no signature");
424 return;
426 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
427 isi.signatureInfor.ouSignatureId = ouId;
430 void XSecController::setPropertyId( OUString const & ouPropertyId )
432 if (m_vInternalSignatureInformations.empty())
434 SAL_INFO("xmlsecurity.helper","XSecController::setPropertyId: no signature");
435 return;
437 InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
439 if (isi.signatureInfor.ouPropertyId.isEmpty())
441 // <SignatureProperty> ID attribute is for the date.
442 isi.signatureInfor.ouPropertyId = ouPropertyId;
444 else
446 // <SignatureProperty> ID attribute is for the description.
447 isi.signatureInfor.ouDescriptionPropertyId = ouPropertyId;
451 /* public: for signature verify */
452 void XSecController::collectToVerify( const OUString& referenceId )
454 /* SAL_WARN_IF( !m_xSAXEventKeeper.is(), "xmlsecurity", "the SAXEventKeeper is NULL" ); */
456 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
458 * if all security components are ready, verify the signature.
461 bool bJustChainingOn = false;
462 cssu::Reference< cssxs::XDocumentHandler > xHandler = nullptr;
464 int i,j;
465 int sigNum = m_vInternalSignatureInformations.size();
467 for (i=0; i<sigNum; ++i)
469 InternalSignatureInformation& isi = m_vInternalSignatureInformations[i];
470 SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors;
471 int refNum = vReferenceInfors.size();
473 for (j=0; j<refNum; ++j)
475 SignatureReferenceInformation &refInfor = vReferenceInfors[j];
477 if (refInfor.ouURI == referenceId)
479 if (chainOn())
481 bJustChainingOn = true;
482 xHandler = m_xSAXEventKeeper->setNextHandler(nullptr);
485 sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
486 cssxc::sax::ElementMarkPriority_BEFOREMODIFY, false );
488 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
489 ( isi.xReferenceResolvedListener, cssu::UNO_QUERY );
491 m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
492 m_xSAXEventKeeper->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
493 xReferenceCollector->setReferenceId( nKeeperId );
495 isi.vKeeperIds[j] = nKeeperId;
496 break;
501 if ( bJustChainingOn )
503 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(static_cast<cppu::OWeakObject*>(m_xSAXEventKeeper.get()), cssu::UNO_QUERY);
504 m_xSAXEventKeeper->setNextHandler(xHandler);
509 void XSecController::addSignature( sal_Int32 nSignatureId )
511 SAL_WARN_IF( !m_xSecParser.is(), "xmlsecurity.helper", "No XSecParser initialized" );
513 m_nReservedSignatureId = nSignatureId;
514 m_bVerifyCurrentSignature = true;
517 cssu::Reference< cssxs::XDocumentHandler > const & XSecController::createSignatureReader(XMLSignatureHelper& rXMLSignatureHelper, sal_Int32 nType)
519 if (nType == embed::StorageFormats::OFOPXML)
520 m_xSecParser = new OOXMLSecParser(rXMLSignatureHelper, this);
521 else
522 m_xSecParser = new XSecParser(rXMLSignatureHelper, this);
523 cssu::Reference< cssl::XInitialization > xInitialization(m_xSecParser, uno::UNO_QUERY);
525 setSAXChainConnector(xInitialization);
527 return m_xSecParser;
530 void XSecController::releaseSignatureReader()
532 clearSAXChainConnector( );
533 m_xSecParser.clear();
536 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */