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