1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlsignaturehelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
34 #include <xmlsecurity/xmlsignaturehelper.hxx>
35 #include <xmlsecurity/documentsignaturehelper.hxx>
36 #include <xsecctl.hxx>
38 #include <xmlsignaturehelper2.hxx>
40 #include <tools/stream.hxx>
41 #include <tools/debug.hxx>
43 #include <xmloff/attrlist.hxx>
45 #include <com/sun/star/io/XOutputStream.hpp>
46 #include <com/sun/star/io/XInputStream.hpp>
47 #include <com/sun/star/io/XActiveDataSource.hpp>
48 #include <com/sun/star/lang/XComponent.hpp>
49 #include <com/sun/star/security/SerialNumberAdapter.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <tools/date.hxx>
53 #include <tools/time.hxx>
55 //MM : search for the default profile
56 //#include <unotools/streamhelper.hxx>
59 /* SEInitializer component */
60 #define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer"
62 #define TAG_DOCUMENTSIGNATURES "document-signatures"
63 #define NS_DOCUMENTSIGNATURES "http://openoffice.org/2004/documentsignatures"
64 #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::uno
;
69 XMLSignatureHelper::XMLSignatureHelper( const uno::Reference
< uno::XComponentContext
>& rxCtx
)
70 : mxCtx(rxCtx
), mbODFPre1_2(false)
72 mpXSecController
= new XSecController(rxCtx
);
73 mxSecurityController
= mpXSecController
;
77 XMLSignatureHelper::~XMLSignatureHelper()
79 if ( mxSEInitializer
.is() && mxSecurityContext
.is() )
80 mxSEInitializer
->freeSecurityContext( mxSecurityContext
);
83 bool XMLSignatureHelper::Init( const rtl::OUString
& rTokenPath
)
85 DBG_ASSERT( !mxSEInitializer
.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" );
86 DBG_ASSERT( !mxSecurityContext
.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" );
88 ImplCreateSEInitializer();
90 if ( mxSEInitializer
.is() )
91 mxSecurityContext
= mxSEInitializer
->createSecurityContext( rTokenPath
);
93 return mxSecurityContext
.is();
96 void XMLSignatureHelper::ImplCreateSEInitializer()
98 rtl::OUString
sSEInitializer(rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT
));
99 uno::Reference
< lang::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
100 mxSEInitializer
= uno::Reference
< com::sun::star::xml::crypto::XSEInitializer
> (
101 xMCF
->createInstanceWithContext( sSEInitializer
, mxCtx
), uno::UNO_QUERY
);
104 void XMLSignatureHelper::SetUriBinding( com::sun::star::uno::Reference
< com::sun::star::xml::crypto::XUriBinding
>& rxUriBinding
)
106 mxUriBinding
= rxUriBinding
;
109 com::sun::star::uno::Reference
< com::sun::star::xml::crypto::XUriBinding
> XMLSignatureHelper::GetUriBinding() const
114 void XMLSignatureHelper::SetStorage(
115 const Reference
< css::embed::XStorage
>& rxStorage
,
116 ::rtl::OUString sODFVersion
)
118 DBG_ASSERT( !mxUriBinding
.is(), "SetStorage - UriBinding already set!" );
119 mxUriBinding
= new UriBindingHelper( rxStorage
);
120 DBG_ASSERT(rxStorage
.is(), "SetStorage - empty storage!");
121 mbODFPre1_2
= DocumentSignatureHelper::isODFPre_1_2(sODFVersion
);
125 void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link
& rLink
)
127 maStartVerifySignatureHdl
= rLink
;
131 void XMLSignatureHelper::StartMission()
133 if ( !mxUriBinding
.is() )
134 mxUriBinding
= new UriBindingHelper();
136 mpXSecController
->startMission( mxUriBinding
, mxSecurityContext
);
139 void XMLSignatureHelper::EndMission()
141 mpXSecController
->endMission();
144 sal_Int32
XMLSignatureHelper::GetNewSecurityId()
146 return mpXSecController
->getNewSecurityId();
149 void XMLSignatureHelper::SetX509Certificate(
150 sal_Int32 nSecurityId
,
151 const rtl::OUString
& ouX509IssuerName
,
152 const rtl::OUString
& ouX509SerialNumber
,
153 const rtl::OUString
& ouX509Cert
)
155 mpXSecController
->setX509Certificate(
162 void XMLSignatureHelper::SetX509Certificate(
163 sal_Int32 nSecurityId
,
164 sal_Int32 nSecurityEnvironmentIndex
,
165 const rtl::OUString
& ouX509IssuerName
,
166 const rtl::OUString
& ouX509SerialNumber
,
167 const rtl::OUString
& ouX509Cert
)
169 mpXSecController
->setX509Certificate(
171 nSecurityEnvironmentIndex
,
177 void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId
, const Date
& rDate
, const Time
& rTime
)
180 rtl::OUString aDate = String::CreateFromInt32( rDate.GetDate() );
181 rtl::OUString aTime = String::CreateFromInt32( rTime.GetTime() );
182 mpXSecController->setDateTime( nSecurityId, aDate, aTime );
184 ::com::sun::star::util::DateTime stDateTime
;
185 stDateTime
.HundredthSeconds
= (::sal_uInt16
)rTime
.Get100Sec();
186 stDateTime
.Seconds
= (::sal_uInt16
)rTime
.GetSec();
187 stDateTime
.Minutes
= (::sal_uInt16
)rTime
.GetMin();
188 stDateTime
.Hours
= (::sal_uInt16
)rTime
.GetHour();
189 stDateTime
.Day
= (::sal_uInt16
)rDate
.GetDay();
190 stDateTime
.Month
= (::sal_uInt16
)rDate
.GetMonth();
191 stDateTime
.Year
= (::sal_uInt16
)rDate
.GetYear();
192 mpXSecController
->setDate( nSecurityId
, stDateTime
);
195 void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId
, const rtl::OUString
& uri
, const rtl::OUString
& objectURL
, sal_Bool bBinary
)
197 mpXSecController
->signAStream( nSecurityId
, uri
, objectURL
, bBinary
);
201 uno::Reference
<xml::sax::XDocumentHandler
> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
202 const com::sun::star::uno::Reference
< com::sun::star::io::XOutputStream
>& xOutputStream
)
205 * get SAX writer component
207 uno::Reference
< lang::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
208 uno::Reference
< io::XActiveDataSource
> xSaxWriter(
209 xMCF
->createInstanceWithContext(rtl::OUString::createFromAscii(
210 "com.sun.star.xml.sax.Writer"), mxCtx
), uno::UNO_QUERY
);
212 DBG_ASSERT( xSaxWriter
.is(), "can't instantiate XML writer" );
215 * connect XML writer to output stream
217 xSaxWriter
->setOutputStream( xOutputStream
);
220 * prepare document handler
222 uno::Reference
<xml::sax::XDocumentHandler
>
223 xDocHandler( xSaxWriter
,uno::UNO_QUERY
);
226 * write the xml context for signatures
228 rtl::OUString
tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES
));
230 SvXMLAttributeList
*pAttributeList
= new SvXMLAttributeList();
231 rtl::OUString sNamespace
;
233 sNamespace
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES
));
235 sNamespace
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES_ODF_1_2
));
237 pAttributeList
->AddAttribute(
238 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS
)),
241 xDocHandler
->startDocument();
242 xDocHandler
->startElement(
244 uno::Reference
< com::sun::star::xml::sax::XAttributeList
> (pAttributeList
));
249 void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference
<xml::sax::XDocumentHandler
>& xDocumentHandler
)
251 rtl::OUString
tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES
));
252 xDocumentHandler
->endElement( tag_AllSignatures
);
253 xDocumentHandler
->endDocument();
256 void XMLSignatureHelper::ExportSignature(
257 const uno::Reference
< xml::sax::XDocumentHandler
>& xDocumentHandler
,
258 const SignatureInformation
& signatureInfo
)
260 mpXSecController
->exportSignature(xDocumentHandler
, signatureInfo
);
263 bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference
< xml::sax::XDocumentHandler
>& xDocumentHandler
)
268 * create a signature listener
271 ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
272 LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
273 LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
274 LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
277 * configure the signature creation listener
279 //mpXSecController->setSignatureCreationResultListener( pSignatureListener );
284 if ( !mpXSecController
->WriteSignature( xDocumentHandler
) )
290 * clear up the signature creation listener
292 //mpXSecController->setSignatureCreationResultListener( NULL );
297 bool XMLSignatureHelper::CreateAndWriteSignature( const com::sun::star::uno::Reference
< com::sun::star::io::XOutputStream
>& xOutputStream
)
299 uno::Reference
<xml::sax::XDocumentHandler
> xDocHandler
300 = CreateDocumentHandlerWithHeader(xOutputStream
);
302 bool rc
= CreateAndWriteSignature( xDocHandler
);
304 CloseDocumentHandler(xDocHandler
);
309 bool XMLSignatureHelper::ReadAndVerifySignature( const com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
>& xInputStream
)
313 DBG_ASSERT(xInputStream
.is(), "input stream missing");
316 * prepare ParserInputSrouce
318 xml::sax::InputSource aParserInput
;
319 // aParserInput.sSystemId = ouName;
320 aParserInput
.aInputStream
= xInputStream
;
323 * get SAX parser component
325 uno::Reference
< lang::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
326 uno::Reference
< xml::sax::XParser
> xParser(
327 xMCF
->createInstanceWithContext(
328 rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser"), mxCtx
),
331 DBG_ASSERT( xParser
.is(), "Can't create parser" );
334 * create a signature reader
336 uno::Reference
< xml::sax::XDocumentHandler
> xHandler
337 = mpXSecController
->createSignatureReader( );
340 * create a signature listener
342 ImplXMLSignatureListener
* pSignatureListener
= new ImplXMLSignatureListener(
343 LINK( this, XMLSignatureHelper
, SignatureCreationResultListener
),
344 LINK( this, XMLSignatureHelper
, SignatureVerifyResultListener
),
345 LINK( this, XMLSignatureHelper
, StartVerifySignatureElement
) );
348 * configure the signature verify listener
350 //mpXSecController->setSignatureVerifyResultListener( pSignatureListener );
353 * setup the connection:
354 * Parser -> SignatureListener -> SignatureReader
356 pSignatureListener
->setNextHandler(xHandler
);
357 xParser
->setDocumentHandler( pSignatureListener
);
364 xParser
->parseStream( aParserInput
);
366 catch( xml::sax::SAXParseException
& )
370 catch( xml::sax::SAXException
& )
374 catch( com::sun::star::io::IOException
& )
378 catch( uno::Exception
& )
384 * clear up the connection
386 pSignatureListener
->setNextHandler( NULL
);
389 * clear up the signature verify listener
391 //mpXSecController->setSignatureVerifyResultListener( NULL );
394 * release the signature reader
396 mpXSecController
->releaseSignatureReader( );
401 SignatureInformation
XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId
) const
403 return mpXSecController
->getSignatureInformation( nSecurityId
);
406 SignatureInformations
XMLSignatureHelper::GetSignatureInformations() const
408 return mpXSecController
->getSignatureInformations();
411 uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
> XMLSignatureHelper::GetSecurityEnvironment()
413 return (mxSecurityContext
.is()?(mxSecurityContext
->getSecurityEnvironment()): uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
>());
416 uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
> XMLSignatureHelper::GetSecurityEnvironmentByIndex(sal_Int32 nId
)
418 return (mxSecurityContext
.is()?(mxSecurityContext
->getSecurityEnvironmentByIndex(nId
)): uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
>());
421 sal_Int32
XMLSignatureHelper::GetSecurityEnvironmentNumber()
423 return (mxSecurityContext
.is()?(mxSecurityContext
->getSecurityEnvironmentNumber()): 0);
428 void XMLSignatureHelper::createSecurityContext( rtl::OUString tokenPath )
430 if ( !mxSEInitializer.is() )
431 ImplCreateSEInitializer();
433 mxSecurityContext = mxSEInitializer->createSecurityContext(tokenPath);
436 void XMLSignatureHelper::freeSecurityContext()
438 if ( !mxSEInitializer.is() )
439 ImplCreateSEInitializer();
441 mxSEInitializer->freeSecurityContext( mxSecurityContext );
445 IMPL_LINK( XMLSignatureHelper
, SignatureCreationResultListener
, XMLSignatureCreationResult
*, pResult
)
447 maCreationResults
.insert( maCreationResults
.begin() + maCreationResults
.size(), *pResult
);
448 if ( pResult
->nSignatureCreationResult
!= com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
)
453 IMPL_LINK( XMLSignatureHelper
, SignatureVerifyResultListener
, XMLSignatureVerifyResult
*, pResult
)
455 maVerifyResults
.insert( maVerifyResults
.begin() + maVerifyResults
.size(), *pResult
);
456 if ( pResult
->nSignatureVerifyResult
!= com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
)
461 IMPL_LINK( XMLSignatureHelper
, StartVerifySignatureElement
, const uno::Reference
< com::sun::star::xml::sax::XAttributeList
>*, pAttrs
)
463 if ( !maStartVerifySignatureHdl
.IsSet() || maStartVerifySignatureHdl
.Call( (void*)pAttrs
) )
465 sal_Int32 nSignatureId
= mpXSecController
->getNewSecurityId();
466 mpXSecController
->addSignature( nSignatureId
);