xref: /AOO41X/main/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.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 
27 #include <sal/config.h>
28 #include <rtl/uuid.h>
29 #include "xmlencryption_mscryptimpl.hxx"
30 
31 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
32 #include "xmldocumentwrapper_xmlsecimpl.hxx"
33 #endif
34 
35 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
36 #include "xmlelementwrapper_xmlsecimpl.hxx"
37 #endif
38 
39 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
40 #include "securityenvironment_mscryptimpl.hxx"
41 #endif
42 #include "errorcallback.hxx"
43 
44 #include "xmlsec/xmlsec.h"
45 #include "xmlsec/xmltree.h"
46 #include "xmlsec/xmlenc.h"
47 #include "xmlsec/crypto.h"
48 
49 #ifdef UNX
50 #define stricmp strcasecmp
51 #endif
52 
53 using namespace ::com::sun::star::uno ;
54 using namespace ::com::sun::star::lang ;
55 using ::com::sun::star::lang::XMultiServiceFactory ;
56 using ::com::sun::star::lang::XSingleServiceFactory ;
57 using ::rtl::OUString ;
58 
59 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
60 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
61 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
62 using ::com::sun::star::xml::crypto::XXMLEncryption ;
63 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ;
64 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
65 using ::com::sun::star::xml::crypto::XMLEncryptionException ;
66 
XMLEncryption_MSCryptImpl(const Reference<XMultiServiceFactory> & aFactory)67 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
68 }
69 
~XMLEncryption_MSCryptImpl()70 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() {
71 }
72 
73 /* XXMLEncryption */
74 Reference< XXMLEncryptionTemplate >
encrypt(const Reference<XXMLEncryptionTemplate> & aTemplate,const Reference<XSecurityEnvironment> & aEnvironment)75 SAL_CALL XMLEncryption_MSCryptImpl :: encrypt(
76     const Reference< XXMLEncryptionTemplate >& aTemplate ,
77     const Reference< XSecurityEnvironment >& aEnvironment
78 ) throw( com::sun::star::xml::crypto::XMLEncryptionException,
79          com::sun::star::uno::SecurityException )
80 {
81     xmlSecKeysMngrPtr pMngr = NULL ;
82     xmlSecEncCtxPtr pEncCtx = NULL ;
83     xmlNodePtr pEncryptedData = NULL ;
84     xmlNodePtr pContent = NULL ;
85 
86     if( !aTemplate.is() )
87         throw RuntimeException() ;
88 
89     if( !aEnvironment.is() )
90         throw RuntimeException() ;
91 
92     //Get Keys Manager
93     Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
94     if( !xSecTunnel.is() ) {
95          throw RuntimeException() ;
96     }
97 
98     SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
99     if( pSecEnv == NULL )
100         throw RuntimeException() ;
101 
102     //Get the encryption template
103     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
104     if( !xTemplate.is() ) {
105         throw RuntimeException() ;
106     }
107 
108     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
109     if( !xTplTunnel.is() ) {
110         throw RuntimeException() ;
111     }
112 
113     XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
114     if( pTemplate == NULL ) {
115         throw RuntimeException() ;
116     }
117 
118     pEncryptedData = pTemplate->getNativeElement() ;
119 
120     //Find the element to be encrypted.
121     //This element is wrapped in the CipherValue sub-element.
122     xmlNodePtr pCipherData = pEncryptedData->children;
123     while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData"))
124     {
125         pCipherData = pCipherData->next;
126     }
127 
128     if( pCipherData == NULL ) {
129         throw XMLEncryptionException() ;
130     }
131 
132     xmlNodePtr pCipherValue = pCipherData->children;
133     while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
134     {
135         pCipherValue = pCipherValue->next;
136     }
137 
138     if( pCipherValue == NULL ) {
139         throw XMLEncryptionException() ;
140     }
141 
142     pContent = pCipherValue->children;
143 
144     if( pContent == NULL ) {
145         throw XMLEncryptionException() ;
146     }
147 
148     xmlUnlinkNode(pContent);
149     xmlAddNextSibling(pEncryptedData, pContent);
150 
151     //remember the position of the element to be signed
152     sal_Bool isParentRef = sal_True;
153     xmlNodePtr pParent = pEncryptedData->parent;
154     xmlNodePtr referenceNode;
155 
156     if (pEncryptedData == pParent->children)
157     {
158         referenceNode = pParent;
159     }
160     else
161     {
162         referenceNode = pEncryptedData->prev;
163         isParentRef = sal_False;
164     }
165 
166     setErrorRecorder( );
167 
168     pMngr = pSecEnv->createKeysManager() ; //i39448
169     if( !pMngr ) {
170         throw RuntimeException() ;
171     }
172 
173     //Create Encryption context
174     pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
175     if( pEncCtx == NULL )
176     {
177         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
178         //throw XMLEncryptionException() ;
179         clearErrorRecorder();
180         return aTemplate;
181     }
182 
183     //Encrypt the template
184     if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) {
185         aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
186         xmlSecEncCtxDestroy( pEncCtx ) ;
187         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
188         clearErrorRecorder();
189         return aTemplate;
190     }
191     aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
192     xmlSecEncCtxDestroy( pEncCtx ) ;
193     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
194 
195     //get the new EncryptedData element
196     if (isParentRef)
197     {
198         pTemplate->setNativeElement(referenceNode->children) ;
199     }
200     else
201     {
202         pTemplate->setNativeElement(referenceNode->next);
203     }
204 
205     clearErrorRecorder();
206     return aTemplate ;
207 }
208 
209 /* XXMLEncryption */
210 Reference< XXMLEncryptionTemplate > SAL_CALL
decrypt(const Reference<XXMLEncryptionTemplate> & aTemplate,const Reference<XXMLSecurityContext> & aSecurityCtx)211 XMLEncryption_MSCryptImpl :: decrypt(
212     const Reference< XXMLEncryptionTemplate >& aTemplate ,
213     const Reference< XXMLSecurityContext >& aSecurityCtx
214 ) throw( com::sun::star::xml::crypto::XMLEncryptionException ,
215          com::sun::star::uno::SecurityException) {
216     xmlSecKeysMngrPtr pMngr = NULL ;
217     xmlSecEncCtxPtr pEncCtx = NULL ;
218     xmlNodePtr pEncryptedData = NULL ;
219 
220     if( !aTemplate.is() )
221         throw RuntimeException() ;
222 
223     if( !aSecurityCtx.is() )
224         throw RuntimeException() ;
225 
226     //Get Keys Manager
227     Reference< XSecurityEnvironment > xSecEnv
228         = aSecurityCtx->getSecurityEnvironmentByIndex(
229             aSecurityCtx->getDefaultSecurityEnvironmentIndex());
230     Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ;
231     if( !xSecTunnel.is() ) {
232          throw RuntimeException() ;
233     }
234 
235     SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
236     if( pSecEnv == NULL )
237         throw RuntimeException() ;
238 
239     //Get the encryption template
240     Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
241     if( !xTemplate.is() ) {
242         throw RuntimeException() ;
243     }
244 
245     Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
246     if( !xTplTunnel.is() ) {
247         throw RuntimeException() ;
248     }
249 
250     XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
251     if( pTemplate == NULL ) {
252         throw RuntimeException() ;
253     }
254 
255     pEncryptedData = pTemplate->getNativeElement() ;
256 
257     //remember the position of the element to be signed
258     sal_Bool isParentRef = sal_True;
259     xmlNodePtr pParent = pEncryptedData->parent;
260     xmlNodePtr referenceNode;
261 
262     if (pEncryptedData == pParent->children)
263     {
264         referenceNode = pParent;
265     }
266     else
267     {
268         referenceNode = pEncryptedData->prev;
269         isParentRef = sal_False;
270     }
271 
272     setErrorRecorder( );
273 
274     pMngr = pSecEnv->createKeysManager() ; //i39448
275     if( !pMngr ) {
276         throw RuntimeException() ;
277     }
278 
279     //Create Encryption context
280     pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
281     if( pEncCtx == NULL )
282     {
283         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
284         //throw XMLEncryptionException() ;
285         clearErrorRecorder();
286         return aTemplate;
287     }
288 
289     //Decrypt the template
290     if( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ) {
291         aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
292         xmlSecEncCtxDestroy( pEncCtx ) ;
293         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
294 
295         //throw XMLEncryptionException() ;
296         clearErrorRecorder();
297         return aTemplate;
298     }
299     aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
300     /*----------------------------------------
301     if( pEncCtx->resultReplaced != 0 ) {
302         pContent = pEncryptedData ;
303 
304         Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ;
305         if( !xTunnel.is() ) {
306             xmlSecEncCtxDestroy( pEncCtx ) ;
307             throw RuntimeException() ;
308         }
309         XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
310         if( pNode == NULL ) {
311             xmlSecEncCtxDestroy( pEncCtx ) ;
312             throw RuntimeException() ;
313         }
314 
315         pNode->setNativeElement( pContent ) ;
316     } else {
317         xmlSecEncCtxDestroy( pEncCtx ) ;
318         throw RuntimeException() ;
319     }
320     ----------------------------------------*/
321 
322     //Destroy the encryption context
323     xmlSecEncCtxDestroy( pEncCtx ) ;
324     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
325 
326     //get the decrypted element
327     XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
328         (referenceNode->children):(referenceNode->next));
329 
330     //return ret;
331     aTemplate->setTemplate(ret);
332 
333     clearErrorRecorder();
334     return aTemplate;
335 }
336 
337 /* XInitialization */
initialize(const Sequence<Any> &)338 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
339     // TBD
340 } ;
341 
342 /* XServiceInfo */
getImplementationName()343 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
344     return impl_getImplementationName() ;
345 }
346 
347 /* XServiceInfo */
supportsService(const OUString & serviceName)348 sal_Bool SAL_CALL XMLEncryption_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
349     Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
350     const OUString* pArray = seqServiceNames.getConstArray() ;
351     for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
352         if( *( pArray + i ) == serviceName )
353             return sal_True ;
354     }
355     return sal_False ;
356 }
357 
358 /* XServiceInfo */
getSupportedServiceNames()359 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
360     return impl_getSupportedServiceNames() ;
361 }
362 
363 //Helper for XServiceInfo
impl_getSupportedServiceNames()364 Sequence< OUString > XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() {
365     ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
366     Sequence< OUString > seqServiceNames( 1 ) ;
367     seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
368     return seqServiceNames ;
369 }
370 
impl_getImplementationName()371 OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
372     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ;
373 }
374 
375 //Helper for registry
impl_createInstance(const Reference<XMultiServiceFactory> & aServiceManager)376 Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
377     return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ;
378 }
379 
impl_createFactory(const Reference<XMultiServiceFactory> & aServiceManager)380 Reference< XSingleServiceFactory > XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
381     //Reference< XSingleServiceFactory > xFactory ;
382     //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
383     //return xFactory ;
384     return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
385 }
386 
387