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 ) 79 { 80 xmlSecKeysMngrPtr pMngr = NULL ; 81 xmlSecEncCtxPtr pEncCtx = NULL ; 82 xmlNodePtr pEncryptedData = NULL ; 83 xmlNodePtr pContent = NULL ; 84 85 if( !aTemplate.is() ) 86 throw RuntimeException() ; 87 88 if( !aEnvironment.is() ) 89 throw RuntimeException() ; 90 91 //Get Keys Manager 92 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; 93 if( !xSecTunnel.is() ) { 94 throw RuntimeException() ; 95 } 96 97 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; 98 if( pSecEnv == NULL ) 99 throw RuntimeException() ; 100 101 //Get the encryption template 102 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; 103 if( !xTemplate.is() ) { 104 throw RuntimeException() ; 105 } 106 107 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; 108 if( !xTplTunnel.is() ) { 109 throw RuntimeException() ; 110 } 111 112 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 113 if( pTemplate == NULL ) { 114 throw RuntimeException() ; 115 } 116 117 pEncryptedData = pTemplate->getNativeElement() ; 118 119 //Find the element to be encrypted. 120 //This element is wrapped in the CipherValue sub-element. 121 xmlNodePtr pCipherData = pEncryptedData->children; 122 while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData")) 123 { 124 pCipherData = pCipherData->next; 125 } 126 127 if( pCipherData == NULL ) { 128 throw XMLEncryptionException() ; 129 } 130 131 xmlNodePtr pCipherValue = pCipherData->children; 132 while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue")) 133 { 134 pCipherValue = pCipherValue->next; 135 } 136 137 if( pCipherValue == NULL ) { 138 throw XMLEncryptionException() ; 139 } 140 141 pContent = pCipherValue->children; 142 143 if( pContent == NULL ) { 144 throw XMLEncryptionException() ; 145 } 146 147 xmlUnlinkNode(pContent); 148 xmlAddNextSibling(pEncryptedData, pContent); 149 150 //remember the position of the element to be signed 151 sal_Bool isParentRef = sal_True; 152 xmlNodePtr pParent = pEncryptedData->parent; 153 xmlNodePtr referenceNode; 154 155 if (pEncryptedData == pParent->children) 156 { 157 referenceNode = pParent; 158 } 159 else 160 { 161 referenceNode = pEncryptedData->prev; 162 isParentRef = sal_False; 163 } 164 165 setErrorRecorder( ); 166 167 pMngr = pSecEnv->createKeysManager() ; //i39448 168 if( !pMngr ) { 169 throw RuntimeException() ; 170 } 171 172 //Create Encryption context 173 pEncCtx = xmlSecEncCtxCreate( pMngr ) ; 174 if( pEncCtx == NULL ) 175 { 176 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 177 //throw XMLEncryptionException() ; 178 clearErrorRecorder(); 179 return aTemplate; 180 } 181 182 //Encrypt the template 183 if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) { 184 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 185 xmlSecEncCtxDestroy( pEncCtx ) ; 186 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 187 clearErrorRecorder(); 188 return aTemplate; 189 } 190 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); 191 xmlSecEncCtxDestroy( pEncCtx ) ; 192 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 193 194 //get the new EncryptedData element 195 if (isParentRef) 196 { 197 pTemplate->setNativeElement(referenceNode->children) ; 198 } 199 else 200 { 201 pTemplate->setNativeElement(referenceNode->next); 202 } 203 204 clearErrorRecorder(); 205 return aTemplate ; 206 } 207 208 /* XXMLEncryption */ 209 Reference< XXMLEncryptionTemplate > SAL_CALL 210 XMLEncryption_MSCryptImpl :: decrypt( 211 const Reference< XXMLEncryptionTemplate >& aTemplate , 212 const Reference< XXMLSecurityContext >& aSecurityCtx 213 ) { 214 xmlSecKeysMngrPtr pMngr = NULL ; 215 xmlSecEncCtxPtr pEncCtx = NULL ; 216 xmlNodePtr pEncryptedData = NULL ; 217 218 if( !aTemplate.is() ) 219 throw RuntimeException() ; 220 221 if( !aSecurityCtx.is() ) 222 throw RuntimeException() ; 223 224 //Get Keys Manager 225 Reference< XSecurityEnvironment > xSecEnv 226 = aSecurityCtx->getSecurityEnvironmentByIndex( 227 aSecurityCtx->getDefaultSecurityEnvironmentIndex()); 228 Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ; 229 if( !xSecTunnel.is() ) { 230 throw RuntimeException() ; 231 } 232 233 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; 234 if( pSecEnv == NULL ) 235 throw RuntimeException() ; 236 237 //Get the encryption template 238 Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; 239 if( !xTemplate.is() ) { 240 throw RuntimeException() ; 241 } 242 243 Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; 244 if( !xTplTunnel.is() ) { 245 throw RuntimeException() ; 246 } 247 248 XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 249 if( pTemplate == NULL ) { 250 throw RuntimeException() ; 251 } 252 253 pEncryptedData = pTemplate->getNativeElement() ; 254 255 //remember the position of the element to be signed 256 sal_Bool isParentRef = sal_True; 257 xmlNodePtr pParent = pEncryptedData->parent; 258 xmlNodePtr referenceNode; 259 260 if (pEncryptedData == pParent->children) 261 { 262 referenceNode = pParent; 263 } 264 else 265 { 266 referenceNode = pEncryptedData->prev; 267 isParentRef = sal_False; 268 } 269 270 setErrorRecorder( ); 271 272 pMngr = pSecEnv->createKeysManager() ; //i39448 273 if( !pMngr ) { 274 throw RuntimeException() ; 275 } 276 277 //Create Encryption context 278 pEncCtx = xmlSecEncCtxCreate( pMngr ) ; 279 if( pEncCtx == NULL ) 280 { 281 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 282 //throw XMLEncryptionException() ; 283 clearErrorRecorder(); 284 return aTemplate; 285 } 286 287 //Decrypt the template 288 if( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ) { 289 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 290 xmlSecEncCtxDestroy( pEncCtx ) ; 291 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 292 293 //throw XMLEncryptionException() ; 294 clearErrorRecorder(); 295 return aTemplate; 296 } 297 aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); 298 /*---------------------------------------- 299 if( pEncCtx->resultReplaced != 0 ) { 300 pContent = pEncryptedData ; 301 302 Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ; 303 if( !xTunnel.is() ) { 304 xmlSecEncCtxDestroy( pEncCtx ) ; 305 throw RuntimeException() ; 306 } 307 XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 308 if( pNode == NULL ) { 309 xmlSecEncCtxDestroy( pEncCtx ) ; 310 throw RuntimeException() ; 311 } 312 313 pNode->setNativeElement( pContent ) ; 314 } else { 315 xmlSecEncCtxDestroy( pEncCtx ) ; 316 throw RuntimeException() ; 317 } 318 ----------------------------------------*/ 319 320 //Destroy the encryption context 321 xmlSecEncCtxDestroy( pEncCtx ) ; 322 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 323 324 //get the decrypted element 325 XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef? 326 (referenceNode->children):(referenceNode->next)); 327 328 //return ret; 329 aTemplate->setTemplate(ret); 330 331 clearErrorRecorder(); 332 return aTemplate; 333 } 334 335 /* XInitialization */ 336 void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) { 337 // TBD 338 } ; 339 340 /* XServiceInfo */ 341 OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() { 342 return impl_getImplementationName() ; 343 } 344 345 /* XServiceInfo */ 346 sal_Bool SAL_CALL XMLEncryption_MSCryptImpl :: supportsService( const OUString& serviceName) { 347 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; 348 const OUString* pArray = seqServiceNames.getConstArray() ; 349 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { 350 if( *( pArray + i ) == serviceName ) 351 return sal_True ; 352 } 353 return sal_False ; 354 } 355 356 /* XServiceInfo */ 357 Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() { 358 return impl_getSupportedServiceNames() ; 359 } 360 361 //Helper for XServiceInfo 362 Sequence< OUString > XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() { 363 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 364 Sequence< OUString > seqServiceNames( 1 ) ; 365 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ; 366 return seqServiceNames ; 367 } 368 369 OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() { 370 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ; 371 } 372 373 //Helper for registry 374 Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) { 375 return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ; 376 } 377 378 Reference< XSingleServiceFactory > XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { 379 //Reference< XSingleServiceFactory > xFactory ; 380 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; 381 //return xFactory ; 382 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; 383 } 384