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