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: xmlsignature_nssimpl.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"
33 #include <sal/config.h>
35 #include "xmlsignature_nssimpl.hxx"
37 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
38 #include "xmldocumentwrapper_xmlsecimpl.hxx"
41 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
42 #include "xmlelementwrapper_xmlsecimpl.hxx"
45 #ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_
46 #include "securityenvironment_nssimpl.hxx"
49 #ifndef _XMLSECURITYCONTEXT_NSSIMPL_HXX_
50 #include "xmlsecuritycontext_nssimpl.hxx"
52 #include "xmlstreamio.hxx"
53 #include "errorcallback.hxx"
55 #include <sal/types.h>
56 //For reasons that escape me, this is what xmlsec does when size_t is not 4
57 #if SAL_TYPES_SIZEOFPOINTER != 4
58 # define XMLSEC_NO_SIZE_T
60 #include "xmlsec/xmlsec.h"
61 #include "xmlsec/xmldsig.h"
62 #include "xmlsec/crypto.h"
64 using namespace ::com::sun::star::uno
;
65 using namespace ::com::sun::star::lang
;
66 using ::com::sun::star::lang::XMultiServiceFactory
;
67 using ::com::sun::star::lang::XSingleServiceFactory
;
68 using ::rtl::OUString
;
70 using ::com::sun::star::xml::wrapper::XXMLElementWrapper
;
71 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper
;
72 using ::com::sun::star::xml::crypto::XSecurityEnvironment
;
73 using ::com::sun::star::xml::crypto::XXMLSignature
;
74 using ::com::sun::star::xml::crypto::XXMLSignatureTemplate
;
75 using ::com::sun::star::xml::crypto::XSecurityEnvironment
;
76 using ::com::sun::star::xml::crypto::XXMLSecurityContext
;
77 using ::com::sun::star::xml::crypto::XUriBinding
;
78 using ::com::sun::star::xml::crypto::XMLSignatureException
;
80 XMLSignature_NssImpl :: XMLSignature_NssImpl( const Reference
< XMultiServiceFactory
>& aFactory
) : m_xServiceManager( aFactory
) {
83 XMLSignature_NssImpl :: ~XMLSignature_NssImpl() {
87 Reference
< XXMLSignatureTemplate
>
88 SAL_CALL
XMLSignature_NssImpl :: generate(
89 const Reference
< XXMLSignatureTemplate
>& aTemplate
,
90 const Reference
< XSecurityEnvironment
>& aEnvironment
91 ) throw( com::sun::star::xml::crypto::XMLSignatureException
,
92 com::sun::star::uno::SecurityException
)
94 xmlSecKeysMngrPtr pMngr
= NULL
;
95 xmlSecDSigCtxPtr pDsigCtx
= NULL
;
96 xmlNodePtr pNode
= NULL
;
99 throw RuntimeException() ;
101 if( !aEnvironment
.is() )
102 throw RuntimeException() ;
105 Reference
< XXMLElementWrapper
> xElement
= aTemplate
->getTemplate() ;
106 if( !xElement
.is() ) {
107 throw RuntimeException() ;
110 Reference
< XUnoTunnel
> xNodTunnel( xElement
, UNO_QUERY
) ;
111 if( !xNodTunnel
.is() ) {
112 throw RuntimeException() ;
115 XMLElementWrapper_XmlSecImpl
* pElement
=
116 reinterpret_cast<XMLElementWrapper_XmlSecImpl
*>(
117 sal::static_int_cast
<sal_uIntPtr
>(
118 xNodTunnel
->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
119 if( pElement
== NULL
) {
120 throw RuntimeException() ;
123 pNode
= pElement
->getNativeElement() ;
125 //Get the stream/URI binding
126 Reference
< XUriBinding
> xUriBinding
= aTemplate
->getBinding() ;
127 if( xUriBinding
.is() ) {
128 //Register the stream input callbacks into libxml2
129 if( xmlRegisterStreamInputCallbacks( xUriBinding
) < 0 )
130 throw RuntimeException() ;
134 Reference
< XUnoTunnel
> xSecTunnel( aEnvironment
, UNO_QUERY
) ;
135 if( !xSecTunnel
.is() ) {
136 throw RuntimeException() ;
139 #if 0 //i39448 : the key manager should be retrieved from SecurityEnvironment, instead of SecurityContext
140 XMLSecurityContext_NssImpl
* pSecCtxt
= ( XMLSecurityContext_NssImpl
* )xSecTunnel
->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
141 if( pSecCtxt
== NULL
)
142 throw RuntimeException() ;
145 SecurityEnvironment_NssImpl
* pSecEnv
=
146 reinterpret_cast<SecurityEnvironment_NssImpl
*>(
147 sal::static_int_cast
<sal_uIntPtr
>(
148 xSecTunnel
->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
149 if( pSecEnv
== NULL
)
150 throw RuntimeException() ;
154 pMngr
= pSecEnv
->createKeysManager() ; //i39448
156 throw RuntimeException() ;
159 //Create Signature context
160 pDsigCtx
= xmlSecDSigCtxCreate( pMngr
) ;
161 if( pDsigCtx
== NULL
)
163 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
164 //throw XMLSignatureException() ;
165 clearErrorRecorder();
170 if( xmlSecDSigCtxSign( pDsigCtx
, pNode
) == 0 )
172 if (pDsigCtx
->status
== xmlSecDSigStatusSucceeded
)
173 aTemplate
->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
175 aTemplate
->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
179 aTemplate
->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
183 xmlSecDSigCtxDestroy( pDsigCtx
) ;
184 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
186 //Unregistered the stream/URI binding
187 if( xUriBinding
.is() )
188 xmlUnregisterStreamInputCallbacks() ;
190 clearErrorRecorder();
195 Reference
< XXMLSignatureTemplate
>
196 SAL_CALL
XMLSignature_NssImpl :: validate(
197 const Reference
< XXMLSignatureTemplate
>& aTemplate
,
198 const Reference
< XXMLSecurityContext
>& aSecurityCtx
199 ) throw( com::sun::star::uno::RuntimeException
,
200 com::sun::star::uno::SecurityException
,
201 com::sun::star::xml::crypto::XMLSignatureException
) {
202 xmlSecKeysMngrPtr pMngr
= NULL
;
203 xmlSecDSigCtxPtr pDsigCtx
= NULL
;
204 xmlNodePtr pNode
= NULL
;
207 if( !aTemplate
.is() )
208 throw RuntimeException() ;
210 if( !aSecurityCtx
.is() )
211 throw RuntimeException() ;
214 Reference
< XXMLElementWrapper
> xElement
= aTemplate
->getTemplate() ;
216 throw RuntimeException() ;
218 Reference
< XUnoTunnel
> xNodTunnel( xElement
, UNO_QUERY
) ;
219 if( !xNodTunnel
.is() ) {
220 throw RuntimeException() ;
223 XMLElementWrapper_XmlSecImpl
* pElement
=
224 reinterpret_cast<XMLElementWrapper_XmlSecImpl
*>(
225 sal::static_int_cast
<sal_uIntPtr
>(
226 xNodTunnel
->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
227 if( pElement
== NULL
)
228 throw RuntimeException() ;
230 pNode
= pElement
->getNativeElement() ;
232 //Get the stream/URI binding
233 Reference
< XUriBinding
> xUriBinding
= aTemplate
->getBinding() ;
234 if( xUriBinding
.is() ) {
235 //Register the stream input callbacks into libxml2
236 if( xmlRegisterStreamInputCallbacks( xUriBinding
) < 0 )
237 throw RuntimeException() ;
242 sal_Int32 nSecurityEnvironment
= aSecurityCtx
->getSecurityEnvironmentNumber();
245 for (i
=0; i
<nSecurityEnvironment
; ++i
)
247 Reference
< XSecurityEnvironment
> aEnvironment
= aSecurityCtx
->getSecurityEnvironmentByIndex(i
);
250 Reference
< XUnoTunnel
> xSecTunnel( aEnvironment
, UNO_QUERY
) ;
251 if( !xSecTunnel
.is() ) {
252 throw RuntimeException() ;
255 SecurityEnvironment_NssImpl
* pSecEnv
=
256 reinterpret_cast<SecurityEnvironment_NssImpl
*>(
257 sal::static_int_cast
<sal_uIntPtr
>(
258 xSecTunnel
->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
259 if( pSecEnv
== NULL
)
260 throw RuntimeException() ;
262 pMngr
= pSecEnv
->createKeysManager() ; //i39448
264 throw RuntimeException() ;
267 //Create Signature context
268 pDsigCtx
= xmlSecDSigCtxCreate( pMngr
) ;
269 if( pDsigCtx
== NULL
)
271 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
272 //throw XMLSignatureException() ;
273 clearErrorRecorder();
278 int rs
= xmlSecDSigCtxVerify( pDsigCtx
, pNode
);
282 pDsigCtx
->status
== xmlSecDSigStatusSucceeded
)
284 aTemplate
->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
285 xmlSecDSigCtxDestroy( pDsigCtx
) ;
286 pSecEnv
->destroyKeysManager( pMngr
);
291 aTemplate
->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
293 xmlSecDSigCtxDestroy( pDsigCtx
) ;
294 pSecEnv
->destroyKeysManager( pMngr
);
299 //Unregistered the stream/URI binding
300 if( xUriBinding
.is() )
301 xmlUnregisterStreamInputCallbacks() ;
304 clearErrorRecorder();
308 /* XInitialization */
309 void SAL_CALL
XMLSignature_NssImpl :: initialize( const Sequence
< Any
>& /*aArguments*/ ) throw( Exception
, RuntimeException
) {
314 OUString SAL_CALL
XMLSignature_NssImpl :: getImplementationName() throw( RuntimeException
) {
315 return impl_getImplementationName() ;
319 sal_Bool SAL_CALL
XMLSignature_NssImpl :: supportsService( const OUString
& serviceName
) throw( RuntimeException
) {
320 Sequence
< OUString
> seqServiceNames
= getSupportedServiceNames() ;
321 const OUString
* pArray
= seqServiceNames
.getConstArray() ;
322 for( sal_Int32 i
= 0 ; i
< seqServiceNames
.getLength() ; i
++ ) {
323 if( *( pArray
+ i
) == serviceName
)
330 Sequence
< OUString
> SAL_CALL
XMLSignature_NssImpl :: getSupportedServiceNames() throw( RuntimeException
) {
331 return impl_getSupportedServiceNames() ;
334 //Helper for XServiceInfo
335 Sequence
< OUString
> XMLSignature_NssImpl :: impl_getSupportedServiceNames() {
336 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() ) ;
337 Sequence
< OUString
> seqServiceNames( 1 ) ;
338 seqServiceNames
.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignature" ) ;
339 return seqServiceNames
;
342 OUString
XMLSignature_NssImpl :: impl_getImplementationName() throw( RuntimeException
) {
343 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl" ) ;
346 //Helper for registry
347 Reference
< XInterface
> SAL_CALL
XMLSignature_NssImpl :: impl_createInstance( const Reference
< XMultiServiceFactory
>& aServiceManager
) throw( RuntimeException
) {
348 return Reference
< XInterface
>( *new XMLSignature_NssImpl( aServiceManager
) ) ;
351 Reference
< XSingleServiceFactory
> XMLSignature_NssImpl :: impl_createFactory( const Reference
< XMultiServiceFactory
>& aServiceManager
) {
352 //Reference< XSingleServiceFactory > xFactory ;
353 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
355 return ::cppu::createSingleFactory( aServiceManager
, impl_getImplementationName() , impl_createInstance
, impl_getSupportedServiceNames() ) ;