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