xref: /trunk/main/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.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 #include <sal/config.h>
31 #include <rtl/uuid.h>
32 #include "xmlsignature_nssimpl.hxx"
33 
34 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
35 #include "xmldocumentwrapper_xmlsecimpl.hxx"
36 #endif
37 
38 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
39 #include "xmlelementwrapper_xmlsecimpl.hxx"
40 #endif
41 
42 #ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_
43 #include "securityenvironment_nssimpl.hxx"
44 #endif
45 
46 #ifndef _XMLSECURITYCONTEXT_NSSIMPL_HXX_
47 #include "xmlsecuritycontext_nssimpl.hxx"
48 #endif
49 #include "xmlstreamio.hxx"
50 #include "errorcallback.hxx"
51 
52 #include <sal/types.h>
53 //For reasons that escape me, this is what xmlsec does when size_t is not 4
54 #if SAL_TYPES_SIZEOFPOINTER != 4
55 #    define XMLSEC_NO_SIZE_T
56 #endif
57 #include "xmlsec/xmlsec.h"
58 #include "xmlsec/xmldsig.h"
59 #include "xmlsec/crypto.h"
60 
61 using namespace ::com::sun::star::uno ;
62 using namespace ::com::sun::star::lang ;
63 using ::com::sun::star::lang::XMultiServiceFactory ;
64 using ::com::sun::star::lang::XSingleServiceFactory ;
65 using ::rtl::OUString ;
66 
67 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
68 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
69 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
70 using ::com::sun::star::xml::crypto::XXMLSignature ;
71 using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ;
72 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
73 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
74 using ::com::sun::star::xml::crypto::XUriBinding ;
75 using ::com::sun::star::xml::crypto::XMLSignatureException ;
76 
77 XMLSignature_NssImpl :: XMLSignature_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
78 }
79 
80 XMLSignature_NssImpl :: ~XMLSignature_NssImpl() {
81 }
82 
83 /* XXMLSignature */
84 Reference< XXMLSignatureTemplate >
85 SAL_CALL XMLSignature_NssImpl :: generate(
86     const Reference< XXMLSignatureTemplate >& aTemplate ,
87     const Reference< XSecurityEnvironment >& aEnvironment
88 ) throw( com::sun::star::xml::crypto::XMLSignatureException,
89          com::sun::star::uno::SecurityException )
90 {
91     xmlSecKeysMngrPtr pMngr = NULL ;
92     xmlSecDSigCtxPtr pDsigCtx = NULL ;
93     xmlNodePtr pNode = NULL ;
94 
95     if( !aTemplate.is() )
96         throw RuntimeException() ;
97 
98     if( !aEnvironment.is() )
99         throw RuntimeException() ;
100 
101     //Get the xml node
102     Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
103     if( !xElement.is() ) {
104         throw RuntimeException() ;
105     }
106 
107     Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
108     if( !xNodTunnel.is() ) {
109         throw RuntimeException() ;
110     }
111 
112     XMLElementWrapper_XmlSecImpl* pElement =
113         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
114             sal::static_int_cast<sal_uIntPtr>(
115                 xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
116     if( pElement == NULL ) {
117         throw RuntimeException() ;
118     }
119 
120     pNode = pElement->getNativeElement() ;
121 
122     //Get the stream/URI binding
123     Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
124     if( xUriBinding.is() ) {
125         //Register the stream input callbacks into libxml2
126         if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
127             throw RuntimeException() ;
128     }
129 
130     //Get Keys Manager
131     Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
132     if( !xSecTunnel.is() ) {
133          throw RuntimeException() ;
134     }
135 
136 #if 0 //i39448 : the key manager should be retrieved from SecurityEnvironment, instead of SecurityContext
137     XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
138     if( pSecCtxt == NULL )
139         throw RuntimeException() ;
140 #endif
141 
142     SecurityEnvironment_NssImpl* pSecEnv =
143         reinterpret_cast<SecurityEnvironment_NssImpl*>(
144             sal::static_int_cast<sal_uIntPtr>(
145                 xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
146     if( pSecEnv == NULL )
147         throw RuntimeException() ;
148 
149     setErrorRecorder();
150 
151     pMngr = pSecEnv->createKeysManager() ; //i39448
152     if( !pMngr ) {
153         throw RuntimeException() ;
154     }
155 
156     //Create Signature context
157     pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
158     if( pDsigCtx == NULL )
159     {
160         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
161         //throw XMLSignatureException() ;
162         clearErrorRecorder();
163         return aTemplate;
164     }
165 
166     //Sign the template
167     if( xmlSecDSigCtxSign( pDsigCtx , pNode ) == 0 )
168     {
169         if (pDsigCtx->status == xmlSecDSigStatusSucceeded)
170             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
171         else
172             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
173     }
174     else
175     {
176         aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
177     }
178 
179 
180     xmlSecDSigCtxDestroy( pDsigCtx ) ;
181     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
182 
183     //Unregistered the stream/URI binding
184     if( xUriBinding.is() )
185         xmlUnregisterStreamInputCallbacks() ;
186 
187     clearErrorRecorder();
188     return aTemplate ;
189 }
190 
191 /* XXMLSignature */
192 Reference< XXMLSignatureTemplate >
193 SAL_CALL XMLSignature_NssImpl :: validate(
194     const Reference< XXMLSignatureTemplate >& aTemplate ,
195     const Reference< XXMLSecurityContext >& aSecurityCtx
196 ) throw( com::sun::star::uno::RuntimeException,
197          com::sun::star::uno::SecurityException,
198          com::sun::star::xml::crypto::XMLSignatureException ) {
199     xmlSecKeysMngrPtr pMngr = NULL ;
200     xmlSecDSigCtxPtr pDsigCtx = NULL ;
201     xmlNodePtr pNode = NULL ;
202     //sal_Bool valid ;
203 
204     if( !aTemplate.is() )
205         throw RuntimeException() ;
206 
207     if( !aSecurityCtx.is() )
208         throw RuntimeException() ;
209 
210     //Get the xml node
211     Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
212     if( !xElement.is() )
213         throw RuntimeException() ;
214 
215     Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
216     if( !xNodTunnel.is() ) {
217         throw RuntimeException() ;
218     }
219 
220     XMLElementWrapper_XmlSecImpl* pElement =
221         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
222             sal::static_int_cast<sal_uIntPtr>(
223                 xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
224     if( pElement == NULL )
225         throw RuntimeException() ;
226 
227     pNode = pElement->getNativeElement() ;
228 
229     //Get the stream/URI binding
230     Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
231     if( xUriBinding.is() ) {
232         //Register the stream input callbacks into libxml2
233         if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
234             throw RuntimeException() ;
235     }
236 
237     setErrorRecorder();
238 
239     sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
240     sal_Int32 i;
241 
242     for (i=0; i<nSecurityEnvironment; ++i)
243     {
244         Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
245 
246         //Get Keys Manager
247         Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
248         if( !xSecTunnel.is() ) {
249              throw RuntimeException() ;
250         }
251 
252         SecurityEnvironment_NssImpl* pSecEnv =
253             reinterpret_cast<SecurityEnvironment_NssImpl*>(
254                 sal::static_int_cast<sal_uIntPtr>(
255                     xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
256         if( pSecEnv == NULL )
257             throw RuntimeException() ;
258 
259         pMngr = pSecEnv->createKeysManager() ; //i39448
260         if( !pMngr ) {
261             throw RuntimeException() ;
262         }
263 
264         //Create Signature context
265         pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
266         if( pDsigCtx == NULL )
267         {
268             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
269             //throw XMLSignatureException() ;
270             clearErrorRecorder();
271             return aTemplate;
272         }
273 
274         //Verify signature
275         int rs = xmlSecDSigCtxVerify( pDsigCtx , pNode );
276 
277 
278         if (rs == 0 &&
279             pDsigCtx->status == xmlSecDSigStatusSucceeded)
280         {
281             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
282             xmlSecDSigCtxDestroy( pDsigCtx ) ;
283             pSecEnv->destroyKeysManager( pMngr );
284             break;
285         }
286         else
287         {
288             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
289         }
290         xmlSecDSigCtxDestroy( pDsigCtx ) ;
291         pSecEnv->destroyKeysManager( pMngr );
292     }
293 
294 
295 
296     //Unregistered the stream/URI binding
297     if( xUriBinding.is() )
298         xmlUnregisterStreamInputCallbacks() ;
299 
300     //return valid ;
301     clearErrorRecorder();
302     return aTemplate;
303 }
304 
305 /* XInitialization */
306 void SAL_CALL XMLSignature_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
307     // TBD
308 } ;
309 
310 /* XServiceInfo */
311 OUString SAL_CALL XMLSignature_NssImpl :: getImplementationName() throw( RuntimeException ) {
312     return impl_getImplementationName() ;
313 }
314 
315 /* XServiceInfo */
316 sal_Bool SAL_CALL XMLSignature_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
317     Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
318     const OUString* pArray = seqServiceNames.getConstArray() ;
319     for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
320         if( *( pArray + i ) == serviceName )
321             return sal_True ;
322     }
323     return sal_False ;
324 }
325 
326 /* XServiceInfo */
327 Sequence< OUString > SAL_CALL XMLSignature_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
328     return impl_getSupportedServiceNames() ;
329 }
330 
331 //Helper for XServiceInfo
332 Sequence< OUString > XMLSignature_NssImpl :: impl_getSupportedServiceNames() {
333     ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
334     Sequence< OUString > seqServiceNames( 1 ) ;
335     seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignature" ) ;
336     return seqServiceNames ;
337 }
338 
339 OUString XMLSignature_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
340     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl" ) ;
341 }
342 
343 //Helper for registry
344 Reference< XInterface > SAL_CALL XMLSignature_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
345     return Reference< XInterface >( *new XMLSignature_NssImpl( aServiceManager ) ) ;
346 }
347 
348 Reference< XSingleServiceFactory > XMLSignature_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
349     //Reference< XSingleServiceFactory > xFactory ;
350     //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
351     //return xFactory ;
352     return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
353 }
354 
355