Update ooo320-m1
[ooovba.git] / xmlsecurity / source / xmlsec / nss / xmlencryption_nssimpl.cxx
blob8830dce5f19aa9e20014353da8812c46d61ada08
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlencryption_nssimpl.cxx,v $
10 * $Revision: 1.10 $
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>
34 #include <rtl/uuid.h>
35 #include "xmlencryption_nssimpl.hxx"
37 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
38 #include "xmldocumentwrapper_xmlsecimpl.hxx"
39 #endif
41 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
42 #include "xmlelementwrapper_xmlsecimpl.hxx"
43 #endif
45 #ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_
46 #include "securityenvironment_nssimpl.hxx"
47 #endif
48 #include "errorcallback.hxx"
50 #include <sal/types.h>
51 //For reasons that escape me, this is what xmlsec does when size_t is not 4
52 #if SAL_TYPES_SIZEOFPOINTER != 4
53 # define XMLSEC_NO_SIZE_T
54 #endif
55 #include "xmlsec/xmlsec.h"
56 #include "xmlsec/xmltree.h"
57 #include "xmlsec/xmlenc.h"
58 #include "xmlsec/crypto.h"
60 #ifdef UNX
61 #define stricmp strcasecmp
62 #endif
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::XXMLEncryption ;
74 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ;
75 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
76 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
77 using ::com::sun::star::xml::crypto::XMLEncryptionException ;
79 XMLEncryption_NssImpl :: XMLEncryption_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
82 XMLEncryption_NssImpl :: ~XMLEncryption_NssImpl() {
85 /* XXMLEncryption */
86 Reference< XXMLEncryptionTemplate >
87 SAL_CALL XMLEncryption_NssImpl :: encrypt(
88 const Reference< XXMLEncryptionTemplate >& aTemplate ,
89 const Reference< XSecurityEnvironment >& aEnvironment
90 ) throw( com::sun::star::xml::crypto::XMLEncryptionException,
91 com::sun::star::uno::SecurityException )
93 xmlSecKeysMngrPtr pMngr = NULL ;
94 xmlSecEncCtxPtr pEncCtx = NULL ;
95 xmlNodePtr pEncryptedData = NULL ;
96 xmlNodePtr pContent = NULL ;
98 if( !aTemplate.is() )
99 throw RuntimeException() ;
101 if( !aEnvironment.is() )
102 throw RuntimeException() ;
104 //Get Keys Manager
105 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
106 if( !xSecTunnel.is() ) {
107 throw RuntimeException() ;
110 #if 0
111 XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
112 if( pSecCtxt == NULL )
113 throw RuntimeException() ;
114 #endif
116 SecurityEnvironment_NssImpl* pSecEnv =
117 reinterpret_cast<SecurityEnvironment_NssImpl*>(
118 sal::static_int_cast<sal_uIntPtr>(xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ;
119 if( pSecEnv == NULL )
120 throw RuntimeException() ;
122 //Get the encryption template
123 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
124 if( !xTemplate.is() ) {
125 throw RuntimeException() ;
128 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
129 if( !xTplTunnel.is() ) {
130 throw RuntimeException() ;
133 XMLElementWrapper_XmlSecImpl* pTemplate =
134 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
135 sal::static_int_cast<sal_uIntPtr>(
136 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
137 if( pTemplate == NULL ) {
138 throw RuntimeException() ;
141 //MM : Get the element to be encrypted
142 Reference< XXMLElementWrapper > xTarget = aTemplate->getTarget() ;
143 if( !xTarget.is() ) {
144 throw XMLEncryptionException() ;
147 Reference< XUnoTunnel > xTgtTunnel( xTarget , UNO_QUERY ) ;
148 if( !xTgtTunnel.is() ) {
149 throw XMLEncryptionException() ;
152 XMLElementWrapper_XmlSecImpl* pTarget =
153 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
154 sal::static_int_cast<sal_uIntPtr>(
155 xTgtTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
156 if( pTarget == NULL ) {
157 throw RuntimeException() ;
160 pContent = pTarget->getNativeElement() ;
161 //MM : end
163 if( pContent == NULL ) {
164 throw XMLEncryptionException() ;
167 /* MM : remove the following 2 lines
168 xmlUnlinkNode(pContent);
169 xmlAddNextSibling(pEncryptedData, pContent);
172 //remember the position of the element to be signed
173 sal_Bool isParentRef = sal_True;
174 xmlNodePtr pParent = pEncryptedData->parent;
175 xmlNodePtr referenceNode;
177 if (pEncryptedData == pParent->children)
179 referenceNode = pParent;
181 else
183 referenceNode = pEncryptedData->prev;
184 isParentRef = sal_False;
187 setErrorRecorder( );
189 pMngr = pSecEnv->createKeysManager() ; //i39448
190 if( !pMngr ) {
191 throw RuntimeException() ;
194 //Create Encryption context
195 pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
196 if( pEncCtx == NULL )
198 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
199 //throw XMLEncryptionException() ;
200 clearErrorRecorder();
201 return aTemplate;
204 pEncryptedData = pTemplate->getNativeElement() ;
206 //Find the element to be encrypted.
207 /* MM : remove the old method to get the target element
208 //This element is wrapped in the CipherValue sub-element.
209 xmlNodePtr pCipherData = pEncryptedData->children;
210 while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData"))
212 pCipherData = pCipherData->next;
215 if( pCipherData == NULL ) {
216 xmlSecEncCtxDestroy( pEncCtx ) ;
217 throw XMLEncryptionException() ;
220 xmlNodePtr pCipherValue = pCipherData->children;
221 while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
223 pCipherValue = pCipherValue->next;
226 if( pCipherValue == NULL ) {
227 xmlSecEncCtxDestroy( pEncCtx ) ;
228 throw XMLEncryptionException() ;
231 pContent = pCipherValue->children;
234 //Encrypt the template
235 if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 )
237 xmlSecEncCtxDestroy( pEncCtx ) ;
238 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
240 //throw XMLEncryptionException() ;
241 clearErrorRecorder();
242 return aTemplate;
245 xmlSecEncCtxDestroy( pEncCtx ) ;
246 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
248 //get the new EncryptedData element
249 if (isParentRef)
251 pTemplate->setNativeElement(referenceNode->children) ;
253 else
255 pTemplate->setNativeElement(referenceNode->next);
258 return aTemplate ;
261 /* XXMLEncryption */
262 Reference< XXMLEncryptionTemplate >
263 SAL_CALL XMLEncryption_NssImpl :: decrypt(
264 const Reference< XXMLEncryptionTemplate >& aTemplate ,
265 const Reference< XXMLSecurityContext >& aSecurityCtx
266 ) throw( com::sun::star::xml::crypto::XMLEncryptionException ,
267 com::sun::star::uno::SecurityException) {
268 xmlSecKeysMngrPtr pMngr = NULL ;
269 xmlSecEncCtxPtr pEncCtx = NULL ;
270 xmlNodePtr pEncryptedData = NULL ;
272 if( !aTemplate.is() )
273 throw RuntimeException() ;
275 if( !aSecurityCtx.is() )
276 throw RuntimeException() ;
278 //Get the encryption template
279 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
280 if( !xTemplate.is() ) {
281 throw RuntimeException() ;
284 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
285 if( !xTplTunnel.is() ) {
286 throw RuntimeException() ;
289 XMLElementWrapper_XmlSecImpl* pTemplate =
290 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
291 sal::static_int_cast<sal_uIntPtr>(
292 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
293 if( pTemplate == NULL ) {
294 throw RuntimeException() ;
297 pEncryptedData = pTemplate->getNativeElement() ;
299 //remember the position of the element to be signed
300 sal_Bool isParentRef = sal_True;
301 xmlNodePtr pParent = pEncryptedData->parent;
302 xmlNodePtr referenceNode;
304 if (pEncryptedData == pParent->children)
306 referenceNode = pParent;
308 else
310 referenceNode = pEncryptedData->prev;
311 isParentRef = sal_False;
314 setErrorRecorder( );
316 sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
317 sal_Int32 i;
319 for (i=0; i<nSecurityEnvironment; ++i)
321 Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
323 //Get Keys Manager
324 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
325 if( !aEnvironment.is() ) {
326 throw RuntimeException() ;
329 SecurityEnvironment_NssImpl* pSecEnv =
330 reinterpret_cast<SecurityEnvironment_NssImpl*>(
331 sal::static_int_cast<sal_uIntPtr>(
332 xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
333 if( pSecEnv == NULL )
334 throw RuntimeException() ;
336 pMngr = pSecEnv->createKeysManager() ; //i39448
337 if( !pMngr ) {
338 throw RuntimeException() ;
341 //Create Encryption context
342 pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
343 if( pEncCtx == NULL )
345 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
346 //throw XMLEncryptionException() ;
347 clearErrorRecorder();
348 return aTemplate;
351 //Decrypt the template
352 if(!( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ))
354 //The decryption succeeds
356 //Destroy the encryption context
357 xmlSecEncCtxDestroy( pEncCtx ) ;
358 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
360 //get the decrypted element
361 XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
362 (referenceNode->children):(referenceNode->next));
364 //return ret;
365 aTemplate->setTemplate(ret);
366 break;
368 else
370 //The decryption fails, continue with the next security environment
371 xmlSecEncCtxDestroy( pEncCtx ) ;
372 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
376 clearErrorRecorder();
377 return aTemplate;
380 /* XInitialization */
381 void SAL_CALL XMLEncryption_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
382 // TBD
385 /* XServiceInfo */
386 OUString SAL_CALL XMLEncryption_NssImpl :: getImplementationName() throw( RuntimeException ) {
387 return impl_getImplementationName() ;
390 /* XServiceInfo */
391 sal_Bool SAL_CALL XMLEncryption_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
392 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
393 const OUString* pArray = seqServiceNames.getConstArray() ;
394 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
395 if( *( pArray + i ) == serviceName )
396 return sal_True ;
398 return sal_False ;
401 /* XServiceInfo */
402 Sequence< OUString > SAL_CALL XMLEncryption_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
403 return impl_getSupportedServiceNames() ;
406 //Helper for XServiceInfo
407 Sequence< OUString > XMLEncryption_NssImpl :: impl_getSupportedServiceNames() {
408 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
409 Sequence< OUString > seqServiceNames( 1 ) ;
410 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
411 return seqServiceNames ;
414 OUString XMLEncryption_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
415 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl" ) ;
418 //Helper for registry
419 Reference< XInterface > SAL_CALL XMLEncryption_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
420 return Reference< XInterface >( *new XMLEncryption_NssImpl( aServiceManager ) ) ;
423 Reference< XSingleServiceFactory > XMLEncryption_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
424 //Reference< XSingleServiceFactory > xFactory ;
425 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
426 //return xFactory ;
427 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;