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 #include <sal/config.h> 27 #include <rtl/uuid.h> 28 #include "xmlencryption_nssimpl.hxx" 29 30 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_ 31 #include "xmldocumentwrapper_xmlsecimpl.hxx" 32 #endif 33 34 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_ 35 #include "xmlelementwrapper_xmlsecimpl.hxx" 36 #endif 37 38 #ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_ 39 #include "securityenvironment_nssimpl.hxx" 40 #endif 41 #include "errorcallback.hxx" 42 43 #include <sal/types.h> 44 //For reasons that escape me, this is what xmlsec does when size_t is not 4 45 #if SAL_TYPES_SIZEOFPOINTER != 4 46 # define XMLSEC_NO_SIZE_T 47 #endif 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::XSecurityEnvironment ; 70 using ::com::sun::star::xml::crypto::XMLEncryptionException ; 71 72 XMLEncryption_NssImpl :: XMLEncryption_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { 73 } 74 75 XMLEncryption_NssImpl :: ~XMLEncryption_NssImpl() { 76 } 77 78 /* XXMLEncryption */ 79 Reference< XXMLEncryptionTemplate > 80 SAL_CALL XMLEncryption_NssImpl :: encrypt( 81 const Reference< XXMLEncryptionTemplate >& aTemplate , 82 const Reference< XSecurityEnvironment >& aEnvironment 83 ) 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 #if 0 103 XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ; 104 if( pSecCtxt == NULL ) 105 throw RuntimeException() ; 106 #endif 107 108 SecurityEnvironment_NssImpl* pSecEnv = 109 reinterpret_cast<SecurityEnvironment_NssImpl*>( 110 sal::static_int_cast<sal_uIntPtr>(xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ; 111 if( pSecEnv == NULL ) 112 throw RuntimeException() ; 113 114 //Get the encryption template 115 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; 116 if( !xTemplate.is() ) { 117 throw RuntimeException() ; 118 } 119 120 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; 121 if( !xTplTunnel.is() ) { 122 throw RuntimeException() ; 123 } 124 125 XMLElementWrapper_XmlSecImpl* pTemplate = 126 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( 127 sal::static_int_cast<sal_uIntPtr>( 128 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); 129 if( pTemplate == NULL ) { 130 throw RuntimeException() ; 131 } 132 133 //MM : Get the element to be encrypted 134 Reference< XXMLElementWrapper > xTarget = aTemplate->getTarget() ; 135 if( !xTarget.is() ) { 136 throw XMLEncryptionException() ; 137 } 138 139 Reference< XUnoTunnel > xTgtTunnel( xTarget , UNO_QUERY ) ; 140 if( !xTgtTunnel.is() ) { 141 throw XMLEncryptionException() ; 142 } 143 144 XMLElementWrapper_XmlSecImpl* pTarget = 145 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( 146 sal::static_int_cast<sal_uIntPtr>( 147 xTgtTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); 148 if( pTarget == NULL ) { 149 throw RuntimeException() ; 150 } 151 152 pContent = pTarget->getNativeElement() ; 153 //MM : end 154 155 if( pContent == NULL ) { 156 throw XMLEncryptionException() ; 157 } 158 159 /* MM : remove the following 2 lines 160 xmlUnlinkNode(pContent); 161 xmlAddNextSibling(pEncryptedData, pContent); 162 */ 163 164 //remember the position of the element to be signed 165 sal_Bool isParentRef = sal_True; 166 xmlNodePtr pParent = pEncryptedData->parent; 167 xmlNodePtr referenceNode; 168 169 if (pEncryptedData == pParent->children) 170 { 171 referenceNode = pParent; 172 } 173 else 174 { 175 referenceNode = pEncryptedData->prev; 176 isParentRef = sal_False; 177 } 178 179 setErrorRecorder( ); 180 181 pMngr = pSecEnv->createKeysManager() ; //i39448 182 if( !pMngr ) { 183 throw RuntimeException() ; 184 } 185 186 //Create Encryption context 187 pEncCtx = xmlSecEncCtxCreate( pMngr ) ; 188 if( pEncCtx == NULL ) 189 { 190 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 191 //throw XMLEncryptionException() ; 192 clearErrorRecorder(); 193 return aTemplate; 194 } 195 196 pEncryptedData = pTemplate->getNativeElement() ; 197 198 //Find the element to be encrypted. 199 /* MM : remove the old method to get the target element 200 //This element is wrapped in the CipherValue sub-element. 201 xmlNodePtr pCipherData = pEncryptedData->children; 202 while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData")) 203 { 204 pCipherData = pCipherData->next; 205 } 206 207 if( pCipherData == NULL ) { 208 xmlSecEncCtxDestroy( pEncCtx ) ; 209 throw XMLEncryptionException() ; 210 } 211 212 xmlNodePtr pCipherValue = pCipherData->children; 213 while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue")) 214 { 215 pCipherValue = pCipherValue->next; 216 } 217 218 if( pCipherValue == NULL ) { 219 xmlSecEncCtxDestroy( pEncCtx ) ; 220 throw XMLEncryptionException() ; 221 } 222 223 pContent = pCipherValue->children; 224 */ 225 226 //Encrypt the template 227 if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) 228 { 229 xmlSecEncCtxDestroy( pEncCtx ) ; 230 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 231 232 //throw XMLEncryptionException() ; 233 clearErrorRecorder(); 234 return aTemplate; 235 } 236 237 xmlSecEncCtxDestroy( pEncCtx ) ; 238 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 239 240 //get the new EncryptedData element 241 if (isParentRef) 242 { 243 pTemplate->setNativeElement(referenceNode->children) ; 244 } 245 else 246 { 247 pTemplate->setNativeElement(referenceNode->next); 248 } 249 250 return aTemplate ; 251 } 252 253 /* XXMLEncryption */ 254 Reference< XXMLEncryptionTemplate > 255 SAL_CALL XMLEncryption_NssImpl :: decrypt( 256 const Reference< XXMLEncryptionTemplate >& aTemplate , 257 const Reference< XXMLSecurityContext >& aSecurityCtx 258 ) { 259 xmlSecKeysMngrPtr pMngr = NULL ; 260 xmlSecEncCtxPtr pEncCtx = NULL ; 261 xmlNodePtr pEncryptedData = NULL ; 262 263 if( !aTemplate.is() ) 264 throw RuntimeException() ; 265 266 if( !aSecurityCtx.is() ) 267 throw RuntimeException() ; 268 269 //Get the encryption template 270 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; 271 if( !xTemplate.is() ) { 272 throw RuntimeException() ; 273 } 274 275 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; 276 if( !xTplTunnel.is() ) { 277 throw RuntimeException() ; 278 } 279 280 XMLElementWrapper_XmlSecImpl* pTemplate = 281 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( 282 sal::static_int_cast<sal_uIntPtr>( 283 xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); 284 if( pTemplate == NULL ) { 285 throw RuntimeException() ; 286 } 287 288 pEncryptedData = pTemplate->getNativeElement() ; 289 290 //remember the position of the element to be signed 291 sal_Bool isParentRef = sal_True; 292 xmlNodePtr pParent = pEncryptedData->parent; 293 xmlNodePtr referenceNode; 294 295 if (pEncryptedData == pParent->children) 296 { 297 referenceNode = pParent; 298 } 299 else 300 { 301 referenceNode = pEncryptedData->prev; 302 isParentRef = sal_False; 303 } 304 305 setErrorRecorder( ); 306 307 sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber(); 308 sal_Int32 i; 309 310 for (i=0; i<nSecurityEnvironment; ++i) 311 { 312 Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i); 313 314 //Get Keys Manager 315 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; 316 if( !aEnvironment.is() ) { 317 throw RuntimeException() ; 318 } 319 320 SecurityEnvironment_NssImpl* pSecEnv = 321 reinterpret_cast<SecurityEnvironment_NssImpl*>( 322 sal::static_int_cast<sal_uIntPtr>( 323 xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))); 324 if( pSecEnv == NULL ) 325 throw RuntimeException() ; 326 327 pMngr = pSecEnv->createKeysManager() ; //i39448 328 if( !pMngr ) { 329 throw RuntimeException() ; 330 } 331 332 //Create Encryption context 333 pEncCtx = xmlSecEncCtxCreate( pMngr ) ; 334 if( pEncCtx == NULL ) 335 { 336 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 337 //throw XMLEncryptionException() ; 338 clearErrorRecorder(); 339 return aTemplate; 340 } 341 342 //Decrypt the template 343 if(!( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL )) 344 { 345 //The decryption succeeds 346 347 //Destroy the encryption context 348 xmlSecEncCtxDestroy( pEncCtx ) ; 349 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 350 351 //get the decrypted element 352 XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef? 353 (referenceNode->children):(referenceNode->next)); 354 355 //return ret; 356 aTemplate->setTemplate(ret); 357 break; 358 } 359 else 360 { 361 //The decryption fails, continue with the next security environment 362 xmlSecEncCtxDestroy( pEncCtx ) ; 363 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 364 } 365 } 366 367 clearErrorRecorder(); 368 return aTemplate; 369 } 370 371 /* XInitialization */ 372 void SAL_CALL XMLEncryption_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) { 373 // TBD 374 } ; 375 376 /* XServiceInfo */ 377 OUString SAL_CALL XMLEncryption_NssImpl :: getImplementationName() { 378 return impl_getImplementationName() ; 379 } 380 381 /* XServiceInfo */ 382 sal_Bool SAL_CALL XMLEncryption_NssImpl :: supportsService( const OUString& serviceName) { 383 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; 384 const OUString* pArray = seqServiceNames.getConstArray() ; 385 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { 386 if( *( pArray + i ) == serviceName ) 387 return sal_True ; 388 } 389 return sal_False ; 390 } 391 392 /* XServiceInfo */ 393 Sequence< OUString > SAL_CALL XMLEncryption_NssImpl :: getSupportedServiceNames() { 394 return impl_getSupportedServiceNames() ; 395 } 396 397 //Helper for XServiceInfo 398 Sequence< OUString > XMLEncryption_NssImpl :: impl_getSupportedServiceNames() { 399 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 400 Sequence< OUString > seqServiceNames( 1 ) ; 401 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ; 402 return seqServiceNames ; 403 } 404 405 OUString XMLEncryption_NssImpl :: impl_getImplementationName() { 406 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl" ) ; 407 } 408 409 //Helper for registry 410 Reference< XInterface > SAL_CALL XMLEncryption_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) { 411 return Reference< XInterface >( *new XMLEncryption_NssImpl( aServiceManager ) ) ; 412 } 413 414 Reference< XSingleServiceFactory > XMLEncryption_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { 415 //Reference< XSingleServiceFactory > xFactory ; 416 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; 417 //return xFactory ; 418 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; 419 } 420