xref: /trunk/main/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.cxx (revision 9d37da743abb7db0a497688391f6e55a19f27c44)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlsecurity.hxx"
26 #include <sal/config.h>
27 #include <rtl/uuid.h>
28 #include "xmlencryption_nssimpl.hxx"
29 
30 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
31 #include "xmldocumentwrapper_xmlsecimpl.hxx"
32 #endif
33 
34 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
35 #include "xmlelementwrapper_xmlsecimpl.hxx"
36 #endif
37 
38 #ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_
39 #include "securityenvironment_nssimpl.hxx"
40 #endif
41 #include "errorcallback.hxx"
42 
43 #include <sal/types.h>
44 //For reasons that escape me, this is what xmlsec does when size_t is not 4
45 #if SAL_TYPES_SIZEOFPOINTER != 4
46 #    define XMLSEC_NO_SIZE_T
47 #endif
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::XSecurityEnvironment ;
70 using ::com::sun::star::xml::crypto::XMLEncryptionException ;
71 
72 XMLEncryption_NssImpl :: XMLEncryption_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
73 }
74 
75 XMLEncryption_NssImpl :: ~XMLEncryption_NssImpl() {
76 }
77 
78 /* XXMLEncryption */
79 Reference< XXMLEncryptionTemplate >
80 SAL_CALL XMLEncryption_NssImpl :: encrypt(
81     const Reference< XXMLEncryptionTemplate >& aTemplate ,
82     const Reference< XSecurityEnvironment >& aEnvironment
83 )
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 #if 0
103     XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
104     if( pSecCtxt == NULL )
105         throw RuntimeException() ;
106 #endif
107 
108     SecurityEnvironment_NssImpl* pSecEnv =
109         reinterpret_cast<SecurityEnvironment_NssImpl*>(
110             sal::static_int_cast<sal_uIntPtr>(xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ;
111     if( pSecEnv == NULL )
112         throw RuntimeException() ;
113 
114     //Get the encryption template
115     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
116     if( !xTemplate.is() ) {
117         throw RuntimeException() ;
118     }
119 
120     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
121     if( !xTplTunnel.is() ) {
122         throw RuntimeException() ;
123     }
124 
125     XMLElementWrapper_XmlSecImpl* pTemplate =
126         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
127             sal::static_int_cast<sal_uIntPtr>(
128                 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
129     if( pTemplate == NULL ) {
130         throw RuntimeException() ;
131     }
132 
133     //MM : Get the element to be encrypted
134     Reference< XXMLElementWrapper > xTarget = aTemplate->getTarget() ;
135     if( !xTarget.is() ) {
136         throw XMLEncryptionException() ;
137     }
138 
139     Reference< XUnoTunnel > xTgtTunnel( xTarget , UNO_QUERY ) ;
140     if( !xTgtTunnel.is() ) {
141         throw XMLEncryptionException() ;
142     }
143 
144     XMLElementWrapper_XmlSecImpl* pTarget =
145         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
146             sal::static_int_cast<sal_uIntPtr>(
147                 xTgtTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
148     if( pTarget == NULL ) {
149         throw RuntimeException() ;
150     }
151 
152     pContent = pTarget->getNativeElement() ;
153     //MM : end
154 
155     if( pContent == NULL ) {
156         throw XMLEncryptionException() ;
157     }
158 
159     /* MM : remove the following 2 lines
160     xmlUnlinkNode(pContent);
161     xmlAddNextSibling(pEncryptedData, pContent);
162     */
163 
164     //remember the position of the element to be signed
165     sal_Bool isParentRef = sal_True;
166     xmlNodePtr pParent = pEncryptedData->parent;
167     xmlNodePtr referenceNode;
168 
169     if (pEncryptedData == pParent->children)
170     {
171         referenceNode = pParent;
172     }
173     else
174     {
175         referenceNode = pEncryptedData->prev;
176         isParentRef = sal_False;
177     }
178 
179     setErrorRecorder( );
180 
181     pMngr = pSecEnv->createKeysManager() ; //i39448
182     if( !pMngr ) {
183         throw RuntimeException() ;
184     }
185 
186     //Create Encryption context
187     pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
188     if( pEncCtx == NULL )
189     {
190         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
191         //throw XMLEncryptionException() ;
192         clearErrorRecorder();
193         return aTemplate;
194     }
195 
196     pEncryptedData = pTemplate->getNativeElement() ;
197 
198     //Find the element to be encrypted.
199     /* MM : remove the old method to get the target element
200     //This element is wrapped in the CipherValue sub-element.
201     xmlNodePtr pCipherData = pEncryptedData->children;
202     while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData"))
203     {
204         pCipherData = pCipherData->next;
205     }
206 
207     if( pCipherData == NULL ) {
208         xmlSecEncCtxDestroy( pEncCtx ) ;
209         throw XMLEncryptionException() ;
210     }
211 
212     xmlNodePtr pCipherValue = pCipherData->children;
213     while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
214     {
215         pCipherValue = pCipherValue->next;
216     }
217 
218     if( pCipherValue == NULL ) {
219         xmlSecEncCtxDestroy( pEncCtx ) ;
220         throw XMLEncryptionException() ;
221     }
222 
223     pContent = pCipherValue->children;
224     */
225 
226     //Encrypt the template
227     if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 )
228     {
229         xmlSecEncCtxDestroy( pEncCtx ) ;
230         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
231 
232         //throw XMLEncryptionException() ;
233         clearErrorRecorder();
234         return aTemplate;
235     }
236 
237     xmlSecEncCtxDestroy( pEncCtx ) ;
238     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
239 
240     //get the new EncryptedData element
241     if (isParentRef)
242     {
243         pTemplate->setNativeElement(referenceNode->children) ;
244     }
245     else
246     {
247         pTemplate->setNativeElement(referenceNode->next);
248     }
249 
250     return aTemplate ;
251 }
252 
253 /* XXMLEncryption */
254 Reference< XXMLEncryptionTemplate >
255 SAL_CALL XMLEncryption_NssImpl :: decrypt(
256     const Reference< XXMLEncryptionTemplate >& aTemplate ,
257     const Reference< XXMLSecurityContext >& aSecurityCtx
258 ) {
259     xmlSecKeysMngrPtr pMngr = NULL ;
260     xmlSecEncCtxPtr pEncCtx = NULL ;
261     xmlNodePtr pEncryptedData = NULL ;
262 
263     if( !aTemplate.is() )
264         throw RuntimeException() ;
265 
266     if( !aSecurityCtx.is() )
267         throw RuntimeException() ;
268 
269     //Get the encryption template
270     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
271     if( !xTemplate.is() ) {
272         throw RuntimeException() ;
273     }
274 
275     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
276     if( !xTplTunnel.is() ) {
277         throw RuntimeException() ;
278     }
279 
280     XMLElementWrapper_XmlSecImpl* pTemplate =
281         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
282             sal::static_int_cast<sal_uIntPtr>(
283                 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
284     if( pTemplate == NULL ) {
285         throw RuntimeException() ;
286     }
287 
288     pEncryptedData = pTemplate->getNativeElement() ;
289 
290     //remember the position of the element to be signed
291     sal_Bool isParentRef = sal_True;
292     xmlNodePtr pParent = pEncryptedData->parent;
293     xmlNodePtr referenceNode;
294 
295     if (pEncryptedData == pParent->children)
296     {
297         referenceNode = pParent;
298     }
299     else
300     {
301         referenceNode = pEncryptedData->prev;
302         isParentRef = sal_False;
303     }
304 
305     setErrorRecorder( );
306 
307     sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
308     sal_Int32 i;
309 
310     for (i=0; i<nSecurityEnvironment; ++i)
311     {
312         Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
313 
314         //Get Keys Manager
315         Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
316         if( !aEnvironment.is() ) {
317              throw RuntimeException() ;
318         }
319 
320         SecurityEnvironment_NssImpl* pSecEnv =
321             reinterpret_cast<SecurityEnvironment_NssImpl*>(
322                 sal::static_int_cast<sal_uIntPtr>(
323                     xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
324         if( pSecEnv == NULL )
325             throw RuntimeException() ;
326 
327         pMngr = pSecEnv->createKeysManager() ; //i39448
328         if( !pMngr ) {
329             throw RuntimeException() ;
330         }
331 
332         //Create Encryption context
333         pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
334         if( pEncCtx == NULL )
335         {
336             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
337             //throw XMLEncryptionException() ;
338             clearErrorRecorder();
339             return aTemplate;
340         }
341 
342         //Decrypt the template
343         if(!( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ))
344         {
345             //The decryption succeeds
346 
347             //Destroy the encryption context
348             xmlSecEncCtxDestroy( pEncCtx ) ;
349             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
350 
351             //get the decrypted element
352             XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
353                 (referenceNode->children):(referenceNode->next));
354 
355             //return ret;
356             aTemplate->setTemplate(ret);
357             break;
358         }
359         else
360         {
361             //The decryption fails, continue with the next security environment
362             xmlSecEncCtxDestroy( pEncCtx ) ;
363             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
364         }
365     }
366 
367     clearErrorRecorder();
368     return aTemplate;
369 }
370 
371 /* XInitialization */
372 void SAL_CALL XMLEncryption_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) {
373     // TBD
374 } ;
375 
376 /* XServiceInfo */
377 OUString SAL_CALL XMLEncryption_NssImpl :: getImplementationName() {
378     return impl_getImplementationName() ;
379 }
380 
381 /* XServiceInfo */
382 sal_Bool SAL_CALL XMLEncryption_NssImpl :: supportsService( const OUString& serviceName) {
383     Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
384     const OUString* pArray = seqServiceNames.getConstArray() ;
385     for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
386         if( *( pArray + i ) == serviceName )
387             return sal_True ;
388     }
389     return sal_False ;
390 }
391 
392 /* XServiceInfo */
393 Sequence< OUString > SAL_CALL XMLEncryption_NssImpl :: getSupportedServiceNames() {
394     return impl_getSupportedServiceNames() ;
395 }
396 
397 //Helper for XServiceInfo
398 Sequence< OUString > XMLEncryption_NssImpl :: impl_getSupportedServiceNames() {
399     ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
400     Sequence< OUString > seqServiceNames( 1 ) ;
401     seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
402     return seqServiceNames ;
403 }
404 
405 OUString XMLEncryption_NssImpl :: impl_getImplementationName() {
406     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl" ) ;
407 }
408 
409 //Helper for registry
410 Reference< XInterface > SAL_CALL XMLEncryption_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) {
411     return Reference< XInterface >( *new XMLEncryption_NssImpl( aServiceManager ) ) ;
412 }
413 
414 Reference< XSingleServiceFactory > XMLEncryption_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
415     //Reference< XSingleServiceFactory > xFactory ;
416     //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
417     //return xFactory ;
418     return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
419 }
420