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