merged tag ooo/OOO330_m14
[LibreOffice.git] / xmlsecurity / source / helper / xsecsign.cxx
blob774a07cb28f297dee6e5a5ade506a3b8e3e8fdb1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #include <xsecctl.hxx>
32 #include <tools/debug.hxx>
34 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
35 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
36 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
37 #include <com/sun/star/xml/crypto/sax/XBlockerMonitor.hpp>
38 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
39 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultBroadcaster.hpp>
40 #include <com/sun/star/io/XActiveDataSource.hpp>
41 #include <rtl/uuid.h>
43 #include <stdio.h>
45 namespace cssu = com::sun::star::uno;
46 namespace cssl = com::sun::star::lang;
47 namespace cssxc = com::sun::star::xml::crypto;
48 namespace cssxs = com::sun::star::xml::sax;
50 /* xml security framework components */
51 #define SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator"
53 /* protected: for signature generation */
54 rtl::OUString XSecController::createId()
56 cssu::Sequence< sal_Int8 > aSeq( 16 );
57 rtl_createUuid ((sal_uInt8 *)aSeq.getArray(), 0, sal_True);
59 char str[68]="ID_";
60 int length = 3;
61 for (int i=0; i<16; ++i)
63 length += sprintf(str+length, "%04x", (unsigned char)aSeq[i]);
66 return rtl::OUString::createFromAscii(str);
69 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite(
70 InternalSignatureInformation& internalSignatureInfor )
72 sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId;
73 SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors;
75 sal_Int32 nIdOfSignatureElementCollector;
76 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
78 nIdOfSignatureElementCollector =
79 m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_True );
81 m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
84 * create a SignatureCreator
86 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
87 xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >(
88 xMCF->createInstanceWithContext(
89 rtl::OUString::createFromAscii(SIGNATURECREATOR_COMPONENT), mxCtx),
90 cssu::UNO_QUERY);
92 cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
94 cssu::Sequence<cssu::Any> args(5);
95 args[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId));
96 args[1] = cssu::makeAny(m_xSAXEventKeeper);
97 args[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector));
99 //i39448 : for nss, the internal module is used for signing, which needs to be improved later
100 sal_Int32 nEnvIndex = internalSignatureInfor.signatureInfor.nSecurityEnvironmentIndex;
101 if( nEnvIndex < 0 || nEnvIndex >= m_xSecurityContext->getSecurityEnvironmentNumber())
102 {// set defaultEnv
103 args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironment());
105 else
107 args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironmentByIndex(nEnvIndex));
110 args[4] = cssu::makeAny(m_xXMLSignature);
111 xInitialization->initialize(args);
113 sal_Int32 nBlockerId = m_xSAXEventKeeper->addBlocker();
114 m_xSAXEventKeeper->setSecurityId(nBlockerId, nSecurityId);
116 cssu::Reference<cssxc::sax::XBlockerMonitor> xBlockerMonitor(xReferenceResolvedListener, cssu::UNO_QUERY);
117 xBlockerMonitor->setBlockerId(nBlockerId);
119 cssu::Reference< cssxc::sax::XSignatureCreationResultBroadcaster >
120 xSignatureCreationResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
122 xSignatureCreationResultBroadcaster->addSignatureCreationResultListener( this );
124 cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster>
125 xReferenceResolvedBroadcaster
126 (m_xSAXEventKeeper,
127 cssu::UNO_QUERY);
129 xReferenceResolvedBroadcaster->addReferenceResolvedListener(
130 nIdOfSignatureElementCollector,
131 xReferenceResolvedListener);
133 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
134 (xReferenceResolvedListener, cssu::UNO_QUERY);
136 int i;
137 int size = vReferenceInfors.size();
138 sal_Int32 nReferenceCount = 0;
140 for(i=0; i<size; ++i)
142 sal_Int32 keeperId = internalSignatureInfor.vKeeperIds[i];
144 if ( keeperId != -1)
146 m_xSAXEventKeeper->setSecurityId(keeperId, nSecurityId);
147 xReferenceResolvedBroadcaster->addReferenceResolvedListener( keeperId, xReferenceResolvedListener);
148 xReferenceCollector->setReferenceId( keeperId );
149 nReferenceCount++;
153 xReferenceCollector->setReferenceCount( nReferenceCount );
156 * adds all URI binding
158 cssu::Reference<cssxc::XUriBinding> xUriBinding
159 (xReferenceResolvedListener, cssu::UNO_QUERY);
161 for(i=0; i<size; ++i)
163 const SignatureReferenceInformation& refInfor = vReferenceInfors[i];
165 cssu::Reference< com::sun::star::io::XInputStream > xInputStream
166 = getObjectInputStream( refInfor.ouURI );
168 if (xInputStream.is())
170 xUriBinding->setUriBinding(refInfor.ouURI,xInputStream);
174 cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
175 keyCollector->setKeyId(0);
177 internalSignatureInfor.signatureInfor.ouSignatureId = createId();
178 internalSignatureInfor.signatureInfor.ouPropertyId = createId();
179 internalSignatureInfor.addReference(TYPE_SAMEDOCUMENT_REFERENCE, internalSignatureInfor.signatureInfor.ouPropertyId, -1 );
180 size++;
183 * replace both digestValues and signatueValue to " "
185 for(i=0; i<size; ++i)
187 SignatureReferenceInformation& refInfor = vReferenceInfors[i];
188 refInfor.ouDigestValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK));
191 internalSignatureInfor.signatureInfor.ouSignatureValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK));
193 return xReferenceResolvedListener;
196 /* public: for signature generation */
197 void XSecController::collectToSign( sal_Int32 securityId, const rtl::OUString& referenceId )
199 /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */
201 chainOn(true);
203 if ( m_nStatusOfSecurityComponents == INITIALIZED )
205 * if all security components are ready, add a signature.
208 sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
209 cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_False);
211 int index = findSignatureInfor( securityId );
213 if ( index == -1 )
215 InternalSignatureInformation isi(securityId, NULL);
216 isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId );
217 m_vInternalSignatureInformations.push_back( isi );
219 else
221 m_vInternalSignatureInformations[index].addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId );
226 void XSecController::signAStream( sal_Int32 securityId, const rtl::OUString& uri, const rtl::OUString& /*objectURL*/, sal_Bool isBinary)
228 sal_Int32 type = ((isBinary==sal_True)?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE);
230 int index = findSignatureInfor( securityId );
232 if (index == -1)
234 InternalSignatureInformation isi(securityId, NULL);
235 isi.addReference(type, uri, -1);
236 m_vInternalSignatureInformations.push_back( isi );
238 else
240 m_vInternalSignatureInformations[index].addReference(type, uri, -1);
244 void XSecController::setX509Certificate(
245 sal_Int32 nSecurityId,
246 const rtl::OUString& ouX509IssuerName,
247 const rtl::OUString& ouX509SerialNumber,
248 const rtl::OUString& ouX509Cert)
250 setX509Certificate(nSecurityId, -1, ouX509IssuerName, ouX509SerialNumber, ouX509Cert);
253 void XSecController::setX509Certificate(
254 sal_Int32 nSecurityId,
255 const sal_Int32 nSecurityEnvironmentIndex,
256 const rtl::OUString& ouX509IssuerName,
257 const rtl::OUString& ouX509SerialNumber,
258 const rtl::OUString& ouX509Cert)
260 int index = findSignatureInfor( nSecurityId );
262 if ( index == -1 )
264 InternalSignatureInformation isi(nSecurityId, NULL);
265 isi.signatureInfor.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex;
266 isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
267 isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
268 isi.signatureInfor.ouX509Certificate = ouX509Cert;
269 m_vInternalSignatureInformations.push_back( isi );
271 else
273 SignatureInformation &si
274 = m_vInternalSignatureInformations[index].signatureInfor;
275 si.ouX509IssuerName = ouX509IssuerName;
276 si.ouX509SerialNumber = ouX509SerialNumber;
277 si.ouX509Certificate = ouX509Cert;
278 si.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex;
282 void XSecController::setDate(
283 sal_Int32 nSecurityId,
284 const ::com::sun::star::util::DateTime& rDateTime )
286 int index = findSignatureInfor( nSecurityId );
288 if ( index == -1 )
290 InternalSignatureInformation isi(nSecurityId, NULL);
291 isi.signatureInfor.stDateTime = rDateTime;
292 m_vInternalSignatureInformations.push_back( isi );
294 else
296 SignatureInformation &si
297 = m_vInternalSignatureInformations[index].signatureInfor;
298 si.stDateTime = rDateTime;
302 bool XSecController::WriteSignature(
303 const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler )
305 bool rc = false;
307 DBG_ASSERT( xDocumentHandler.is(), "I really need a document handler!" );
310 * chain the SAXEventKeeper to the SAX chain
312 chainOn(true);
314 if ( m_nStatusOfSecurityComponents == INITIALIZED )
316 * if all security components are ready, add the signature
317 * stream.
320 m_bIsSAXEventKeeperSticky = true;
321 m_xSAXEventKeeper->setNextHandler(xDocumentHandler);
326 * export the signature template
328 cssu::Reference<cssxs::XDocumentHandler> xSEKHandler( m_xSAXEventKeeper,cssu::UNO_QUERY);
330 int i;
331 int sigNum = m_vInternalSignatureInformations.size();
333 for (i=0; i<sigNum; ++i)
335 InternalSignatureInformation &isi = m_vInternalSignatureInformations[i];
338 * prepare the signature creator
340 isi.xReferenceResolvedListener
341 = prepareSignatureToWrite( isi );
343 exportSignature( xSEKHandler, isi.signatureInfor );
346 m_bIsSAXEventKeeperSticky = false;
347 chainOff();
349 rc = true;
351 catch( cssxs::SAXException& )
353 m_pErrorMessage = ERROR_SAXEXCEPTIONDURINGCREATION;
355 catch( com::sun::star::io::IOException& )
357 m_pErrorMessage = ERROR_IOEXCEPTIONDURINGCREATION;
359 catch( cssu::Exception& )
361 m_pErrorMessage = ERROR_EXCEPTIONDURINGCREATION;
364 m_xSAXEventKeeper->setNextHandler( NULL );
365 m_bIsSAXEventKeeperSticky = false;
367 else
369 m_pErrorMessage = ERROR_CANNOTCREATEXMLSECURITYCOMPONENT;
372 return rc;