xref: /trunk/main/xmlsecurity/source/helper/xmlsignaturehelper.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 <xmlsecurity/xmlsignaturehelper.hxx>
32 #include <xmlsecurity/documentsignaturehelper.hxx>
33 #include <xsecctl.hxx>
34 
35 #include <xmlsignaturehelper2.hxx>
36 
37 #include <tools/stream.hxx>
38 #include <tools/debug.hxx>
39 
40 #include <xmloff/attrlist.hxx>
41 
42 #include <com/sun/star/io/XOutputStream.hpp>
43 #include <com/sun/star/io/XInputStream.hpp>
44 #include <com/sun/star/io/XActiveDataSource.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/security/SerialNumberAdapter.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 
49 #include <tools/date.hxx>
50 #include <tools/time.hxx>
51 
52 //MM : search for the default profile
53 //#include <unotools/streamhelper.hxx>
54 //MM : end
55 
56 /* SEInitializer component */
57 #define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer"
58 
59 #define TAG_DOCUMENTSIGNATURES  "document-signatures"
60 #define NS_DOCUMENTSIGNATURES   "http://openoffice.org/2004/documentsignatures"
61 #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
62 
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::uno;
65 
66 XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx)
67     : mxCtx(rxCtx), mbODFPre1_2(false)
68 {
69     mpXSecController = new XSecController(rxCtx);
70     mxSecurityController = mpXSecController;
71     mbError = false;
72 }
73 
74 XMLSignatureHelper::~XMLSignatureHelper()
75 {
76 }
77 
78 bool XMLSignatureHelper::Init()
79 {
80     DBG_ASSERT( !mxSEInitializer.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" );
81     DBG_ASSERT( !mxSecurityContext.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" );
82 
83     ImplCreateSEInitializer();
84 
85     if ( mxSEInitializer.is() )
86         mxSecurityContext = mxSEInitializer->createSecurityContext( ::rtl::OUString() );
87 
88     return mxSecurityContext.is();
89 }
90 
91 void XMLSignatureHelper::ImplCreateSEInitializer()
92 {
93     rtl::OUString sSEInitializer(rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT ));
94     uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
95     mxSEInitializer = uno::Reference< com::sun::star::xml::crypto::XSEInitializer > (
96         xMCF->createInstanceWithContext( sSEInitializer,  mxCtx ), uno::UNO_QUERY );
97 }
98 
99 void XMLSignatureHelper::SetUriBinding( com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding >& rxUriBinding )
100 {
101     mxUriBinding = rxUriBinding;
102 }
103 
104 com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding > XMLSignatureHelper::GetUriBinding() const
105 {
106     return mxUriBinding;
107 }
108 
109 void XMLSignatureHelper::SetStorage(
110     const Reference < css::embed::XStorage >& rxStorage,
111     ::rtl::OUString sODFVersion)
112 {
113     DBG_ASSERT( !mxUriBinding.is(), "SetStorage - UriBinding already set!" );
114     mxUriBinding = new UriBindingHelper( rxStorage );
115     DBG_ASSERT(rxStorage.is(), "SetStorage - empty storage!");
116     mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
117 }
118 
119 
120 void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link& rLink )
121 {
122     maStartVerifySignatureHdl = rLink;
123 }
124 
125 
126 void XMLSignatureHelper::StartMission()
127 {
128     if ( !mxUriBinding.is() )
129         mxUriBinding = new UriBindingHelper();
130 
131     mpXSecController->startMission( mxUriBinding, mxSecurityContext );
132 }
133 
134 void XMLSignatureHelper::EndMission()
135 {
136     mpXSecController->endMission();
137 }
138 
139 sal_Int32 XMLSignatureHelper::GetNewSecurityId()
140 {
141     return mpXSecController->getNewSecurityId();
142 }
143 
144 void XMLSignatureHelper::SetX509Certificate(
145         sal_Int32 nSecurityId,
146         const rtl::OUString& ouX509IssuerName,
147         const rtl::OUString& ouX509SerialNumber,
148         const rtl::OUString& ouX509Cert)
149 {
150     mpXSecController->setX509Certificate(
151         nSecurityId,
152         ouX509IssuerName,
153         ouX509SerialNumber,
154         ouX509Cert);
155 }
156 
157 void XMLSignatureHelper::SetX509Certificate(
158         sal_Int32 nSecurityId,
159         sal_Int32 nSecurityEnvironmentIndex,
160         const rtl::OUString& ouX509IssuerName,
161         const rtl::OUString& ouX509SerialNumber,
162         const rtl::OUString& ouX509Cert)
163 {
164     mpXSecController->setX509Certificate(
165         nSecurityId,
166         nSecurityEnvironmentIndex,
167         ouX509IssuerName,
168         ouX509SerialNumber,
169         ouX509Cert);
170 }
171 
172 void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const Time& rTime )
173 {
174     /*
175     rtl::OUString aDate = String::CreateFromInt32( rDate.GetDate() );
176     rtl::OUString aTime = String::CreateFromInt32( rTime.GetTime() );
177     mpXSecController->setDateTime( nSecurityId, aDate, aTime );
178     */
179     ::com::sun::star::util::DateTime stDateTime;
180     stDateTime.HundredthSeconds = (::sal_uInt16)rTime.Get100Sec();
181     stDateTime.Seconds = (::sal_uInt16)rTime.GetSec();
182     stDateTime.Minutes = (::sal_uInt16)rTime.GetMin();
183     stDateTime.Hours = (::sal_uInt16)rTime.GetHour();
184     stDateTime.Day = (::sal_uInt16)rDate.GetDay();
185     stDateTime.Month = (::sal_uInt16)rDate.GetMonth();
186     stDateTime.Year = (::sal_uInt16)rDate.GetYear();
187     mpXSecController->setDate( nSecurityId, stDateTime );
188 }
189 
190 void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const rtl::OUString& uri, const rtl::OUString& objectURL, sal_Bool bBinary )
191 {
192     mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary );
193 }
194 
195 
196 uno::Reference<xml::sax::XDocumentHandler> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
197     const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
198 {
199     /*
200      * get SAX writer component
201      */
202     uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
203     uno::Reference< io::XActiveDataSource > xSaxWriter(
204         xMCF->createInstanceWithContext(rtl::OUString::createFromAscii(
205             "com.sun.star.xml.sax.Writer"), mxCtx ), uno::UNO_QUERY );
206 
207     DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
208 
209     /*
210      * connect XML writer to output stream
211      */
212     xSaxWriter->setOutputStream( xOutputStream );
213 
214     /*
215      * prepare document handler
216      */
217     uno::Reference<xml::sax::XDocumentHandler>
218         xDocHandler( xSaxWriter,uno::UNO_QUERY);
219 
220     /*
221      * write the xml context for signatures
222      */
223     rtl::OUString tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES));
224 
225     SvXMLAttributeList *pAttributeList = new SvXMLAttributeList();
226     rtl::OUString sNamespace;
227     if (mbODFPre1_2)
228         sNamespace = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES));
229     else
230         sNamespace = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES_ODF_1_2));
231 
232     pAttributeList->AddAttribute(
233         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS)),
234         sNamespace);
235 
236     xDocHandler->startDocument();
237     xDocHandler->startElement(
238         tag_AllSignatures,
239         uno::Reference< com::sun::star::xml::sax::XAttributeList > (pAttributeList));
240 
241     return xDocHandler;
242 }
243 
244 void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler )
245 {
246     rtl::OUString tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES));
247     xDocumentHandler->endElement( tag_AllSignatures );
248     xDocumentHandler->endDocument();
249 }
250 
251 void XMLSignatureHelper::ExportSignature(
252     const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler,
253     const SignatureInformation& signatureInfo )
254 {
255     mpXSecController->exportSignature(xDocumentHandler, signatureInfo);
256 }
257 
258 bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler )
259 {
260     mbError = false;
261 
262     /*
263      * create a signature listener
264      */
265 /*
266     ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
267                                                     LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
268                                                     LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
269                                                     LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
270 */
271     /*
272      * configure the signature creation listener
273      */
274     //mpXSecController->setSignatureCreationResultListener( pSignatureListener );
275 
276     /*
277      * write signatures
278      */
279     if ( !mpXSecController->WriteSignature( xDocumentHandler ) )
280     {
281         mbError = true;
282     }
283 
284     /*
285      * clear up the signature creation listener
286      */
287     //mpXSecController->setSignatureCreationResultListener( NULL );
288 
289     return !mbError;
290 }
291 
292 bool XMLSignatureHelper::CreateAndWriteSignature( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
293 {
294     uno::Reference<xml::sax::XDocumentHandler> xDocHandler
295         = CreateDocumentHandlerWithHeader(xOutputStream);
296 
297     bool rc = CreateAndWriteSignature( xDocHandler );
298 
299     CloseDocumentHandler(xDocHandler);
300 
301     return rc;
302 }
303 
304 bool XMLSignatureHelper::ReadAndVerifySignature( const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream )
305 {
306     mbError = false;
307 
308     DBG_ASSERT(xInputStream.is(), "input stream missing");
309 
310     /*
311      * prepare ParserInputSrouce
312      */
313     xml::sax::InputSource aParserInput;
314     // aParserInput.sSystemId = ouName;
315     aParserInput.aInputStream = xInputStream;
316 
317     /*
318      * get SAX parser component
319      */
320     uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
321     uno::Reference< xml::sax::XParser > xParser(
322         xMCF->createInstanceWithContext(
323             rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser"), mxCtx ),
324         uno::UNO_QUERY );
325 
326     DBG_ASSERT( xParser.is(), "Can't create parser" );
327 
328     /*
329      * create a signature reader
330      */
331     uno::Reference< xml::sax::XDocumentHandler > xHandler
332         = mpXSecController->createSignatureReader( );
333 
334     /*
335      * create a signature listener
336      */
337     ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
338                                                     LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
339                                                     LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
340                                                     LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
341 
342     /*
343      * configure the signature verify listener
344      */
345     //mpXSecController->setSignatureVerifyResultListener( pSignatureListener );
346 
347     /*
348      * setup the connection:
349      * Parser -> SignatureListener -> SignatureReader
350      */
351     pSignatureListener->setNextHandler(xHandler);
352     xParser->setDocumentHandler( pSignatureListener );
353 
354     /*
355      * parser the stream
356      */
357     try
358     {
359         xParser->parseStream( aParserInput );
360     }
361     catch( xml::sax::SAXParseException& )
362     {
363         mbError = true;
364     }
365     catch( xml::sax::SAXException& )
366     {
367         mbError = true;
368     }
369     catch( com::sun::star::io::IOException& )
370     {
371         mbError = true;
372     }
373     catch( uno::Exception& )
374     {
375         mbError = true;
376     }
377 
378     /*
379      * clear up the connection
380      */
381     pSignatureListener->setNextHandler( NULL );
382 
383     /*
384      * clear up the signature verify listener
385      */
386     //mpXSecController->setSignatureVerifyResultListener( NULL );
387 
388     /*
389      * release the signature reader
390      */
391     mpXSecController->releaseSignatureReader( );
392 
393     return !mbError;
394 }
395 
396 SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const
397 {
398     return mpXSecController->getSignatureInformation( nSecurityId );
399 }
400 
401 SignatureInformations XMLSignatureHelper::GetSignatureInformations() const
402 {
403     return mpXSecController->getSignatureInformations();
404 }
405 
406 uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironment()
407 {
408     return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironment()): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >());
409 }
410 
411 uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironmentByIndex(sal_Int32 nId)
412 {
413     return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentByIndex(nId)): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >());
414 }
415 
416 sal_Int32 XMLSignatureHelper::GetSecurityEnvironmentNumber()
417 {
418     return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentNumber()): 0);
419 }
420 
421 IMPL_LINK( XMLSignatureHelper, SignatureCreationResultListener, XMLSignatureCreationResult*, pResult )
422 {
423     maCreationResults.insert( maCreationResults.begin() + maCreationResults.size(), *pResult );
424     if ( pResult->nSignatureCreationResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
425         mbError = true;
426     return 0;
427 }
428 
429 IMPL_LINK( XMLSignatureHelper, SignatureVerifyResultListener, XMLSignatureVerifyResult*, pResult )
430 {
431     maVerifyResults.insert( maVerifyResults.begin() + maVerifyResults.size(), *pResult );
432     if ( pResult->nSignatureVerifyResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
433         mbError = true;
434     return 0;
435 }
436 
437 IMPL_LINK( XMLSignatureHelper, StartVerifySignatureElement, const uno::Reference< com::sun::star::xml::sax::XAttributeList >*, pAttrs )
438 {
439     if ( !maStartVerifySignatureHdl.IsSet() || maStartVerifySignatureHdl.Call( (void*)pAttrs ) )
440     {
441         sal_Int32 nSignatureId = mpXSecController->getNewSecurityId();
442         mpXSecController->addSignature( nSignatureId );
443     }
444 
445     return 0;
446 }
447