Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 : #include <rtl/uuid.h>
22 : #include "xmlencryption_nssimpl.hxx"
23 :
24 : #include "xmldocumentwrapper_xmlsecimpl.hxx"
25 :
26 : #include "xmlelementwrapper_xmlsecimpl.hxx"
27 :
28 : #include "securityenvironment_nssimpl.hxx"
29 : #include "errorcallback.hxx"
30 :
31 : #include <sal/types.h>
32 : //For reasons that escape me, this is what xmlsec does when size_t is not 4
33 : #if SAL_TYPES_SIZEOFPOINTER != 4
34 : # define XMLSEC_NO_SIZE_T
35 : #endif
36 : #include "xmlsec/xmlsec.h"
37 : #include "xmlsec/xmltree.h"
38 : #include "xmlsec/xmlenc.h"
39 : #include "xmlsec/crypto.h"
40 :
41 : #ifdef UNX
42 : #define stricmp strcasecmp
43 : #endif
44 :
45 : using namespace ::com::sun::star::uno ;
46 : using namespace ::com::sun::star::lang ;
47 : using ::com::sun::star::lang::XMultiServiceFactory ;
48 : using ::com::sun::star::lang::XSingleServiceFactory ;
49 : using ::rtl::OUString ;
50 :
51 : using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
52 : using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
53 : using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
54 : using ::com::sun::star::xml::crypto::XXMLEncryption ;
55 : using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ;
56 : using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
57 : using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
58 : using ::com::sun::star::xml::crypto::XMLEncryptionException ;
59 :
60 0 : XMLEncryption_NssImpl :: XMLEncryption_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
61 0 : }
62 :
63 0 : XMLEncryption_NssImpl :: ~XMLEncryption_NssImpl() {
64 0 : }
65 :
66 : /* XXMLEncryption */
67 : Reference< XXMLEncryptionTemplate >
68 0 : SAL_CALL XMLEncryption_NssImpl :: encrypt(
69 : const Reference< XXMLEncryptionTemplate >& aTemplate ,
70 : const Reference< XSecurityEnvironment >& aEnvironment
71 : ) throw( com::sun::star::xml::crypto::XMLEncryptionException,
72 : com::sun::star::uno::SecurityException )
73 : {
74 0 : xmlSecKeysMngrPtr pMngr = NULL ;
75 0 : xmlSecEncCtxPtr pEncCtx = NULL ;
76 0 : xmlNodePtr pEncryptedData = NULL ;
77 0 : xmlNodePtr pContent = NULL ;
78 :
79 0 : if( !aTemplate.is() )
80 0 : throw RuntimeException() ;
81 :
82 0 : if( !aEnvironment.is() )
83 0 : throw RuntimeException() ;
84 :
85 : //Get Keys Manager
86 0 : Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
87 0 : if( !xSecTunnel.is() ) {
88 0 : throw RuntimeException() ;
89 : }
90 :
91 : SecurityEnvironment_NssImpl* pSecEnv =
92 : reinterpret_cast<SecurityEnvironment_NssImpl*>(
93 0 : sal::static_int_cast<sal_uIntPtr>(xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ;
94 0 : if( pSecEnv == NULL )
95 0 : throw RuntimeException() ;
96 :
97 : //Get the encryption template
98 0 : Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
99 0 : if( !xTemplate.is() ) {
100 0 : throw RuntimeException() ;
101 : }
102 :
103 0 : Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
104 0 : if( !xTplTunnel.is() ) {
105 0 : throw RuntimeException() ;
106 : }
107 :
108 : XMLElementWrapper_XmlSecImpl* pTemplate =
109 : reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
110 : sal::static_int_cast<sal_uIntPtr>(
111 0 : xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
112 0 : if( pTemplate == NULL ) {
113 0 : throw RuntimeException() ;
114 : }
115 :
116 : // Get the element to be encrypted
117 0 : Reference< XXMLElementWrapper > xTarget = aTemplate->getTarget() ;
118 0 : if( !xTarget.is() ) {
119 0 : throw XMLEncryptionException() ;
120 : }
121 :
122 0 : Reference< XUnoTunnel > xTgtTunnel( xTarget , UNO_QUERY ) ;
123 0 : if( !xTgtTunnel.is() ) {
124 0 : throw XMLEncryptionException() ;
125 : }
126 :
127 : XMLElementWrapper_XmlSecImpl* pTarget =
128 : reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
129 : sal::static_int_cast<sal_uIntPtr>(
130 0 : xTgtTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
131 0 : if( pTarget == NULL ) {
132 0 : throw RuntimeException() ;
133 : }
134 :
135 0 : pContent = pTarget->getNativeElement() ;
136 :
137 0 : if( pContent == NULL ) {
138 0 : throw XMLEncryptionException() ;
139 : }
140 :
141 : //remember the position of the element to be signed
142 0 : sal_Bool isParentRef = sal_True;
143 0 : pEncryptedData = pTemplate->getNativeElement();
144 :
145 0 : xmlNodePtr pParent = pEncryptedData->parent;
146 : xmlNodePtr referenceNode;
147 :
148 0 : if (pEncryptedData == pParent->children)
149 : {
150 0 : referenceNode = pParent;
151 : }
152 : else
153 : {
154 0 : referenceNode = pEncryptedData->prev;
155 0 : isParentRef = sal_False;
156 : }
157 :
158 0 : setErrorRecorder( );
159 :
160 0 : pMngr = pSecEnv->createKeysManager() ; //i39448
161 0 : if( !pMngr ) {
162 0 : throw RuntimeException() ;
163 : }
164 :
165 : //Create Encryption context
166 0 : pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
167 0 : if( pEncCtx == NULL )
168 : {
169 0 : pSecEnv->destroyKeysManager( pMngr ) ; //i39448
170 : //throw XMLEncryptionException() ;
171 0 : clearErrorRecorder();
172 0 : return aTemplate;
173 : }
174 :
175 : //Find the element to be encrypted.
176 :
177 : //Encrypt the template
178 0 : if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 )
179 : {
180 0 : xmlSecEncCtxDestroy( pEncCtx ) ;
181 0 : pSecEnv->destroyKeysManager( pMngr ) ; //i39448
182 :
183 : //throw XMLEncryptionException() ;
184 0 : clearErrorRecorder();
185 0 : return aTemplate;
186 : }
187 :
188 0 : xmlSecEncCtxDestroy( pEncCtx ) ;
189 0 : pSecEnv->destroyKeysManager( pMngr ) ; //i39448
190 :
191 : //get the new EncryptedData element
192 0 : if (isParentRef)
193 : {
194 0 : pTemplate->setNativeElement(referenceNode->children) ;
195 : }
196 : else
197 : {
198 0 : pTemplate->setNativeElement(referenceNode->next);
199 : }
200 :
201 0 : return aTemplate ;
202 : }
203 :
204 : /* XXMLEncryption */
205 : Reference< XXMLEncryptionTemplate >
206 0 : SAL_CALL XMLEncryption_NssImpl :: decrypt(
207 : const Reference< XXMLEncryptionTemplate >& aTemplate ,
208 : const Reference< XXMLSecurityContext >& aSecurityCtx
209 : ) throw( com::sun::star::xml::crypto::XMLEncryptionException ,
210 : com::sun::star::uno::SecurityException) {
211 0 : xmlSecKeysMngrPtr pMngr = NULL ;
212 0 : xmlSecEncCtxPtr pEncCtx = NULL ;
213 0 : xmlNodePtr pEncryptedData = NULL ;
214 :
215 0 : if( !aTemplate.is() )
216 0 : throw RuntimeException() ;
217 :
218 0 : if( !aSecurityCtx.is() )
219 0 : throw RuntimeException() ;
220 :
221 : //Get the encryption template
222 0 : Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
223 0 : if( !xTemplate.is() ) {
224 0 : throw RuntimeException() ;
225 : }
226 :
227 0 : Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
228 0 : if( !xTplTunnel.is() ) {
229 0 : throw RuntimeException() ;
230 : }
231 :
232 : XMLElementWrapper_XmlSecImpl* pTemplate =
233 : reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
234 : sal::static_int_cast<sal_uIntPtr>(
235 0 : xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() )));
236 0 : if( pTemplate == NULL ) {
237 0 : throw RuntimeException() ;
238 : }
239 :
240 0 : pEncryptedData = pTemplate->getNativeElement() ;
241 :
242 : //remember the position of the element to be signed
243 0 : sal_Bool isParentRef = sal_True;
244 0 : xmlNodePtr pParent = pEncryptedData->parent;
245 : xmlNodePtr referenceNode;
246 :
247 0 : if (pEncryptedData == pParent->children)
248 : {
249 0 : referenceNode = pParent;
250 : }
251 : else
252 : {
253 0 : referenceNode = pEncryptedData->prev;
254 0 : isParentRef = sal_False;
255 : }
256 :
257 0 : setErrorRecorder( );
258 :
259 0 : sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
260 : sal_Int32 i;
261 :
262 0 : for (i=0; i<nSecurityEnvironment; ++i)
263 : {
264 0 : Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
265 :
266 : //Get Keys Manager
267 0 : Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
268 0 : if( !aEnvironment.is() ) {
269 0 : throw RuntimeException() ;
270 : }
271 :
272 : SecurityEnvironment_NssImpl* pSecEnv =
273 : reinterpret_cast<SecurityEnvironment_NssImpl*>(
274 : sal::static_int_cast<sal_uIntPtr>(
275 0 : xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
276 0 : if( pSecEnv == NULL )
277 0 : throw RuntimeException() ;
278 :
279 0 : pMngr = pSecEnv->createKeysManager() ; //i39448
280 0 : if( !pMngr ) {
281 0 : throw RuntimeException() ;
282 : }
283 :
284 : //Create Encryption context
285 0 : pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
286 0 : if( pEncCtx == NULL )
287 : {
288 0 : pSecEnv->destroyKeysManager( pMngr ) ; //i39448
289 : //throw XMLEncryptionException() ;
290 0 : clearErrorRecorder();
291 0 : return aTemplate;
292 : }
293 :
294 : //Decrypt the template
295 0 : if(!( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ))
296 : {
297 : //The decryption succeeds
298 :
299 : //Destroy the encryption context
300 0 : xmlSecEncCtxDestroy( pEncCtx ) ;
301 0 : pSecEnv->destroyKeysManager( pMngr ) ; //i39448
302 :
303 : //get the decrypted element
304 : XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
305 0 : (referenceNode->children):(referenceNode->next));
306 :
307 : //return ret;
308 0 : aTemplate->setTemplate(ret);
309 : break;
310 : }
311 : else
312 : {
313 : //The decryption fails, continue with the next security environment
314 0 : xmlSecEncCtxDestroy( pEncCtx ) ;
315 0 : pSecEnv->destroyKeysManager( pMngr ) ; //i39448
316 : }
317 0 : }
318 :
319 0 : clearErrorRecorder();
320 0 : return aTemplate;
321 : }
322 :
323 : /* XInitialization */
324 0 : void SAL_CALL XMLEncryption_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
325 : // TBD
326 0 : } ;
327 :
328 : /* XServiceInfo */
329 0 : OUString SAL_CALL XMLEncryption_NssImpl :: getImplementationName() throw( RuntimeException ) {
330 0 : return impl_getImplementationName() ;
331 : }
332 :
333 : /* XServiceInfo */
334 0 : sal_Bool SAL_CALL XMLEncryption_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
335 0 : Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
336 0 : const OUString* pArray = seqServiceNames.getConstArray() ;
337 0 : for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
338 0 : if( *( pArray + i ) == serviceName )
339 0 : return sal_True ;
340 : }
341 0 : return sal_False ;
342 : }
343 :
344 : /* XServiceInfo */
345 0 : Sequence< OUString > SAL_CALL XMLEncryption_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
346 0 : return impl_getSupportedServiceNames() ;
347 : }
348 :
349 : //Helper for XServiceInfo
350 0 : Sequence< OUString > XMLEncryption_NssImpl :: impl_getSupportedServiceNames() {
351 0 : ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
352 0 : Sequence< OUString > seqServiceNames( 1 ) ;
353 0 : seqServiceNames.getArray()[0] = OUString("com.sun.star.xml.crypto.XMLEncryption") ;
354 0 : return seqServiceNames ;
355 : }
356 :
357 0 : OUString XMLEncryption_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
358 0 : return OUString("com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl") ;
359 : }
360 :
361 : //Helper for registry
362 0 : Reference< XInterface > SAL_CALL XMLEncryption_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
363 0 : return Reference< XInterface >( *new XMLEncryption_NssImpl( aServiceManager ) ) ;
364 : }
365 :
366 0 : Reference< XSingleServiceFactory > XMLEncryption_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
367 : //Reference< XSingleServiceFactory > xFactory ;
368 : //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
369 : //return xFactory ;
370 0 : return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
371 : }
372 :
373 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|