xref: /trunk/main/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.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 
31 #include <sal/config.h>
32 #include <rtl/uuid.h>
33 #include "xmlencryption_mscryptimpl.hxx"
34 
35 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
36 #include "xmldocumentwrapper_xmlsecimpl.hxx"
37 #endif
38 
39 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
40 #include "xmlelementwrapper_xmlsecimpl.hxx"
41 #endif
42 
43 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
44 #include "securityenvironment_mscryptimpl.hxx"
45 #endif
46 #include "errorcallback.hxx"
47 
48 #include "xmlsec/xmlsec.h"
49 #include "xmlsec/xmltree.h"
50 #include "xmlsec/xmlenc.h"
51 #include "xmlsec/crypto.h"
52 
53 #ifdef UNX
54 #define stricmp strcasecmp
55 #endif
56 
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 ;
62 
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 ;
70 
71 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
72 }
73 
74 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() {
75 }
76 
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 )
84 {
85     xmlSecKeysMngrPtr pMngr = NULL ;
86     xmlSecEncCtxPtr pEncCtx = NULL ;
87     xmlNodePtr pEncryptedData = NULL ;
88     xmlNodePtr pContent = NULL ;
89 
90     if( !aTemplate.is() )
91         throw RuntimeException() ;
92 
93     if( !aEnvironment.is() )
94         throw RuntimeException() ;
95 
96     //Get Keys Manager
97     Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
98     if( !xSecTunnel.is() ) {
99          throw RuntimeException() ;
100     }
101 
102     SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
103     if( pSecEnv == NULL )
104         throw RuntimeException() ;
105 
106     //Get the encryption template
107     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
108     if( !xTemplate.is() ) {
109         throw RuntimeException() ;
110     }
111 
112     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
113     if( !xTplTunnel.is() ) {
114         throw RuntimeException() ;
115     }
116 
117     XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
118     if( pTemplate == NULL ) {
119         throw RuntimeException() ;
120     }
121 
122     pEncryptedData = pTemplate->getNativeElement() ;
123 
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"))
128     {
129         pCipherData = pCipherData->next;
130     }
131 
132     if( pCipherData == NULL ) {
133         throw XMLEncryptionException() ;
134     }
135 
136     xmlNodePtr pCipherValue = pCipherData->children;
137     while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
138     {
139         pCipherValue = pCipherValue->next;
140     }
141 
142     if( pCipherValue == NULL ) {
143         throw XMLEncryptionException() ;
144     }
145 
146     pContent = pCipherValue->children;
147 
148     if( pContent == NULL ) {
149         throw XMLEncryptionException() ;
150     }
151 
152     xmlUnlinkNode(pContent);
153     xmlAddNextSibling(pEncryptedData, pContent);
154 
155     //remember the position of the element to be signed
156     sal_Bool isParentRef = sal_True;
157     xmlNodePtr pParent = pEncryptedData->parent;
158     xmlNodePtr referenceNode;
159 
160     if (pEncryptedData == pParent->children)
161     {
162         referenceNode = pParent;
163     }
164     else
165     {
166         referenceNode = pEncryptedData->prev;
167         isParentRef = sal_False;
168     }
169 
170     setErrorRecorder( );
171 
172     pMngr = pSecEnv->createKeysManager() ; //i39448
173     if( !pMngr ) {
174         throw RuntimeException() ;
175     }
176 
177     //Create Encryption context
178     pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
179     if( pEncCtx == NULL )
180     {
181         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
182         //throw XMLEncryptionException() ;
183         clearErrorRecorder();
184         return aTemplate;
185     }
186 
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;
194     }
195     aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
196     xmlSecEncCtxDestroy( pEncCtx ) ;
197     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
198 
199     //get the new EncryptedData element
200     if (isParentRef)
201     {
202         pTemplate->setNativeElement(referenceNode->children) ;
203     }
204     else
205     {
206         pTemplate->setNativeElement(referenceNode->next);
207     }
208 
209     clearErrorRecorder();
210     return aTemplate ;
211 }
212 
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 ;
223 
224     if( !aTemplate.is() )
225         throw RuntimeException() ;
226 
227     if( !aSecurityCtx.is() )
228         throw RuntimeException() ;
229 
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() ;
237     }
238 
239     SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
240     if( pSecEnv == NULL )
241         throw RuntimeException() ;
242 
243     //Get the encryption template
244     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
245     if( !xTemplate.is() ) {
246         throw RuntimeException() ;
247     }
248 
249     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
250     if( !xTplTunnel.is() ) {
251         throw RuntimeException() ;
252     }
253 
254     XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
255     if( pTemplate == NULL ) {
256         throw RuntimeException() ;
257     }
258 
259     pEncryptedData = pTemplate->getNativeElement() ;
260 
261     //remember the position of the element to be signed
262     sal_Bool isParentRef = sal_True;
263     xmlNodePtr pParent = pEncryptedData->parent;
264     xmlNodePtr referenceNode;
265 
266     if (pEncryptedData == pParent->children)
267     {
268         referenceNode = pParent;
269     }
270     else
271     {
272         referenceNode = pEncryptedData->prev;
273         isParentRef = sal_False;
274     }
275 
276     setErrorRecorder( );
277 
278     pMngr = pSecEnv->createKeysManager() ; //i39448
279     if( !pMngr ) {
280         throw RuntimeException() ;
281     }
282 
283     //Create Encryption context
284     pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
285     if( pEncCtx == NULL )
286     {
287         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
288         //throw XMLEncryptionException() ;
289         clearErrorRecorder();
290         return aTemplate;
291     }
292 
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
298 
299         //throw XMLEncryptionException() ;
300         clearErrorRecorder();
301         return aTemplate;
302     }
303     aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
304     /*----------------------------------------
305     if( pEncCtx->resultReplaced != 0 ) {
306         pContent = pEncryptedData ;
307 
308         Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ;
309         if( !xTunnel.is() ) {
310             xmlSecEncCtxDestroy( pEncCtx ) ;
311             throw RuntimeException() ;
312         }
313         XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
314         if( pNode == NULL ) {
315             xmlSecEncCtxDestroy( pEncCtx ) ;
316             throw RuntimeException() ;
317         }
318 
319         pNode->setNativeElement( pContent ) ;
320     } else {
321         xmlSecEncCtxDestroy( pEncCtx ) ;
322         throw RuntimeException() ;
323     }
324     ----------------------------------------*/
325 
326     //Destroy the encryption context
327     xmlSecEncCtxDestroy( pEncCtx ) ;
328     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
329 
330     //get the decrypted element
331     XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
332         (referenceNode->children):(referenceNode->next));
333 
334     //return ret;
335     aTemplate->setTemplate(ret);
336 
337     clearErrorRecorder();
338     return aTemplate;
339 }
340 
341 /* XInitialization */
342 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
343     // TBD
344 } ;
345 
346 /* XServiceInfo */
347 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
348     return impl_getImplementationName() ;
349 }
350 
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 ;
358     }
359     return sal_False ;
360 }
361 
362 /* XServiceInfo */
363 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
364     return impl_getSupportedServiceNames() ;
365 }
366 
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 ;
373 }
374 
375 OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
376     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ;
377 }
378 
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 ) ) ;
382 }
383 
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() ) ;
389 }
390 
391