xref: /trunk/main/xmlsecurity/source/helper/xsecsign.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
30 
31 #include <xsecctl.hxx>
32 #include <tools/debug.hxx>
33 
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>
42 
43 #include <stdio.h>
44 
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;
49 
50 /* xml security framework components */
51 #define SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator"
52 
53 /* protected: for signature generation */
54 rtl::OUString XSecController::createId()
55 {
56     cssu::Sequence< sal_Int8 > aSeq( 16 );
57     rtl_createUuid ((sal_uInt8 *)aSeq.getArray(), 0, sal_True);
58 
59     char str[68]="ID_";
60     int length = 3;
61     for (int i=0; i<16; ++i)
62     {
63         length += sprintf(str+length, "%04x", (unsigned char)aSeq[i]);
64     }
65 
66     return rtl::OUString::createFromAscii(str);
67 }
68 
69 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite(
70     InternalSignatureInformation& internalSignatureInfor )
71 {
72     sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId;
73     SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors;
74 
75     sal_Int32 nIdOfSignatureElementCollector;
76     cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;
77 
78     nIdOfSignatureElementCollector =
79         m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_True );
80 
81     m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
82 
83         /*
84          * create a SignatureCreator
85          */
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);
91 
92     cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
93 
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));
98 
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());
104     }
105     else
106     {
107         args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironmentByIndex(nEnvIndex));
108     }
109 
110     args[4] = cssu::makeAny(m_xXMLSignature);
111     xInitialization->initialize(args);
112 
113     sal_Int32 nBlockerId = m_xSAXEventKeeper->addBlocker();
114     m_xSAXEventKeeper->setSecurityId(nBlockerId, nSecurityId);
115 
116     cssu::Reference<cssxc::sax::XBlockerMonitor> xBlockerMonitor(xReferenceResolvedListener, cssu::UNO_QUERY);
117     xBlockerMonitor->setBlockerId(nBlockerId);
118 
119     cssu::Reference< cssxc::sax::XSignatureCreationResultBroadcaster >
120         xSignatureCreationResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
121 
122     xSignatureCreationResultBroadcaster->addSignatureCreationResultListener( this );
123 
124     cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster>
125         xReferenceResolvedBroadcaster
126         (m_xSAXEventKeeper,
127         cssu::UNO_QUERY);
128 
129     xReferenceResolvedBroadcaster->addReferenceResolvedListener(
130         nIdOfSignatureElementCollector,
131         xReferenceResolvedListener);
132 
133     cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
134         (xReferenceResolvedListener, cssu::UNO_QUERY);
135 
136     int i;
137     int size = vReferenceInfors.size();
138     sal_Int32 nReferenceCount = 0;
139 
140     for(i=0; i<size; ++i)
141     {
142         sal_Int32 keeperId = internalSignatureInfor.vKeeperIds[i];
143 
144         if ( keeperId != -1)
145         {
146             m_xSAXEventKeeper->setSecurityId(keeperId, nSecurityId);
147             xReferenceResolvedBroadcaster->addReferenceResolvedListener( keeperId, xReferenceResolvedListener);
148             xReferenceCollector->setReferenceId( keeperId );
149             nReferenceCount++;
150         }
151     }
152 
153     xReferenceCollector->setReferenceCount( nReferenceCount );
154 
155     /*
156      * adds all URI binding
157      */
158     cssu::Reference<cssxc::XUriBinding> xUriBinding
159         (xReferenceResolvedListener, cssu::UNO_QUERY);
160 
161     for(i=0; i<size; ++i)
162     {
163         const SignatureReferenceInformation& refInfor = vReferenceInfors[i];
164 
165         cssu::Reference< com::sun::star::io::XInputStream > xInputStream
166             = getObjectInputStream( refInfor.ouURI );
167 
168         if (xInputStream.is())
169         {
170             xUriBinding->setUriBinding(refInfor.ouURI,xInputStream);
171         }
172     }
173 
174     cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
175     keyCollector->setKeyId(0);
176 
177     internalSignatureInfor.signatureInfor.ouSignatureId = createId();
178     internalSignatureInfor.signatureInfor.ouPropertyId = createId();
179     internalSignatureInfor.addReference(TYPE_SAMEDOCUMENT_REFERENCE, internalSignatureInfor.signatureInfor.ouPropertyId, -1 );
180     size++;
181 
182     /*
183      * replace both digestValues and signatueValue to " "
184      */
185     for(i=0; i<size; ++i)
186     {
187         SignatureReferenceInformation& refInfor = vReferenceInfors[i];
188         refInfor.ouDigestValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK));
189     }
190 
191     internalSignatureInfor.signatureInfor.ouSignatureValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK));
192 
193     return xReferenceResolvedListener;
194 }
195 
196 /* public: for signature generation */
197 void XSecController::collectToSign( sal_Int32 securityId, const rtl::OUString& referenceId )
198 {
199     /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */
200 
201     chainOn(true);
202 
203     if ( m_nStatusOfSecurityComponents == INITIALIZED )
204     /*
205      * if all security components are ready, add a signature.
206      */
207     {
208         sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
209             cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_False);
210 
211         int index = findSignatureInfor( securityId );
212 
213         if ( index == -1 )
214         {
215             InternalSignatureInformation isi(securityId, NULL);
216             isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId );
217             m_vInternalSignatureInformations.push_back( isi );
218         }
219         else
220         {
221             m_vInternalSignatureInformations[index].addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId );
222         }
223     }
224 }
225 
226 void XSecController::signAStream( sal_Int32 securityId, const rtl::OUString& uri, const rtl::OUString& /*objectURL*/, sal_Bool isBinary)
227 {
228         sal_Int32 type = ((isBinary==sal_True)?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE);
229 
230     int index = findSignatureInfor( securityId );
231 
232     if (index == -1)
233     {
234         InternalSignatureInformation isi(securityId, NULL);
235         isi.addReference(type, uri, -1);
236         m_vInternalSignatureInformations.push_back( isi );
237     }
238     else
239     {
240         m_vInternalSignatureInformations[index].addReference(type, uri, -1);
241     }
242 }
243 
244 void XSecController::setX509Certificate(
245     sal_Int32 nSecurityId,
246     const rtl::OUString& ouX509IssuerName,
247     const rtl::OUString& ouX509SerialNumber,
248     const rtl::OUString& ouX509Cert)
249 {
250     setX509Certificate(nSecurityId, -1, ouX509IssuerName, ouX509SerialNumber, ouX509Cert);
251 }
252 
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)
259 {
260     int index = findSignatureInfor( nSecurityId );
261 
262     if ( index == -1 )
263     {
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 );
270     }
271     else
272     {
273         SignatureInformation &si
274             = m_vInternalSignatureInformations[index].signatureInfor;
275         si.ouX509IssuerName = ouX509IssuerName;
276         si.ouX509SerialNumber = ouX509SerialNumber;
277         si.ouX509Certificate = ouX509Cert;
278         si.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex;
279     }
280 }
281 
282 void XSecController::setDate(
283     sal_Int32 nSecurityId,
284     const ::com::sun::star::util::DateTime& rDateTime )
285 {
286     int index = findSignatureInfor( nSecurityId );
287 
288     if ( index == -1 )
289     {
290         InternalSignatureInformation isi(nSecurityId, NULL);
291         isi.signatureInfor.stDateTime = rDateTime;
292         m_vInternalSignatureInformations.push_back( isi );
293     }
294     else
295     {
296         SignatureInformation &si
297             = m_vInternalSignatureInformations[index].signatureInfor;
298         si.stDateTime = rDateTime;
299     }
300 }
301 
302 bool XSecController::WriteSignature(
303     const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler )
304 {
305     bool rc = false;
306 
307     DBG_ASSERT( xDocumentHandler.is(), "I really need a document handler!" );
308 
309     /*
310      * chain the SAXEventKeeper to the SAX chain
311      */
312     chainOn(true);
313 
314     if ( m_nStatusOfSecurityComponents == INITIALIZED )
315     /*
316      * if all security components are ready, add the signature
317      * stream.
318      */
319     {
320         m_bIsSAXEventKeeperSticky = true;
321         m_xSAXEventKeeper->setNextHandler(xDocumentHandler);
322 
323         try
324         {
325             /*
326              * export the signature template
327              */
328             cssu::Reference<cssxs::XDocumentHandler> xSEKHandler( m_xSAXEventKeeper,cssu::UNO_QUERY);
329 
330             int i;
331             int sigNum = m_vInternalSignatureInformations.size();
332 
333             for (i=0; i<sigNum; ++i)
334             {
335                 InternalSignatureInformation &isi = m_vInternalSignatureInformations[i];
336 
337                 /*
338                  * prepare the signature creator
339                  */
340                 isi.xReferenceResolvedListener
341                     = prepareSignatureToWrite( isi );
342 
343                 exportSignature( xSEKHandler, isi.signatureInfor );
344             }
345 
346             m_bIsSAXEventKeeperSticky = false;
347             chainOff();
348 
349             rc = true;
350         }
351         catch( cssxs::SAXException& )
352         {
353             m_pErrorMessage = ERROR_SAXEXCEPTIONDURINGCREATION;
354         }
355         catch( com::sun::star::io::IOException& )
356         {
357             m_pErrorMessage = ERROR_IOEXCEPTIONDURINGCREATION;
358         }
359         catch( cssu::Exception& )
360         {
361             m_pErrorMessage = ERROR_EXCEPTIONDURINGCREATION;
362         }
363 
364         m_xSAXEventKeeper->setNextHandler( NULL );
365         m_bIsSAXEventKeeperSticky = false;
366     }
367     else
368     {
369         m_pErrorMessage = ERROR_CANNOTCREATEXMLSECURITYCOMPONENT;
370     }
371 
372     return rc;
373 }
374 
375