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 <xmlsecurity/xmlsignaturehelper.hxx>
32 #include <xmlsecurity/documentsignaturehelper.hxx>
33 #include <xsecctl.hxx>
35 #include <xmlsignaturehelper2.hxx>
37 #include <tools/stream.hxx>
38 #include <tools/debug.hxx>
40 #include <xmloff/attrlist.hxx>
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>
49 #include <tools/date.hxx>
50 #include <tools/time.hxx>
52 //MM : search for the default profile
53 //#include <unotools/streamhelper.hxx>
56 /* SEInitializer component */
57 #define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer"
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"
63 using namespace ::com::sun::star
;
64 using namespace ::com::sun::star::uno
;
66 XMLSignatureHelper::XMLSignatureHelper( const uno::Reference
< uno::XComponentContext
>& rxCtx
)
67 : mxCtx(rxCtx
), mbODFPre1_2(false)
69 mpXSecController
= new XSecController(rxCtx
);
70 mxSecurityController
= mpXSecController
;
74 XMLSignatureHelper::~XMLSignatureHelper()
76 if ( mxSEInitializer
.is() && mxSecurityContext
.is() )
77 mxSEInitializer
->freeSecurityContext( mxSecurityContext
);
80 bool XMLSignatureHelper::Init( const rtl::OUString
& rTokenPath
)
82 DBG_ASSERT( !mxSEInitializer
.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" );
83 DBG_ASSERT( !mxSecurityContext
.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" );
85 ImplCreateSEInitializer();
87 if ( mxSEInitializer
.is() )
88 mxSecurityContext
= mxSEInitializer
->createSecurityContext( rTokenPath
);
90 return mxSecurityContext
.is();
93 void XMLSignatureHelper::ImplCreateSEInitializer()
95 rtl::OUString
sSEInitializer(rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT
));
96 uno::Reference
< lang::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
97 mxSEInitializer
= uno::Reference
< com::sun::star::xml::crypto::XSEInitializer
> (
98 xMCF
->createInstanceWithContext( sSEInitializer
, mxCtx
), uno::UNO_QUERY
);
101 void XMLSignatureHelper::SetUriBinding( com::sun::star::uno::Reference
< com::sun::star::xml::crypto::XUriBinding
>& rxUriBinding
)
103 mxUriBinding
= rxUriBinding
;
106 com::sun::star::uno::Reference
< com::sun::star::xml::crypto::XUriBinding
> XMLSignatureHelper::GetUriBinding() const
111 void XMLSignatureHelper::SetStorage(
112 const Reference
< css::embed::XStorage
>& rxStorage
,
113 ::rtl::OUString sODFVersion
)
115 DBG_ASSERT( !mxUriBinding
.is(), "SetStorage - UriBinding already set!" );
116 mxUriBinding
= new UriBindingHelper( rxStorage
);
117 DBG_ASSERT(rxStorage
.is(), "SetStorage - empty storage!");
118 mbODFPre1_2
= DocumentSignatureHelper::isODFPre_1_2(sODFVersion
);
122 void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link
& rLink
)
124 maStartVerifySignatureHdl
= rLink
;
128 void XMLSignatureHelper::StartMission()
130 if ( !mxUriBinding
.is() )
131 mxUriBinding
= new UriBindingHelper();
133 mpXSecController
->startMission( mxUriBinding
, mxSecurityContext
);
136 void XMLSignatureHelper::EndMission()
138 mpXSecController
->endMission();
141 sal_Int32
XMLSignatureHelper::GetNewSecurityId()
143 return mpXSecController
->getNewSecurityId();
146 void XMLSignatureHelper::SetX509Certificate(
147 sal_Int32 nSecurityId
,
148 const rtl::OUString
& ouX509IssuerName
,
149 const rtl::OUString
& ouX509SerialNumber
,
150 const rtl::OUString
& ouX509Cert
)
152 mpXSecController
->setX509Certificate(
159 void XMLSignatureHelper::SetX509Certificate(
160 sal_Int32 nSecurityId
,
161 sal_Int32 nSecurityEnvironmentIndex
,
162 const rtl::OUString
& ouX509IssuerName
,
163 const rtl::OUString
& ouX509SerialNumber
,
164 const rtl::OUString
& ouX509Cert
)
166 mpXSecController
->setX509Certificate(
168 nSecurityEnvironmentIndex
,
174 void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId
, const Date
& rDate
, const Time
& rTime
)
177 rtl::OUString aDate = String::CreateFromInt32( rDate.GetDate() );
178 rtl::OUString aTime = String::CreateFromInt32( rTime.GetTime() );
179 mpXSecController->setDateTime( nSecurityId, aDate, aTime );
181 ::com::sun::star::util::DateTime stDateTime
;
182 stDateTime
.HundredthSeconds
= (::sal_uInt16
)rTime
.Get100Sec();
183 stDateTime
.Seconds
= (::sal_uInt16
)rTime
.GetSec();
184 stDateTime
.Minutes
= (::sal_uInt16
)rTime
.GetMin();
185 stDateTime
.Hours
= (::sal_uInt16
)rTime
.GetHour();
186 stDateTime
.Day
= (::sal_uInt16
)rDate
.GetDay();
187 stDateTime
.Month
= (::sal_uInt16
)rDate
.GetMonth();
188 stDateTime
.Year
= (::sal_uInt16
)rDate
.GetYear();
189 mpXSecController
->setDate( nSecurityId
, stDateTime
);
192 void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId
, const rtl::OUString
& uri
, const rtl::OUString
& objectURL
, sal_Bool bBinary
)
194 mpXSecController
->signAStream( nSecurityId
, uri
, objectURL
, bBinary
);
198 uno::Reference
<xml::sax::XDocumentHandler
> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
199 const com::sun::star::uno::Reference
< com::sun::star::io::XOutputStream
>& xOutputStream
)
202 * get SAX writer component
204 uno::Reference
< lang::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
205 uno::Reference
< io::XActiveDataSource
> xSaxWriter(
206 xMCF
->createInstanceWithContext(rtl::OUString::createFromAscii(
207 "com.sun.star.xml.sax.Writer"), mxCtx
), uno::UNO_QUERY
);
209 DBG_ASSERT( xSaxWriter
.is(), "can't instantiate XML writer" );
212 * connect XML writer to output stream
214 xSaxWriter
->setOutputStream( xOutputStream
);
217 * prepare document handler
219 uno::Reference
<xml::sax::XDocumentHandler
>
220 xDocHandler( xSaxWriter
,uno::UNO_QUERY
);
223 * write the xml context for signatures
225 rtl::OUString
tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES
));
227 SvXMLAttributeList
*pAttributeList
= new SvXMLAttributeList();
228 rtl::OUString sNamespace
;
230 sNamespace
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES
));
232 sNamespace
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES_ODF_1_2
));
234 pAttributeList
->AddAttribute(
235 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS
)),
238 xDocHandler
->startDocument();
239 xDocHandler
->startElement(
241 uno::Reference
< com::sun::star::xml::sax::XAttributeList
> (pAttributeList
));
246 void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference
<xml::sax::XDocumentHandler
>& xDocumentHandler
)
248 rtl::OUString
tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES
));
249 xDocumentHandler
->endElement( tag_AllSignatures
);
250 xDocumentHandler
->endDocument();
253 void XMLSignatureHelper::ExportSignature(
254 const uno::Reference
< xml::sax::XDocumentHandler
>& xDocumentHandler
,
255 const SignatureInformation
& signatureInfo
)
257 mpXSecController
->exportSignature(xDocumentHandler
, signatureInfo
);
260 bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference
< xml::sax::XDocumentHandler
>& xDocumentHandler
)
265 * create a signature listener
268 ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
269 LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
270 LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
271 LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
274 * configure the signature creation listener
276 //mpXSecController->setSignatureCreationResultListener( pSignatureListener );
281 if ( !mpXSecController
->WriteSignature( xDocumentHandler
) )
287 * clear up the signature creation listener
289 //mpXSecController->setSignatureCreationResultListener( NULL );
294 bool XMLSignatureHelper::CreateAndWriteSignature( const com::sun::star::uno::Reference
< com::sun::star::io::XOutputStream
>& xOutputStream
)
296 uno::Reference
<xml::sax::XDocumentHandler
> xDocHandler
297 = CreateDocumentHandlerWithHeader(xOutputStream
);
299 bool rc
= CreateAndWriteSignature( xDocHandler
);
301 CloseDocumentHandler(xDocHandler
);
306 bool XMLSignatureHelper::ReadAndVerifySignature( const com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
>& xInputStream
)
310 DBG_ASSERT(xInputStream
.is(), "input stream missing");
313 * prepare ParserInputSrouce
315 xml::sax::InputSource aParserInput
;
316 // aParserInput.sSystemId = ouName;
317 aParserInput
.aInputStream
= xInputStream
;
320 * get SAX parser component
322 uno::Reference
< lang::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
323 uno::Reference
< xml::sax::XParser
> xParser(
324 xMCF
->createInstanceWithContext(
325 rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser"), mxCtx
),
328 DBG_ASSERT( xParser
.is(), "Can't create parser" );
331 * create a signature reader
333 uno::Reference
< xml::sax::XDocumentHandler
> xHandler
334 = mpXSecController
->createSignatureReader( );
337 * create a signature listener
339 ImplXMLSignatureListener
* pSignatureListener
= new ImplXMLSignatureListener(
340 LINK( this, XMLSignatureHelper
, SignatureCreationResultListener
),
341 LINK( this, XMLSignatureHelper
, SignatureVerifyResultListener
),
342 LINK( this, XMLSignatureHelper
, StartVerifySignatureElement
) );
345 * configure the signature verify listener
347 //mpXSecController->setSignatureVerifyResultListener( pSignatureListener );
350 * setup the connection:
351 * Parser -> SignatureListener -> SignatureReader
353 pSignatureListener
->setNextHandler(xHandler
);
354 xParser
->setDocumentHandler( pSignatureListener
);
361 xParser
->parseStream( aParserInput
);
363 catch( xml::sax::SAXParseException
& )
367 catch( xml::sax::SAXException
& )
371 catch( com::sun::star::io::IOException
& )
375 catch( uno::Exception
& )
381 * clear up the connection
383 pSignatureListener
->setNextHandler( NULL
);
386 * clear up the signature verify listener
388 //mpXSecController->setSignatureVerifyResultListener( NULL );
391 * release the signature reader
393 mpXSecController
->releaseSignatureReader( );
398 SignatureInformation
XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId
) const
400 return mpXSecController
->getSignatureInformation( nSecurityId
);
403 SignatureInformations
XMLSignatureHelper::GetSignatureInformations() const
405 return mpXSecController
->getSignatureInformations();
408 uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
> XMLSignatureHelper::GetSecurityEnvironment()
410 return (mxSecurityContext
.is()?(mxSecurityContext
->getSecurityEnvironment()): uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
>());
413 uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
> XMLSignatureHelper::GetSecurityEnvironmentByIndex(sal_Int32 nId
)
415 return (mxSecurityContext
.is()?(mxSecurityContext
->getSecurityEnvironmentByIndex(nId
)): uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
>());
418 sal_Int32
XMLSignatureHelper::GetSecurityEnvironmentNumber()
420 return (mxSecurityContext
.is()?(mxSecurityContext
->getSecurityEnvironmentNumber()): 0);
425 void XMLSignatureHelper::createSecurityContext( rtl::OUString tokenPath )
427 if ( !mxSEInitializer.is() )
428 ImplCreateSEInitializer();
430 mxSecurityContext = mxSEInitializer->createSecurityContext(tokenPath);
433 void XMLSignatureHelper::freeSecurityContext()
435 if ( !mxSEInitializer.is() )
436 ImplCreateSEInitializer();
438 mxSEInitializer->freeSecurityContext( mxSecurityContext );
442 IMPL_LINK( XMLSignatureHelper
, SignatureCreationResultListener
, XMLSignatureCreationResult
*, pResult
)
444 maCreationResults
.insert( maCreationResults
.begin() + maCreationResults
.size(), *pResult
);
445 if ( pResult
->nSignatureCreationResult
!= com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
)
450 IMPL_LINK( XMLSignatureHelper
, SignatureVerifyResultListener
, XMLSignatureVerifyResult
*, pResult
)
452 maVerifyResults
.insert( maVerifyResults
.begin() + maVerifyResults
.size(), *pResult
);
453 if ( pResult
->nSignatureVerifyResult
!= com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
)
458 IMPL_LINK( XMLSignatureHelper
, StartVerifySignatureElement
, const uno::Reference
< com::sun::star::xml::sax::XAttributeList
>*, pAttrs
)
460 if ( !maStartVerifySignatureHdl
.IsSet() || maStartVerifySignatureHdl
.Call( (void*)pAttrs
) )
462 sal_Int32 nSignatureId
= mpXSecController
->getNewSecurityId();
463 mpXSecController
->addSignature( nSignatureId
);