Bump version to 5.0-14
[LibreOffice.git] / xmlsecurity / source / xmlsec / mscrypt / xmlencryption_mscryptimpl.cxx
blob1ee9831ab27ef8d84a649bdab6de7f84a20121e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <rtl/uuid.h>
22 #include "xmlencryption_mscryptimpl.hxx"
24 #include "xmldocumentwrapper_xmlsecimpl.hxx"
26 #include "xmlelementwrapper_xmlsecimpl.hxx"
28 #include "securityenvironment_mscryptimpl.hxx"
29 #include "errorcallback.hxx"
31 #include "xmlsecurity/xmlsec-wrapper.h"
33 #ifdef UNX
34 #define stricmp strcasecmp
35 #endif
37 using namespace ::com::sun::star::uno ;
38 using namespace ::com::sun::star::lang ;
39 using ::com::sun::star::lang::XMultiServiceFactory ;
40 using ::com::sun::star::lang::XSingleServiceFactory ;
42 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
43 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
44 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
45 using ::com::sun::star::xml::crypto::XXMLEncryption ;
46 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ;
47 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
48 using ::com::sun::star::xml::crypto::XMLEncryptionException ;
50 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
53 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() {
56 /* XXMLEncryption */
57 Reference< XXMLEncryptionTemplate >
58 SAL_CALL XMLEncryption_MSCryptImpl :: encrypt(
59 const Reference< XXMLEncryptionTemplate >& aTemplate ,
60 const Reference< XSecurityEnvironment >& aEnvironment
61 ) throw( com::sun::star::xml::crypto::XMLEncryptionException,
62 com::sun::star::uno::SecurityException )
64 xmlSecKeysMngrPtr pMngr = NULL ;
65 xmlSecEncCtxPtr pEncCtx = NULL ;
66 xmlNodePtr pEncryptedData = NULL ;
67 xmlNodePtr pContent = NULL ;
69 if( !aTemplate.is() )
70 throw RuntimeException() ;
72 if( !aEnvironment.is() )
73 throw RuntimeException() ;
75 //Get Keys Manager
76 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
77 if( !xSecTunnel.is() ) {
78 throw RuntimeException() ;
81 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
82 if( pSecEnv == NULL )
83 throw RuntimeException() ;
85 //Get the encryption template
86 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
87 if( !xTemplate.is() ) {
88 throw RuntimeException() ;
91 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
92 if( !xTplTunnel.is() ) {
93 throw RuntimeException() ;
96 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
97 if( pTemplate == NULL ) {
98 throw RuntimeException() ;
101 pEncryptedData = pTemplate->getNativeElement() ;
103 //Find the element to be encrypted.
104 //This element is wrapped in the CipherValue sub-element.
105 xmlNodePtr pCipherData = pEncryptedData->children;
106 while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData"))
108 pCipherData = pCipherData->next;
111 if( pCipherData == NULL ) {
112 throw XMLEncryptionException() ;
115 xmlNodePtr pCipherValue = pCipherData->children;
116 while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue"))
118 pCipherValue = pCipherValue->next;
121 if( pCipherValue == NULL ) {
122 throw XMLEncryptionException() ;
125 pContent = pCipherValue->children;
127 if( pContent == NULL ) {
128 throw XMLEncryptionException() ;
131 xmlUnlinkNode(pContent);
132 xmlAddNextSibling(pEncryptedData, pContent);
134 //remember the position of the element to be signed
135 sal_Bool isParentRef = sal_True;
136 xmlNodePtr pParent = pEncryptedData->parent;
137 xmlNodePtr referenceNode;
139 if (pEncryptedData == pParent->children)
141 referenceNode = pParent;
143 else
145 referenceNode = pEncryptedData->prev;
146 isParentRef = sal_False;
149 setErrorRecorder( );
151 pMngr = pSecEnv->createKeysManager();
152 if( !pMngr ) {
153 throw RuntimeException() ;
156 //Create Encryption context
157 pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
158 if( pEncCtx == NULL )
160 pSecEnv->destroyKeysManager( pMngr );
161 //throw XMLEncryptionException() ;
162 clearErrorRecorder();
163 return aTemplate;
166 //Encrypt the template
167 if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) {
168 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
169 xmlSecEncCtxDestroy( pEncCtx ) ;
170 pSecEnv->destroyKeysManager( pMngr );
171 clearErrorRecorder();
172 return aTemplate;
174 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
175 xmlSecEncCtxDestroy( pEncCtx ) ;
176 pSecEnv->destroyKeysManager( pMngr );
178 //get the new EncryptedData element
179 if (isParentRef)
181 pTemplate->setNativeElement(referenceNode->children) ;
183 else
185 pTemplate->setNativeElement(referenceNode->next);
188 clearErrorRecorder();
189 return aTemplate ;
192 /* XXMLEncryption */
193 Reference< XXMLEncryptionTemplate > SAL_CALL
194 XMLEncryption_MSCryptImpl :: decrypt(
195 const Reference< XXMLEncryptionTemplate >& aTemplate ,
196 const Reference< XXMLSecurityContext >& aSecurityCtx
197 ) throw( com::sun::star::xml::crypto::XMLEncryptionException ,
198 com::sun::star::uno::SecurityException) {
199 xmlSecKeysMngrPtr pMngr = NULL ;
200 xmlSecEncCtxPtr pEncCtx = NULL ;
201 xmlNodePtr pEncryptedData = NULL ;
203 if( !aTemplate.is() )
204 throw RuntimeException() ;
206 if( !aSecurityCtx.is() )
207 throw RuntimeException() ;
209 //Get Keys Manager
210 Reference< XSecurityEnvironment > xSecEnv
211 = aSecurityCtx->getSecurityEnvironmentByIndex(
212 aSecurityCtx->getDefaultSecurityEnvironmentIndex());
213 Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ;
214 if( !xSecTunnel.is() ) {
215 throw RuntimeException() ;
218 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
219 if( pSecEnv == NULL )
220 throw RuntimeException() ;
222 //Get the encryption template
223 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ;
224 if( !xTemplate.is() ) {
225 throw RuntimeException() ;
228 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ;
229 if( !xTplTunnel.is() ) {
230 throw RuntimeException() ;
233 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
234 if( pTemplate == NULL ) {
235 throw RuntimeException() ;
238 pEncryptedData = pTemplate->getNativeElement() ;
240 //remember the position of the element to be signed
241 sal_Bool isParentRef = sal_True;
242 xmlNodePtr pParent = pEncryptedData->parent;
243 xmlNodePtr referenceNode;
245 if (pEncryptedData == pParent->children)
247 referenceNode = pParent;
249 else
251 referenceNode = pEncryptedData->prev;
252 isParentRef = sal_False;
255 setErrorRecorder( );
257 pMngr = pSecEnv->createKeysManager();
258 if( !pMngr ) {
259 throw RuntimeException() ;
262 //Create Encryption context
263 pEncCtx = xmlSecEncCtxCreate( pMngr ) ;
264 if( pEncCtx == NULL )
266 pSecEnv->destroyKeysManager( pMngr );
267 //throw XMLEncryptionException() ;
268 clearErrorRecorder();
269 return aTemplate;
272 //Decrypt the template
273 if( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ) {
274 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
275 xmlSecEncCtxDestroy( pEncCtx ) ;
276 pSecEnv->destroyKeysManager( pMngr );
278 //throw XMLEncryptionException() ;
279 clearErrorRecorder();
280 return aTemplate;
282 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
283 #if 0 // This code block has been commented out since 2004,
284 // but let's keep it here in case it contains some useful hints
285 // for future work.
286 if( pEncCtx->resultReplaced != 0 ) {
287 pContent = pEncryptedData ;
289 Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ;
290 if( !xTunnel.is() ) {
291 xmlSecEncCtxDestroy( pEncCtx ) ;
292 throw RuntimeException() ;
294 XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
295 if( pNode == NULL ) {
296 xmlSecEncCtxDestroy( pEncCtx ) ;
297 throw RuntimeException() ;
300 pNode->setNativeElement( pContent ) ;
301 } else {
302 xmlSecEncCtxDestroy( pEncCtx ) ;
303 throw RuntimeException() ;
305 #endif // 0
307 //Destroy the encryption context
308 xmlSecEncCtxDestroy( pEncCtx ) ;
309 pSecEnv->destroyKeysManager( pMngr );
311 //get the decrypted element
312 XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef?
313 (referenceNode->children):(referenceNode->next));
315 //return ret;
316 aTemplate->setTemplate(ret);
318 clearErrorRecorder();
319 return aTemplate;
322 /* XServiceInfo */
323 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
324 return impl_getImplementationName() ;
327 /* XServiceInfo */
328 sal_Bool SAL_CALL XMLEncryption_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
329 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
330 const OUString* pArray = seqServiceNames.getConstArray() ;
331 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
332 if( *( pArray + i ) == serviceName )
333 return sal_True ;
335 return sal_False ;
338 /* XServiceInfo */
339 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
340 return impl_getSupportedServiceNames() ;
343 //Helper for XServiceInfo
344 Sequence< OUString > XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() {
345 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
346 Sequence< OUString > seqServiceNames( 1 ) ;
347 seqServiceNames[0] = "com.sun.star.xml.crypto.XMLEncryption";
348 return seqServiceNames ;
351 OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
352 return OUString("com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl") ;
355 //Helper for registry
356 Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
357 return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ;
360 Reference< XSingleServiceFactory > XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
361 //Reference< XSingleServiceFactory > xFactory ;
362 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
363 //return xFactory ;
364 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */