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 )
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
decrypt(const Reference<XXMLEncryptionTemplate> & aTemplate,const Reference<XXMLSecurityContext> & aSecurityCtx)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 */
initialize(const Sequence<Any> &)336 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) {
337 // TBD
338 } ;
339
340 /* XServiceInfo */
getImplementationName()341 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() {
342 return impl_getImplementationName() ;
343 }
344
345 /* XServiceInfo */
supportsService(const OUString & serviceName)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 */
getSupportedServiceNames()357 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() {
358 return impl_getSupportedServiceNames() ;
359 }
360
361 //Helper for XServiceInfo
impl_getSupportedServiceNames()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
impl_getImplementationName()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
impl_createInstance(const Reference<XMultiServiceFactory> & aServiceManager)374 Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) {
375 return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ;
376 }
377
impl_createFactory(const Reference<XMultiServiceFactory> & aServiceManager)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