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