xref: /AOO41X/main/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.cxx (revision 06b3ce531745799678cf4bb887ef37436d81238b)
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 
XMLEncryption_NssImpl(const Reference<XMultiServiceFactory> & aFactory)72 XMLEncryption_NssImpl :: XMLEncryption_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
73 }
74 
~XMLEncryption_NssImpl()75 XMLEncryption_NssImpl :: ~XMLEncryption_NssImpl() {
76 }
77 
78 /* XXMLEncryption */
79 Reference< XXMLEncryptionTemplate >
encrypt(const Reference<XXMLEncryptionTemplate> & aTemplate,const Reference<XSecurityEnvironment> & aEnvironment)80 SAL_CALL XMLEncryption_NssImpl :: encrypt(
81     const Reference< XXMLEncryptionTemplate >& aTemplate ,
82     const Reference< XSecurityEnvironment >& aEnvironment
83 ) throw( com::sun::star::xml::crypto::XMLEncryptionException,
84          com::sun::star::uno::SecurityException )
85 {
86     xmlSecKeysMngrPtr pMngr = NULL ;
87     xmlSecEncCtxPtr pEncCtx = NULL ;
88     xmlNodePtr pEncryptedData = NULL ;
89     xmlNodePtr pContent = NULL ;
90 
91     if( !aTemplate.is() )
92         throw RuntimeException() ;
93 
94     if( !aEnvironment.is() )
95         throw RuntimeException() ;
96 
97     //Get Keys Manager
98     Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
99     if( !xSecTunnel.is() ) {
100          throw RuntimeException() ;
101     }
102 
103 #if 0
104     XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
105     if( pSecCtxt == NULL )
106         throw RuntimeException() ;
107 #endif
108 
109     SecurityEnvironment_NssImpl* pSecEnv =
110         reinterpret_cast<SecurityEnvironment_NssImpl*>(
111             sal::static_int_cast<sal_uIntPtr>(xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ;
112     if( pSecEnv == NULL )
113         throw RuntimeException() ;
114 
115     //Get the encryption template
116     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
117     if( !xTemplate.is() ) {
118         throw RuntimeException() ;
119     }
120 
121     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
122     if( !xTplTunnel.is() ) {
123         throw RuntimeException() ;
124     }
125 
126     XMLElementWrapper_XmlSecImpl* pTemplate =
127         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
128             sal::static_int_cast<sal_uIntPtr>(
129                 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
130     if( pTemplate == NULL ) {
131         throw RuntimeException() ;
132     }
133 
134     //MM : Get the element to be encrypted
135     Reference< XXMLElementWrapper > xTarget = aTemplate->getTarget() ;
136     if( !xTarget.is() ) {
137         throw XMLEncryptionException() ;
138     }
139 
140     Reference< XUnoTunnel > xTgtTunnel( xTarget , UNO_QUERY ) ;
141     if( !xTgtTunnel.is() ) {
142         throw XMLEncryptionException() ;
143     }
144 
145     XMLElementWrapper_XmlSecImpl* pTarget =
146         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
147             sal::static_int_cast<sal_uIntPtr>(
148                 xTgtTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
149     if( pTarget == NULL ) {
150         throw RuntimeException() ;
151     }
152 
153     pContent = pTarget->getNativeElement() ;
154     //MM : end
155 
156     if( pContent == NULL ) {
157         throw XMLEncryptionException() ;
158     }
159 
160     /* MM : remove the following 2 lines
161     xmlUnlinkNode(pContent);
162     xmlAddNextSibling(pEncryptedData, pContent);
163     */
164 
165     //remember the position of the element to be signed
166     sal_Bool isParentRef = sal_True;
167     xmlNodePtr pParent = pEncryptedData->parent;
168     xmlNodePtr referenceNode;
169 
170     if (pEncryptedData == pParent->children)
171     {
172         referenceNode = pParent;
173     }
174     else
175     {
176         referenceNode = pEncryptedData->prev;
177         isParentRef = sal_False;
178     }
179 
180     setErrorRecorder( );
181 
182     pMngr = pSecEnv->createKeysManager() ; //i39448
183     if( !pMngr ) {
184         throw RuntimeException() ;
185     }
186 
187     //Create Encryption context
188     pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
189     if( pEncCtx == NULL )
190     {
191         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
192         //throw XMLEncryptionException() ;
193         clearErrorRecorder();
194         return aTemplate;
195     }
196 
197     pEncryptedData = pTemplate->getNativeElement() ;
198 
199     //Find the element to be encrypted.
200     /* MM : remove the old method to get the target element
201     //This element is wrapped in the CipherValue sub-element.
202     xmlNodePtr pCipherData = pEncryptedData->children;
203     while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData"))
204     {
205         pCipherData = pCipherData->next;
206     }
207 
208     if( pCipherData == NULL ) {
209         xmlSecEncCtxDestroy( pEncCtx ) ;
210         throw XMLEncryptionException() ;
211     }
212 
213     xmlNodePtr pCipherValue = pCipherData->children;
214     while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
215     {
216         pCipherValue = pCipherValue->next;
217     }
218 
219     if( pCipherValue == NULL ) {
220         xmlSecEncCtxDestroy( pEncCtx ) ;
221         throw XMLEncryptionException() ;
222     }
223 
224     pContent = pCipherValue->children;
225     */
226 
227     //Encrypt the template
228     if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 )
229     {
230         xmlSecEncCtxDestroy( pEncCtx ) ;
231         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
232 
233         //throw XMLEncryptionException() ;
234         clearErrorRecorder();
235         return aTemplate;
236     }
237 
238     xmlSecEncCtxDestroy( pEncCtx ) ;
239     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
240 
241     //get the new EncryptedData element
242     if (isParentRef)
243     {
244         pTemplate->setNativeElement(referenceNode->children) ;
245     }
246     else
247     {
248         pTemplate->setNativeElement(referenceNode->next);
249     }
250 
251     return aTemplate ;
252 }
253 
254 /* XXMLEncryption */
255 Reference< XXMLEncryptionTemplate >
decrypt(const Reference<XXMLEncryptionTemplate> & aTemplate,const Reference<XXMLSecurityContext> & aSecurityCtx)256 SAL_CALL XMLEncryption_NssImpl :: decrypt(
257     const Reference< XXMLEncryptionTemplate >& aTemplate ,
258     const Reference< XXMLSecurityContext >& aSecurityCtx
259 ) throw( com::sun::star::xml::crypto::XMLEncryptionException ,
260          com::sun::star::uno::SecurityException) {
261     xmlSecKeysMngrPtr pMngr = NULL ;
262     xmlSecEncCtxPtr pEncCtx = NULL ;
263     xmlNodePtr pEncryptedData = NULL ;
264 
265     if( !aTemplate.is() )
266         throw RuntimeException() ;
267 
268     if( !aSecurityCtx.is() )
269         throw RuntimeException() ;
270 
271     //Get the encryption template
272     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
273     if( !xTemplate.is() ) {
274         throw RuntimeException() ;
275     }
276 
277     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
278     if( !xTplTunnel.is() ) {
279         throw RuntimeException() ;
280     }
281 
282     XMLElementWrapper_XmlSecImpl* pTemplate =
283         reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
284             sal::static_int_cast<sal_uIntPtr>(
285                 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
286     if( pTemplate == NULL ) {
287         throw RuntimeException() ;
288     }
289 
290     pEncryptedData = pTemplate->getNativeElement() ;
291 
292     //remember the position of the element to be signed
293     sal_Bool isParentRef = sal_True;
294     xmlNodePtr pParent = pEncryptedData->parent;
295     xmlNodePtr referenceNode;
296 
297     if (pEncryptedData == pParent->children)
298     {
299         referenceNode = pParent;
300     }
301     else
302     {
303         referenceNode = pEncryptedData->prev;
304         isParentRef = sal_False;
305     }
306 
307     setErrorRecorder( );
308 
309     sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
310     sal_Int32 i;
311 
312     for (i=0; i<nSecurityEnvironment; ++i)
313     {
314         Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
315 
316         //Get Keys Manager
317         Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
318         if( !aEnvironment.is() ) {
319              throw RuntimeException() ;
320         }
321 
322         SecurityEnvironment_NssImpl* pSecEnv =
323             reinterpret_cast<SecurityEnvironment_NssImpl*>(
324                 sal::static_int_cast<sal_uIntPtr>(
325                     xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
326         if( pSecEnv == NULL )
327             throw RuntimeException() ;
328 
329         pMngr = pSecEnv->createKeysManager() ; //i39448
330         if( !pMngr ) {
331             throw RuntimeException() ;
332         }
333 
334         //Create Encryption context
335         pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
336         if( pEncCtx == NULL )
337         {
338             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
339             //throw XMLEncryptionException() ;
340             clearErrorRecorder();
341             return aTemplate;
342         }
343 
344         //Decrypt the template
345         if(!( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ))
346         {
347             //The decryption succeeds
348 
349             //Destroy the encryption context
350             xmlSecEncCtxDestroy( pEncCtx ) ;
351             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
352 
353             //get the decrypted element
354             XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
355                 (referenceNode->children):(referenceNode->next));
356 
357             //return ret;
358             aTemplate->setTemplate(ret);
359             break;
360         }
361         else
362         {
363             //The decryption fails, continue with the next security environment
364             xmlSecEncCtxDestroy( pEncCtx ) ;
365             pSecEnv->destroyKeysManager( pMngr ) ; //i39448
366         }
367     }
368 
369     clearErrorRecorder();
370     return aTemplate;
371 }
372 
373 /* XInitialization */
initialize(const Sequence<Any> &)374 void SAL_CALL XMLEncryption_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
375     // TBD
376 } ;
377 
378 /* XServiceInfo */
getImplementationName()379 OUString SAL_CALL XMLEncryption_NssImpl :: getImplementationName() throw( RuntimeException ) {
380     return impl_getImplementationName() ;
381 }
382 
383 /* XServiceInfo */
supportsService(const OUString & serviceName)384 sal_Bool SAL_CALL XMLEncryption_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
385     Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
386     const OUString* pArray = seqServiceNames.getConstArray() ;
387     for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
388         if( *( pArray + i ) == serviceName )
389             return sal_True ;
390     }
391     return sal_False ;
392 }
393 
394 /* XServiceInfo */
getSupportedServiceNames()395 Sequence< OUString > SAL_CALL XMLEncryption_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
396     return impl_getSupportedServiceNames() ;
397 }
398 
399 //Helper for XServiceInfo
impl_getSupportedServiceNames()400 Sequence< OUString > XMLEncryption_NssImpl :: impl_getSupportedServiceNames() {
401     ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
402     Sequence< OUString > seqServiceNames( 1 ) ;
403     seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
404     return seqServiceNames ;
405 }
406 
impl_getImplementationName()407 OUString XMLEncryption_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
408     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl" ) ;
409 }
410 
411 //Helper for registry
impl_createInstance(const Reference<XMultiServiceFactory> & aServiceManager)412 Reference< XInterface > SAL_CALL XMLEncryption_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
413     return Reference< XInterface >( *new XMLEncryption_NssImpl( aServiceManager ) ) ;
414 }
415 
impl_createFactory(const Reference<XMultiServiceFactory> & aServiceManager)416 Reference< XSingleServiceFactory > XMLEncryption_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
417     //Reference< XSingleServiceFactory > xFactory ;
418     //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
419     //return xFactory ;
420     return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
421 }
422 
423