merged tag ooo/OOO330_m14
[LibreOffice.git] / xmlsecurity / source / xmlsec / mscrypt / xmlencryption_mscryptimpl.cxx
blobe30eabfb279e337ba6a5ba06fcbd829cb5448b80
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 <sal/config.h>
32 #include <rtl/uuid.h>
33 #include "xmlencryption_mscryptimpl.hxx"
35 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
36 #include "xmldocumentwrapper_xmlsecimpl.hxx"
37 #endif
39 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
40 #include "xmlelementwrapper_xmlsecimpl.hxx"
41 #endif
43 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
44 #include "securityenvironment_mscryptimpl.hxx"
45 #endif
46 #include "errorcallback.hxx"
48 #include "xmlsec/xmlsec.h"
49 #include "xmlsec/xmltree.h"
50 #include "xmlsec/xmlenc.h"
51 #include "xmlsec/crypto.h"
53 #ifdef UNX
54 #define stricmp strcasecmp
55 #endif
57 using namespace ::com::sun::star::uno ;
58 using namespace ::com::sun::star::lang ;
59 using ::com::sun::star::lang::XMultiServiceFactory ;
60 using ::com::sun::star::lang::XSingleServiceFactory ;
61 using ::rtl::OUString ;
63 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
64 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
65 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
66 using ::com::sun::star::xml::crypto::XXMLEncryption ;
67 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ;
68 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
69 using ::com::sun::star::xml::crypto::XMLEncryptionException ;
71 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
74 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() {
77 /* XXMLEncryption */
78 Reference< XXMLEncryptionTemplate >
79 SAL_CALL XMLEncryption_MSCryptImpl :: encrypt(
80 const Reference< XXMLEncryptionTemplate >& aTemplate ,
81 const Reference< XSecurityEnvironment >& aEnvironment
82 ) throw( com::sun::star::xml::crypto::XMLEncryptionException,
83 com::sun::star::uno::SecurityException )
85 xmlSecKeysMngrPtr pMngr = NULL ;
86 xmlSecEncCtxPtr pEncCtx = NULL ;
87 xmlNodePtr pEncryptedData = NULL ;
88 xmlNodePtr pContent = NULL ;
90 if( !aTemplate.is() )
91 throw RuntimeException() ;
93 if( !aEnvironment.is() )
94 throw RuntimeException() ;
96 //Get Keys Manager
97 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
98 if( !xSecTunnel.is() ) {
99 throw RuntimeException() ;
102 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
103 if( pSecEnv == NULL )
104 throw RuntimeException() ;
106 //Get the encryption template
107 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
108 if( !xTemplate.is() ) {
109 throw RuntimeException() ;
112 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
113 if( !xTplTunnel.is() ) {
114 throw RuntimeException() ;
117 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
118 if( pTemplate == NULL ) {
119 throw RuntimeException() ;
122 pEncryptedData = pTemplate->getNativeElement() ;
124 //Find the element to be encrypted.
125 //This element is wrapped in the CipherValue sub-element.
126 xmlNodePtr pCipherData = pEncryptedData->children;
127 while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData"))
129 pCipherData = pCipherData->next;
132 if( pCipherData == NULL ) {
133 throw XMLEncryptionException() ;
136 xmlNodePtr pCipherValue = pCipherData->children;
137 while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
139 pCipherValue = pCipherValue->next;
142 if( pCipherValue == NULL ) {
143 throw XMLEncryptionException() ;
146 pContent = pCipherValue->children;
148 if( pContent == NULL ) {
149 throw XMLEncryptionException() ;
152 xmlUnlinkNode(pContent);
153 xmlAddNextSibling(pEncryptedData, pContent);
155 //remember the position of the element to be signed
156 sal_Bool isParentRef = sal_True;
157 xmlNodePtr pParent = pEncryptedData->parent;
158 xmlNodePtr referenceNode;
160 if (pEncryptedData == pParent->children)
162 referenceNode = pParent;
164 else
166 referenceNode = pEncryptedData->prev;
167 isParentRef = sal_False;
170 setErrorRecorder( );
172 pMngr = pSecEnv->createKeysManager() ; //i39448
173 if( !pMngr ) {
174 throw RuntimeException() ;
177 //Create Encryption context
178 pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
179 if( pEncCtx == NULL )
181 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
182 //throw XMLEncryptionException() ;
183 clearErrorRecorder();
184 return aTemplate;
187 //Encrypt the template
188 if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) {
189 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
190 xmlSecEncCtxDestroy( pEncCtx ) ;
191 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
192 clearErrorRecorder();
193 return aTemplate;
195 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
196 xmlSecEncCtxDestroy( pEncCtx ) ;
197 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
199 //get the new EncryptedData element
200 if (isParentRef)
202 pTemplate->setNativeElement(referenceNode->children) ;
204 else
206 pTemplate->setNativeElement(referenceNode->next);
209 clearErrorRecorder();
210 return aTemplate ;
213 /* XXMLEncryption */
214 Reference< XXMLEncryptionTemplate > SAL_CALL
215 XMLEncryption_MSCryptImpl :: decrypt(
216 const Reference< XXMLEncryptionTemplate >& aTemplate ,
217 const Reference< XXMLSecurityContext >& aSecurityCtx
218 ) throw( com::sun::star::xml::crypto::XMLEncryptionException ,
219 com::sun::star::uno::SecurityException) {
220 xmlSecKeysMngrPtr pMngr = NULL ;
221 xmlSecEncCtxPtr pEncCtx = NULL ;
222 xmlNodePtr pEncryptedData = NULL ;
224 if( !aTemplate.is() )
225 throw RuntimeException() ;
227 if( !aSecurityCtx.is() )
228 throw RuntimeException() ;
230 //Get Keys Manager
231 Reference< XSecurityEnvironment > xSecEnv
232 = aSecurityCtx->getSecurityEnvironmentByIndex(
233 aSecurityCtx->getDefaultSecurityEnvironmentIndex());
234 Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ;
235 if( !xSecTunnel.is() ) {
236 throw RuntimeException() ;
239 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
240 if( pSecEnv == NULL )
241 throw RuntimeException() ;
243 //Get the encryption template
244 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
245 if( !xTemplate.is() ) {
246 throw RuntimeException() ;
249 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
250 if( !xTplTunnel.is() ) {
251 throw RuntimeException() ;
254 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
255 if( pTemplate == NULL ) {
256 throw RuntimeException() ;
259 pEncryptedData = pTemplate->getNativeElement() ;
261 //remember the position of the element to be signed
262 sal_Bool isParentRef = sal_True;
263 xmlNodePtr pParent = pEncryptedData->parent;
264 xmlNodePtr referenceNode;
266 if (pEncryptedData == pParent->children)
268 referenceNode = pParent;
270 else
272 referenceNode = pEncryptedData->prev;
273 isParentRef = sal_False;
276 setErrorRecorder( );
278 pMngr = pSecEnv->createKeysManager() ; //i39448
279 if( !pMngr ) {
280 throw RuntimeException() ;
283 //Create Encryption context
284 pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
285 if( pEncCtx == NULL )
287 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
288 //throw XMLEncryptionException() ;
289 clearErrorRecorder();
290 return aTemplate;
293 //Decrypt the template
294 if( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ) {
295 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
296 xmlSecEncCtxDestroy( pEncCtx ) ;
297 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
299 //throw XMLEncryptionException() ;
300 clearErrorRecorder();
301 return aTemplate;
303 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
304 /*----------------------------------------
305 if( pEncCtx->resultReplaced != 0 ) {
306 pContent = pEncryptedData ;
308 Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ;
309 if( !xTunnel.is() ) {
310 xmlSecEncCtxDestroy( pEncCtx ) ;
311 throw RuntimeException() ;
313 XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
314 if( pNode == NULL ) {
315 xmlSecEncCtxDestroy( pEncCtx ) ;
316 throw RuntimeException() ;
319 pNode->setNativeElement( pContent ) ;
320 } else {
321 xmlSecEncCtxDestroy( pEncCtx ) ;
322 throw RuntimeException() ;
324 ----------------------------------------*/
326 //Destroy the encryption context
327 xmlSecEncCtxDestroy( pEncCtx ) ;
328 pSecEnv->destroyKeysManager( pMngr ) ; //i39448
330 //get the decrypted element
331 XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
332 (referenceNode->children):(referenceNode->next));
334 //return ret;
335 aTemplate->setTemplate(ret);
337 clearErrorRecorder();
338 return aTemplate;
341 /* XInitialization */
342 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
343 // TBD
346 /* XServiceInfo */
347 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
348 return impl_getImplementationName() ;
351 /* XServiceInfo */
352 sal_Bool SAL_CALL XMLEncryption_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
353 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
354 const OUString* pArray = seqServiceNames.getConstArray() ;
355 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
356 if( *( pArray + i ) == serviceName )
357 return sal_True ;
359 return sal_False ;
362 /* XServiceInfo */
363 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
364 return impl_getSupportedServiceNames() ;
367 //Helper for XServiceInfo
368 Sequence< OUString > XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() {
369 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
370 Sequence< OUString > seqServiceNames( 1 ) ;
371 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
372 return seqServiceNames ;
375 OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
376 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ;
379 //Helper for registry
380 Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
381 return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ;
384 Reference< XSingleServiceFactory > XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
385 //Reference< XSingleServiceFactory > xFactory ;
386 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
387 //return xFactory ;
388 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;