build fix
[LibreOffice.git] / xmlsecurity / source / helper / xsecsign.cxx
blob40d1fd0e3848921dd16b99d29acbdb6802d7c460
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 .
21 #include "xsecctl.hxx"
23 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
24 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
25 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
26 #include <com/sun/star/xml/crypto/sax/XBlockerMonitor.hpp>
27 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
28 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultBroadcaster.hpp>
29 #include <com/sun/star/io/XActiveDataSource.hpp>
30 #include <com/sun/star/embed/StorageFormats.hpp>
31 #include <rtl/uuid.h>
33 #include <stdio.h>
35 using namespace com::sun::star;
36 namespace cssu = com::sun::star::uno;
37 namespace cssl = com::sun::star::lang;
38 namespace cssxc = com::sun::star::xml::crypto;
39 namespace cssxs = com::sun::star::xml::sax;
41 /* xml security framework components */
42 #define SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator"
44 /* protected: for signature generation */
45 OUString XSecController::createId()
47 sal_uInt8 aSeq[16];
48 rtl_createUuid( aSeq, nullptr, true );
50 char str[68]="ID_";
51 int length = 3;
52 for (sal_uInt8 i : aSeq)
54 length += sprintf(str+length, "%04x", i);
57 return OUString::createFromAscii(str);
60 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite(
61 InternalSignatureInformation& internalSignatureInfor,
62 sal_Int32 nStorageFormat,
63 bool bXAdESCompliantIfODF)
65 sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId;
66 SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors;
68 sal_Int32 nIdOfSignatureElementCollector;
69 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
71 nIdOfSignatureElementCollector =
72 m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY, true );
74 m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
77 * create a SignatureCreator
79 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
80 xReferenceResolvedListener.set(
81 xMCF->createInstanceWithContext(SIGNATURECREATOR_COMPONENT, mxCtx),
82 cssu::UNO_QUERY);
84 cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
86 cssu::Sequence<cssu::Any> args(5);
87 args[0] = cssu::makeAny(OUString::number(nSecurityId));
88 args[1] = cssu::makeAny(m_xSAXEventKeeper);
89 args[2] = cssu::makeAny(OUString::number(nIdOfSignatureElementCollector));
91 //for nss, the internal module is used for signing, which needs to be improved later
92 args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironment());
94 args[4] = cssu::makeAny(m_xXMLSignature);
95 xInitialization->initialize(args);
97 sal_Int32 nBlockerId = m_xSAXEventKeeper->addBlocker();
98 m_xSAXEventKeeper->setSecurityId(nBlockerId, nSecurityId);
100 cssu::Reference<cssxc::sax::XBlockerMonitor> xBlockerMonitor(xReferenceResolvedListener, cssu::UNO_QUERY);
101 xBlockerMonitor->setBlockerId(nBlockerId);
103 cssu::Reference< cssxc::sax::XSignatureCreationResultBroadcaster >
104 xSignatureCreationResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
106 xSignatureCreationResultBroadcaster->addSignatureCreationResultListener( this );
108 cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster>
109 xReferenceResolvedBroadcaster
110 (m_xSAXEventKeeper,
111 cssu::UNO_QUERY);
113 xReferenceResolvedBroadcaster->addReferenceResolvedListener(
114 nIdOfSignatureElementCollector,
115 xReferenceResolvedListener);
117 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
118 (xReferenceResolvedListener, cssu::UNO_QUERY);
120 int i;
121 int size = vReferenceInfors.size();
122 sal_Int32 nReferenceCount = 0;
124 for(i=0; i<size; ++i)
126 sal_Int32 keeperId = internalSignatureInfor.vKeeperIds[i];
128 if ( keeperId != -1)
130 m_xSAXEventKeeper->setSecurityId(keeperId, nSecurityId);
131 xReferenceResolvedBroadcaster->addReferenceResolvedListener( keeperId, xReferenceResolvedListener);
132 xReferenceCollector->setReferenceId( keeperId );
133 nReferenceCount++;
137 xReferenceCollector->setReferenceCount( nReferenceCount );
140 * adds all URI binding
142 cssu::Reference<cssxc::XUriBinding> xUriBinding
143 (xReferenceResolvedListener, cssu::UNO_QUERY);
145 for(i=0; i<size; ++i)
147 const SignatureReferenceInformation& refInfor = vReferenceInfors[i];
149 cssu::Reference< css::io::XInputStream > xInputStream
150 = getObjectInputStream( refInfor.ouURI );
152 if (xInputStream.is())
154 xUriBinding->setUriBinding(refInfor.ouURI,xInputStream);
158 cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
159 keyCollector->setKeyId(0);
161 const sal_Int32 digestID = bXAdESCompliantIfODF ? cssxc::DigestID::SHA256 : cssxc::DigestID::SHA1;
163 if (nStorageFormat != embed::StorageFormats::OFOPXML)
165 internalSignatureInfor.signatureInfor.ouSignatureId = createId();
166 internalSignatureInfor.signatureInfor.ouPropertyId = createId();
167 internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouPropertyId, -1 );
168 size++;
170 if (bXAdESCompliantIfODF)
172 internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idSignedProperties", -1);
173 size++;
176 if (!internalSignatureInfor.signatureInfor.ouDescription.isEmpty())
178 // Only mention the hash of the description in the signature if it's non-empty.
179 internalSignatureInfor.signatureInfor.ouDescriptionPropertyId = createId();
180 internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouDescriptionPropertyId, -1);
181 size++;
184 else
186 internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idPackageObject", -1);
187 size++;
188 internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idOfficeObject", -1);
189 size++;
190 internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idSignedProperties", -1);
191 size++;
195 * replace both digestValues and signatueValue to " "
197 for(i=0; i<size; ++i)
199 SignatureReferenceInformation& refInfor = vReferenceInfors[i];
200 refInfor.ouDigestValue = " ";
203 internalSignatureInfor.signatureInfor.ouSignatureValue = " ";
205 return xReferenceResolvedListener;
208 void XSecController::signAStream( sal_Int32 securityId, const OUString& uri, const OUString& /*objectURL*/, bool isBinary, bool bXAdESCompliantIfODF)
210 const SignatureReferenceType type = isBinary ? SignatureReferenceType::BINARYSTREAM : SignatureReferenceType::XMLSTREAM;
211 const sal_Int32 digestID = bXAdESCompliantIfODF ? cssxc::DigestID::SHA256 : cssxc::DigestID::SHA1;
213 int index = findSignatureInfor( securityId );
215 if (index == -1)
217 InternalSignatureInformation isi(securityId, nullptr);
218 isi.addReference(type, digestID, uri, -1);
219 m_vInternalSignatureInformations.push_back( isi );
221 else
223 m_vInternalSignatureInformations[index].addReference(type, digestID, uri, -1);
227 void XSecController::setX509Certificate(
228 sal_Int32 nSecurityId,
229 const OUString& ouX509IssuerName,
230 const OUString& ouX509SerialNumber,
231 const OUString& ouX509Cert,
232 const OUString& ouX509CertDigest)
234 int index = findSignatureInfor( nSecurityId );
236 if ( index == -1 )
238 InternalSignatureInformation isi(nSecurityId, nullptr);
239 isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
240 isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
241 isi.signatureInfor.ouX509Certificate = ouX509Cert;
242 isi.signatureInfor.ouCertDigest = ouX509CertDigest;
243 m_vInternalSignatureInformations.push_back( isi );
245 else
247 SignatureInformation &si
248 = m_vInternalSignatureInformations[index].signatureInfor;
249 si.ouX509IssuerName = ouX509IssuerName;
250 si.ouX509SerialNumber = ouX509SerialNumber;
251 si.ouX509Certificate = ouX509Cert;
252 si.ouCertDigest = ouX509CertDigest;
256 void XSecController::setDate(
257 sal_Int32 nSecurityId,
258 const css::util::DateTime& rDateTime )
260 int index = findSignatureInfor( nSecurityId );
262 if ( index == -1 )
264 InternalSignatureInformation isi(nSecurityId, nullptr);
265 isi.signatureInfor.stDateTime = rDateTime;
266 m_vInternalSignatureInformations.push_back( isi );
268 else
270 SignatureInformation &si
271 = m_vInternalSignatureInformations[index].signatureInfor;
272 si.stDateTime = rDateTime;
276 void XSecController::setDescription(sal_Int32 nSecurityId, const OUString& rDescription)
278 int nIndex = findSignatureInfor(nSecurityId);
280 if (nIndex == -1)
282 InternalSignatureInformation aInformation(nSecurityId, nullptr);
283 aInformation.signatureInfor.ouDescription = rDescription;
284 m_vInternalSignatureInformations.push_back(aInformation);
286 else
288 SignatureInformation& rInformation = m_vInternalSignatureInformations[nIndex].signatureInfor;
289 rInformation.ouDescription = rDescription;
293 bool XSecController::WriteSignature(
294 const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
295 bool bXAdESCompliantIfODF )
297 bool rc = false;
299 SAL_WARN_IF( !xDocumentHandler.is(), "xmlsecurity.helper", "I really need a document handler!" );
302 * chain the SAXEventKeeper to the SAX chain
304 chainOn(true);
306 if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED )
308 * if all security components are ready, add the signature
309 * stream.
312 m_bIsSAXEventKeeperSticky = true;
313 m_xSAXEventKeeper->setNextHandler(xDocumentHandler);
318 * export the signature template
320 cssu::Reference<cssxs::XDocumentHandler> xSEKHandler( m_xSAXEventKeeper,cssu::UNO_QUERY);
322 int i;
323 int sigNum = m_vInternalSignatureInformations.size();
325 for (i=0; i<sigNum; ++i)
327 InternalSignatureInformation &isi = m_vInternalSignatureInformations[i];
329 // Prepare the signature creator.
330 // 0 is not a documented value of embed::StorageFormats, ugh
331 isi.xReferenceResolvedListener = prepareSignatureToWrite( isi, 0, bXAdESCompliantIfODF );
333 exportSignature( xSEKHandler, isi.signatureInfor, bXAdESCompliantIfODF );
336 m_bIsSAXEventKeeperSticky = false;
337 chainOff();
339 rc = true;
341 catch( cssu::Exception& )
345 m_xSAXEventKeeper->setNextHandler( nullptr );
346 m_bIsSAXEventKeeperSticky = false;
349 return rc;
352 bool XSecController::WriteOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler)
354 bool bRet = false;
356 SAL_WARN_IF(!xDocumentHandler.is(), "xmlsecurity.helper", "empty xDocumentHandler reference");
358 // Chain the SAXEventKeeper to the SAX chain.
359 chainOn(/*bRetrievingLastEvent=*/true);
361 if (m_eStatusOfSecurityComponents == InitializationState::INITIALIZED)
363 m_bIsSAXEventKeeperSticky = true;
364 m_xSAXEventKeeper->setNextHandler(xDocumentHandler);
368 // Export the signature template.
369 cssu::Reference<xml::sax::XDocumentHandler> xSEKHandler(m_xSAXEventKeeper, uno::UNO_QUERY);
371 for (InternalSignatureInformation & rInformation : m_vInternalSignatureInformations)
373 // Prepare the signature creator.
374 rInformation.xReferenceResolvedListener = prepareSignatureToWrite(rInformation, embed::StorageFormats::OFOPXML, false);
376 exportOOXMLSignature(xRootStorage, xSEKHandler, rInformation.signatureInfor);
379 m_bIsSAXEventKeeperSticky = false;
380 chainOff();
382 bRet = true;
384 catch(const uno::Exception&)
388 m_xSAXEventKeeper->setNextHandler(nullptr);
389 m_bIsSAXEventKeeperSticky = false;
392 return bRet;
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */