1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmlsecurity.hxx" 30 31 #include <sal/config.h> 32 #include <rtl/uuid.h> 33 #include "xmlencryption_mscryptimpl.hxx" 34 35 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_ 36 #include "xmldocumentwrapper_xmlsecimpl.hxx" 37 #endif 38 39 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_ 40 #include "xmlelementwrapper_xmlsecimpl.hxx" 41 #endif 42 43 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_ 44 #include "securityenvironment_mscryptimpl.hxx" 45 #endif 46 #include "errorcallback.hxx" 47 48 #include "xmlsec/xmlsec.h" 49 #include "xmlsec/xmltree.h" 50 #include "xmlsec/xmlenc.h" 51 #include "xmlsec/crypto.h" 52 53 #ifdef UNX 54 #define stricmp strcasecmp 55 #endif 56 57 using namespace ::com::sun::star::uno ; 58 using namespace ::com::sun::star::lang ; 59 using ::com::sun::star::lang::XMultiServiceFactory ; 60 using ::com::sun::star::lang::XSingleServiceFactory ; 61 using ::rtl::OUString ; 62 63 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ; 64 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ; 65 using ::com::sun::star::xml::crypto::XSecurityEnvironment ; 66 using ::com::sun::star::xml::crypto::XXMLEncryption ; 67 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ; 68 using ::com::sun::star::xml::crypto::XXMLSecurityContext ; 69 using ::com::sun::star::xml::crypto::XMLEncryptionException ; 70 71 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { 72 } 73 74 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() { 75 } 76 77 /* XXMLEncryption */ 78 Reference< XXMLEncryptionTemplate > 79 SAL_CALL XMLEncryption_MSCryptImpl :: encrypt( 80 const Reference< XXMLEncryptionTemplate >& aTemplate , 81 const Reference< XSecurityEnvironment >& aEnvironment 82 ) throw( com::sun::star::xml::crypto::XMLEncryptionException, 83 com::sun::star::uno::SecurityException ) 84 { 85 xmlSecKeysMngrPtr pMngr = NULL ; 86 xmlSecEncCtxPtr pEncCtx = NULL ; 87 xmlNodePtr pEncryptedData = NULL ; 88 xmlNodePtr pContent = NULL ; 89 90 if( !aTemplate.is() ) 91 throw RuntimeException() ; 92 93 if( !aEnvironment.is() ) 94 throw RuntimeException() ; 95 96 //Get Keys Manager 97 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; 98 if( !xSecTunnel.is() ) { 99 throw RuntimeException() ; 100 } 101 102 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; 103 if( pSecEnv == NULL ) 104 throw RuntimeException() ; 105 106 //Get the encryption template 107 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; 108 if( !xTemplate.is() ) { 109 throw RuntimeException() ; 110 } 111 112 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; 113 if( !xTplTunnel.is() ) { 114 throw RuntimeException() ; 115 } 116 117 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 118 if( pTemplate == NULL ) { 119 throw RuntimeException() ; 120 } 121 122 pEncryptedData = pTemplate->getNativeElement() ; 123 124 //Find the element to be encrypted. 125 //This element is wrapped in the CipherValue sub-element. 126 xmlNodePtr pCipherData = pEncryptedData->children; 127 while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData")) 128 { 129 pCipherData = pCipherData->next; 130 } 131 132 if( pCipherData == NULL ) { 133 throw XMLEncryptionException() ; 134 } 135 136 xmlNodePtr pCipherValue = pCipherData->children; 137 while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue")) 138 { 139 pCipherValue = pCipherValue->next; 140 } 141 142 if( pCipherValue == NULL ) { 143 throw XMLEncryptionException() ; 144 } 145 146 pContent = pCipherValue->children; 147 148 if( pContent == NULL ) { 149 throw XMLEncryptionException() ; 150 } 151 152 xmlUnlinkNode(pContent); 153 xmlAddNextSibling(pEncryptedData, pContent); 154 155 //remember the position of the element to be signed 156 sal_Bool isParentRef = sal_True; 157 xmlNodePtr pParent = pEncryptedData->parent; 158 xmlNodePtr referenceNode; 159 160 if (pEncryptedData == pParent->children) 161 { 162 referenceNode = pParent; 163 } 164 else 165 { 166 referenceNode = pEncryptedData->prev; 167 isParentRef = sal_False; 168 } 169 170 setErrorRecorder( ); 171 172 pMngr = pSecEnv->createKeysManager() ; //i39448 173 if( !pMngr ) { 174 throw RuntimeException() ; 175 } 176 177 //Create Encryption context 178 pEncCtx = xmlSecEncCtxCreate( pMngr ) ; 179 if( pEncCtx == NULL ) 180 { 181 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 182 //throw XMLEncryptionException() ; 183 clearErrorRecorder(); 184 return aTemplate; 185 } 186 187 //Encrypt the template 188 if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) { 189 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 190 xmlSecEncCtxDestroy( pEncCtx ) ; 191 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 192 clearErrorRecorder(); 193 return aTemplate; 194 } 195 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); 196 xmlSecEncCtxDestroy( pEncCtx ) ; 197 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 198 199 //get the new EncryptedData element 200 if (isParentRef) 201 { 202 pTemplate->setNativeElement(referenceNode->children) ; 203 } 204 else 205 { 206 pTemplate->setNativeElement(referenceNode->next); 207 } 208 209 clearErrorRecorder(); 210 return aTemplate ; 211 } 212 213 /* XXMLEncryption */ 214 Reference< XXMLEncryptionTemplate > SAL_CALL 215 XMLEncryption_MSCryptImpl :: decrypt( 216 const Reference< XXMLEncryptionTemplate >& aTemplate , 217 const Reference< XXMLSecurityContext >& aSecurityCtx 218 ) throw( com::sun::star::xml::crypto::XMLEncryptionException , 219 com::sun::star::uno::SecurityException) { 220 xmlSecKeysMngrPtr pMngr = NULL ; 221 xmlSecEncCtxPtr pEncCtx = NULL ; 222 xmlNodePtr pEncryptedData = NULL ; 223 224 if( !aTemplate.is() ) 225 throw RuntimeException() ; 226 227 if( !aSecurityCtx.is() ) 228 throw RuntimeException() ; 229 230 //Get Keys Manager 231 Reference< XSecurityEnvironment > xSecEnv 232 = aSecurityCtx->getSecurityEnvironmentByIndex( 233 aSecurityCtx->getDefaultSecurityEnvironmentIndex()); 234 Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ; 235 if( !xSecTunnel.is() ) { 236 throw RuntimeException() ; 237 } 238 239 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; 240 if( pSecEnv == NULL ) 241 throw RuntimeException() ; 242 243 //Get the encryption template 244 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; 245 if( !xTemplate.is() ) { 246 throw RuntimeException() ; 247 } 248 249 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; 250 if( !xTplTunnel.is() ) { 251 throw RuntimeException() ; 252 } 253 254 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 255 if( pTemplate == NULL ) { 256 throw RuntimeException() ; 257 } 258 259 pEncryptedData = pTemplate->getNativeElement() ; 260 261 //remember the position of the element to be signed 262 sal_Bool isParentRef = sal_True; 263 xmlNodePtr pParent = pEncryptedData->parent; 264 xmlNodePtr referenceNode; 265 266 if (pEncryptedData == pParent->children) 267 { 268 referenceNode = pParent; 269 } 270 else 271 { 272 referenceNode = pEncryptedData->prev; 273 isParentRef = sal_False; 274 } 275 276 setErrorRecorder( ); 277 278 pMngr = pSecEnv->createKeysManager() ; //i39448 279 if( !pMngr ) { 280 throw RuntimeException() ; 281 } 282 283 //Create Encryption context 284 pEncCtx = xmlSecEncCtxCreate( pMngr ) ; 285 if( pEncCtx == NULL ) 286 { 287 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 288 //throw XMLEncryptionException() ; 289 clearErrorRecorder(); 290 return aTemplate; 291 } 292 293 //Decrypt the template 294 if( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ) { 295 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 296 xmlSecEncCtxDestroy( pEncCtx ) ; 297 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 298 299 //throw XMLEncryptionException() ; 300 clearErrorRecorder(); 301 return aTemplate; 302 } 303 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); 304 /*---------------------------------------- 305 if( pEncCtx->resultReplaced != 0 ) { 306 pContent = pEncryptedData ; 307 308 Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ; 309 if( !xTunnel.is() ) { 310 xmlSecEncCtxDestroy( pEncCtx ) ; 311 throw RuntimeException() ; 312 } 313 XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 314 if( pNode == NULL ) { 315 xmlSecEncCtxDestroy( pEncCtx ) ; 316 throw RuntimeException() ; 317 } 318 319 pNode->setNativeElement( pContent ) ; 320 } else { 321 xmlSecEncCtxDestroy( pEncCtx ) ; 322 throw RuntimeException() ; 323 } 324 ----------------------------------------*/ 325 326 //Destroy the encryption context 327 xmlSecEncCtxDestroy( pEncCtx ) ; 328 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 329 330 //get the decrypted element 331 XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef? 332 (referenceNode->children):(referenceNode->next)); 333 334 //return ret; 335 aTemplate->setTemplate(ret); 336 337 clearErrorRecorder(); 338 return aTemplate; 339 } 340 341 /* XInitialization */ 342 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { 343 // TBD 344 } ; 345 346 /* XServiceInfo */ 347 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { 348 return impl_getImplementationName() ; 349 } 350 351 /* XServiceInfo */ 352 sal_Bool SAL_CALL XMLEncryption_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { 353 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; 354 const OUString* pArray = seqServiceNames.getConstArray() ; 355 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { 356 if( *( pArray + i ) == serviceName ) 357 return sal_True ; 358 } 359 return sal_False ; 360 } 361 362 /* XServiceInfo */ 363 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { 364 return impl_getSupportedServiceNames() ; 365 } 366 367 //Helper for XServiceInfo 368 Sequence< OUString > XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() { 369 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 370 Sequence< OUString > seqServiceNames( 1 ) ; 371 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ; 372 return seqServiceNames ; 373 } 374 375 OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { 376 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ; 377 } 378 379 //Helper for registry 380 Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { 381 return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ; 382 } 383 384 Reference< XSingleServiceFactory > XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { 385 //Reference< XSingleServiceFactory > xFactory ; 386 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; 387 //return xFactory ; 388 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; 389 } 390 391