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 67 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { 68 } 69 70 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() { 71 } 72 73 /* XXMLEncryption */ 74 Reference< XXMLEncryptionTemplate > 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 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 */ 338 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { 339 // TBD 340 } ; 341 342 /* XServiceInfo */ 343 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { 344 return impl_getImplementationName() ; 345 } 346 347 /* XServiceInfo */ 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 */ 359 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { 360 return impl_getSupportedServiceNames() ; 361 } 362 363 //Helper for XServiceInfo 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 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 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 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