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 #include <sal/config.h> 31 #include <rtl/uuid.h> 32 #include "xmlsignature_nssimpl.hxx" 33 34 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_ 35 #include "xmldocumentwrapper_xmlsecimpl.hxx" 36 #endif 37 38 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_ 39 #include "xmlelementwrapper_xmlsecimpl.hxx" 40 #endif 41 42 #ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_ 43 #include "securityenvironment_nssimpl.hxx" 44 #endif 45 46 #ifndef _XMLSECURITYCONTEXT_NSSIMPL_HXX_ 47 #include "xmlsecuritycontext_nssimpl.hxx" 48 #endif 49 #include "xmlstreamio.hxx" 50 #include "errorcallback.hxx" 51 52 #include <sal/types.h> 53 //For reasons that escape me, this is what xmlsec does when size_t is not 4 54 #if SAL_TYPES_SIZEOFPOINTER != 4 55 # define XMLSEC_NO_SIZE_T 56 #endif 57 #include "xmlsec/xmlsec.h" 58 #include "xmlsec/xmldsig.h" 59 #include "xmlsec/crypto.h" 60 61 using namespace ::com::sun::star::uno ; 62 using namespace ::com::sun::star::lang ; 63 using ::com::sun::star::lang::XMultiServiceFactory ; 64 using ::com::sun::star::lang::XSingleServiceFactory ; 65 using ::rtl::OUString ; 66 67 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ; 68 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ; 69 using ::com::sun::star::xml::crypto::XSecurityEnvironment ; 70 using ::com::sun::star::xml::crypto::XXMLSignature ; 71 using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ; 72 using ::com::sun::star::xml::crypto::XSecurityEnvironment ; 73 using ::com::sun::star::xml::crypto::XXMLSecurityContext ; 74 using ::com::sun::star::xml::crypto::XUriBinding ; 75 using ::com::sun::star::xml::crypto::XMLSignatureException ; 76 77 XMLSignature_NssImpl :: XMLSignature_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { 78 } 79 80 XMLSignature_NssImpl :: ~XMLSignature_NssImpl() { 81 } 82 83 /* XXMLSignature */ 84 Reference< XXMLSignatureTemplate > 85 SAL_CALL XMLSignature_NssImpl :: generate( 86 const Reference< XXMLSignatureTemplate >& aTemplate , 87 const Reference< XSecurityEnvironment >& aEnvironment 88 ) throw( com::sun::star::xml::crypto::XMLSignatureException, 89 com::sun::star::uno::SecurityException ) 90 { 91 xmlSecKeysMngrPtr pMngr = NULL ; 92 xmlSecDSigCtxPtr pDsigCtx = NULL ; 93 xmlNodePtr pNode = NULL ; 94 95 if( !aTemplate.is() ) 96 throw RuntimeException() ; 97 98 if( !aEnvironment.is() ) 99 throw RuntimeException() ; 100 101 //Get the xml node 102 Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ; 103 if( !xElement.is() ) { 104 throw RuntimeException() ; 105 } 106 107 Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ; 108 if( !xNodTunnel.is() ) { 109 throw RuntimeException() ; 110 } 111 112 XMLElementWrapper_XmlSecImpl* pElement = 113 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( 114 sal::static_int_cast<sal_uIntPtr>( 115 xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); 116 if( pElement == NULL ) { 117 throw RuntimeException() ; 118 } 119 120 pNode = pElement->getNativeElement() ; 121 122 //Get the stream/URI binding 123 Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ; 124 if( xUriBinding.is() ) { 125 //Register the stream input callbacks into libxml2 126 if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 ) 127 throw RuntimeException() ; 128 } 129 130 //Get Keys Manager 131 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; 132 if( !xSecTunnel.is() ) { 133 throw RuntimeException() ; 134 } 135 136 #if 0 //i39448 : the key manager should be retrieved from SecurityEnvironment, instead of SecurityContext 137 XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ; 138 if( pSecCtxt == NULL ) 139 throw RuntimeException() ; 140 #endif 141 142 SecurityEnvironment_NssImpl* pSecEnv = 143 reinterpret_cast<SecurityEnvironment_NssImpl*>( 144 sal::static_int_cast<sal_uIntPtr>( 145 xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))); 146 if( pSecEnv == NULL ) 147 throw RuntimeException() ; 148 149 setErrorRecorder(); 150 151 pMngr = pSecEnv->createKeysManager() ; //i39448 152 if( !pMngr ) { 153 throw RuntimeException() ; 154 } 155 156 //Create Signature context 157 pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ; 158 if( pDsigCtx == NULL ) 159 { 160 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 161 //throw XMLSignatureException() ; 162 clearErrorRecorder(); 163 return aTemplate; 164 } 165 166 //Sign the template 167 if( xmlSecDSigCtxSign( pDsigCtx , pNode ) == 0 ) 168 { 169 if (pDsigCtx->status == xmlSecDSigStatusSucceeded) 170 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); 171 else 172 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 173 } 174 else 175 { 176 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 177 } 178 179 180 xmlSecDSigCtxDestroy( pDsigCtx ) ; 181 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 182 183 //Unregistered the stream/URI binding 184 if( xUriBinding.is() ) 185 xmlUnregisterStreamInputCallbacks() ; 186 187 clearErrorRecorder(); 188 return aTemplate ; 189 } 190 191 /* XXMLSignature */ 192 Reference< XXMLSignatureTemplate > 193 SAL_CALL XMLSignature_NssImpl :: validate( 194 const Reference< XXMLSignatureTemplate >& aTemplate , 195 const Reference< XXMLSecurityContext >& aSecurityCtx 196 ) throw( com::sun::star::uno::RuntimeException, 197 com::sun::star::uno::SecurityException, 198 com::sun::star::xml::crypto::XMLSignatureException ) { 199 xmlSecKeysMngrPtr pMngr = NULL ; 200 xmlSecDSigCtxPtr pDsigCtx = NULL ; 201 xmlNodePtr pNode = NULL ; 202 //sal_Bool valid ; 203 204 if( !aTemplate.is() ) 205 throw RuntimeException() ; 206 207 if( !aSecurityCtx.is() ) 208 throw RuntimeException() ; 209 210 //Get the xml node 211 Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ; 212 if( !xElement.is() ) 213 throw RuntimeException() ; 214 215 Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ; 216 if( !xNodTunnel.is() ) { 217 throw RuntimeException() ; 218 } 219 220 XMLElementWrapper_XmlSecImpl* pElement = 221 reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( 222 sal::static_int_cast<sal_uIntPtr>( 223 xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); 224 if( pElement == NULL ) 225 throw RuntimeException() ; 226 227 pNode = pElement->getNativeElement() ; 228 229 //Get the stream/URI binding 230 Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ; 231 if( xUriBinding.is() ) { 232 //Register the stream input callbacks into libxml2 233 if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 ) 234 throw RuntimeException() ; 235 } 236 237 setErrorRecorder(); 238 239 sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber(); 240 sal_Int32 i; 241 242 for (i=0; i<nSecurityEnvironment; ++i) 243 { 244 Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i); 245 246 //Get Keys Manager 247 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; 248 if( !xSecTunnel.is() ) { 249 throw RuntimeException() ; 250 } 251 252 SecurityEnvironment_NssImpl* pSecEnv = 253 reinterpret_cast<SecurityEnvironment_NssImpl*>( 254 sal::static_int_cast<sal_uIntPtr>( 255 xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))); 256 if( pSecEnv == NULL ) 257 throw RuntimeException() ; 258 259 pMngr = pSecEnv->createKeysManager() ; //i39448 260 if( !pMngr ) { 261 throw RuntimeException() ; 262 } 263 264 //Create Signature context 265 pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ; 266 if( pDsigCtx == NULL ) 267 { 268 pSecEnv->destroyKeysManager( pMngr ) ; //i39448 269 //throw XMLSignatureException() ; 270 clearErrorRecorder(); 271 return aTemplate; 272 } 273 274 //Verify signature 275 int rs = xmlSecDSigCtxVerify( pDsigCtx , pNode ); 276 277 278 if (rs == 0 && 279 pDsigCtx->status == xmlSecDSigStatusSucceeded) 280 { 281 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); 282 xmlSecDSigCtxDestroy( pDsigCtx ) ; 283 pSecEnv->destroyKeysManager( pMngr ); 284 break; 285 } 286 else 287 { 288 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); 289 } 290 xmlSecDSigCtxDestroy( pDsigCtx ) ; 291 pSecEnv->destroyKeysManager( pMngr ); 292 } 293 294 295 296 //Unregistered the stream/URI binding 297 if( xUriBinding.is() ) 298 xmlUnregisterStreamInputCallbacks() ; 299 300 //return valid ; 301 clearErrorRecorder(); 302 return aTemplate; 303 } 304 305 /* XInitialization */ 306 void SAL_CALL XMLSignature_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { 307 // TBD 308 } ; 309 310 /* XServiceInfo */ 311 OUString SAL_CALL XMLSignature_NssImpl :: getImplementationName() throw( RuntimeException ) { 312 return impl_getImplementationName() ; 313 } 314 315 /* XServiceInfo */ 316 sal_Bool SAL_CALL XMLSignature_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { 317 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; 318 const OUString* pArray = seqServiceNames.getConstArray() ; 319 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { 320 if( *( pArray + i ) == serviceName ) 321 return sal_True ; 322 } 323 return sal_False ; 324 } 325 326 /* XServiceInfo */ 327 Sequence< OUString > SAL_CALL XMLSignature_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) { 328 return impl_getSupportedServiceNames() ; 329 } 330 331 //Helper for XServiceInfo 332 Sequence< OUString > XMLSignature_NssImpl :: impl_getSupportedServiceNames() { 333 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 334 Sequence< OUString > seqServiceNames( 1 ) ; 335 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignature" ) ; 336 return seqServiceNames ; 337 } 338 339 OUString XMLSignature_NssImpl :: impl_getImplementationName() throw( RuntimeException ) { 340 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl" ) ; 341 } 342 343 //Helper for registry 344 Reference< XInterface > SAL_CALL XMLSignature_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { 345 return Reference< XInterface >( *new XMLSignature_NssImpl( aServiceManager ) ) ; 346 } 347 348 Reference< XSingleServiceFactory > XMLSignature_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { 349 //Reference< XSingleServiceFactory > xFactory ; 350 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; 351 //return xFactory ; 352 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; 353 } 354 355