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 /** -- C++ Source File -- **/ 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmlsecurity.hxx" 26 #include <stdio.h> 27 #include "helper.hxx" 28 29 #include "libxml/tree.h" 30 #include "libxml/parser.h" 31 #ifndef XMLSEC_NO_XSLT 32 #include "libxslt/xslt.h" 33 #endif 34 35 #include "securityenvironment_mscryptimpl.hxx" 36 #include "xmlelementwrapper_xmlsecimpl.hxx" 37 38 #include "xmlsec/strings.h" 39 #include "xmlsec/mscrypto/app.h" 40 #include "xmlsec/xmltree.h" 41 42 #include <rtl/ustring.hxx> 43 44 #include <com/sun/star/beans/PropertyValue.hpp> 45 #include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp> 46 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp> 47 #include <com/sun/star/xml/crypto/XXMLSignature.hpp> 48 #include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp> 49 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> 50 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 51 52 using namespace ::rtl ; 53 using namespace ::cppu ; 54 using namespace ::com::sun::star::uno ; 55 using namespace ::com::sun::star::io ; 56 using namespace ::com::sun::star::ucb ; 57 using namespace ::com::sun::star::beans ; 58 using namespace ::com::sun::star::document ; 59 using namespace ::com::sun::star::lang ; 60 using namespace ::com::sun::star::xml::wrapper ; 61 using namespace ::com::sun::star::xml::crypto ; 62 63 64 int SAL_CALL main( int argc, char **argv ) 65 { 66 const char* n_pCertStore ; 67 HCERTSTORE n_hStoreHandle ; 68 69 xmlDocPtr doc = NULL ; 70 xmlNodePtr tplNode ; 71 xmlNodePtr tarNode ; 72 xmlAttrPtr idAttr ; 73 xmlChar* idValue ; 74 xmlAttrPtr uriAttr ; 75 xmlChar* uriValue ; 76 OUString* uri = NULL ; 77 Reference< XUriBinding > xUriBinding ; 78 FILE* dstFile = NULL ; 79 80 if( argc !=4 && argc != 5 ) { 81 fprintf( stderr, "Usage: %s <file_url of template> <file_url of result> <rdb file>\n" , argv[0] ) ; 82 fprintf( stderr, "Or: \t%s <file_url of template> <file_url of result> <rdb file> < Cert Store Name >\n\n" , argv[0] ) ; 83 return 1 ; 84 } 85 86 for( int hhh = 0 ; hhh < 4 ; hhh ++ ) { 87 88 //Init libxml and libxslt libraries 89 xmlInitParser(); 90 LIBXML_TEST_VERSION 91 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 92 xmlSubstituteEntitiesDefault(1); 93 94 #ifndef XMLSEC_NO_XSLT 95 xmlIndentTreeOutput = 1; 96 #endif // XMLSEC_NO_XSLT 97 98 //Initialize the crypto engine 99 if( argc == 5 ) { 100 n_pCertStore = argv[4] ; 101 n_hStoreHandle = CertOpenSystemStore( NULL, n_pCertStore ) ; 102 if( n_hStoreHandle == NULL ) { 103 fprintf( stderr, "Can not open the system cert store %s\n", n_pCertStore ) ; 104 return 1 ; 105 } 106 } else { 107 n_pCertStore = NULL ; 108 n_hStoreHandle = NULL ; 109 } 110 xmlSecMSCryptoAppInit( n_pCertStore ) ; 111 112 //Load XML document 113 doc = xmlParseFile( argv[1] ) ; 114 if( doc == NULL || xmlDocGetRootElement( doc ) == NULL ) { 115 fprintf( stderr , "### Cannot load template xml document!\n" ) ; 116 goto done ; 117 } 118 119 //Find the signature template 120 tplNode = xmlSecFindNode( xmlDocGetRootElement( doc ), xmlSecNodeSignature, xmlSecDSigNs ) ; 121 if( tplNode == NULL ) { 122 fprintf( stderr , "### Cannot find the signature template!\n" ) ; 123 goto done ; 124 } 125 126 //Find the element with ID attribute 127 //Here we only try to find the "document" node. 128 tarNode = xmlSecFindNode( xmlDocGetRootElement( doc ), ( xmlChar* )"document", ( xmlChar* )"http://openoffice.org/2000/office" ) ; 129 if( tarNode == NULL ) { 130 tarNode = xmlSecFindNode( xmlDocGetRootElement( doc ), ( xmlChar* )"document", NULL ) ; 131 } 132 133 //Find the "id" attrbute in the element 134 if( tarNode != NULL ) { 135 if( ( idAttr = xmlHasProp( tarNode, ( xmlChar* )"id" ) ) != NULL ) { 136 //NULL 137 } else if( ( idAttr = xmlHasProp( tarNode, ( xmlChar* )"Id" ) ) != NULL ) { 138 //NULL 139 } else { 140 idAttr = NULL ; 141 } 142 } 143 144 //Add ID to DOM 145 if( idAttr != NULL ) { 146 idValue = xmlNodeListGetString( tarNode->doc, idAttr->children, 1 ) ; 147 if( idValue == NULL ) { 148 fprintf( stderr , "### the ID value is NULL!\n" ) ; 149 goto done ; 150 } 151 152 if( xmlAddID( NULL, doc, idValue, idAttr ) == NULL ) { 153 fprintf( stderr , "### Can not add the ID value!\n" ) ; 154 goto done ; 155 } 156 } 157 158 //Reference handler 159 //Find the signature reference 160 tarNode = xmlSecFindNode( tplNode, xmlSecNodeReference, xmlSecDSigNs ) ; 161 if( tarNode == NULL ) { 162 fprintf( stderr , "### Cannot find the signature reference!\n" ) ; 163 goto done ; 164 } 165 166 //Find the "URI" attrbute in the reference 167 uriAttr = xmlHasProp( tarNode, ( xmlChar* )"URI" ) ; 168 if( tarNode == NULL ) { 169 fprintf( stderr , "### Cannot find URI of the reference!\n" ) ; 170 goto done ; 171 } 172 173 //Get the "URI" attrbute value 174 uriValue = xmlNodeListGetString( tarNode->doc, uriAttr->children, 1 ) ; 175 if( uriValue == NULL ) { 176 fprintf( stderr , "### the URI value is NULL!\n" ) ; 177 goto done ; 178 } 179 180 if( strchr( ( const char* )uriValue, '/' ) != NULL && strchr( ( const char* )uriValue, '#' ) == NULL ) { 181 fprintf( stdout , "### Find a stream URI [%s]\n", uriValue ) ; 182 // uri = new ::rtl::OUString( ( const sal_Unicode* )uriValue ) ; 183 uri = new ::rtl::OUString( ( const sal_Char* )uriValue, xmlStrlen( uriValue ), RTL_TEXTENCODING_ASCII_US ) ; 184 } 185 186 if( uri != NULL ) { 187 fprintf( stdout , "### Find the URI [%s]\n", OUStringToOString( *uri , RTL_TEXTENCODING_ASCII_US ).getStr() ) ; 188 Reference< XInputStream > xStream = createStreamFromFile( *uri ) ; 189 if( !xStream.is() ) { 190 fprintf( stderr , "### Can not get the URI stream!\n" ) ; 191 goto done ; 192 } 193 194 xUriBinding = new OUriBinding( *uri, xStream ) ; 195 } 196 197 try { 198 Reference< XMultiComponentFactory > xManager = NULL ; 199 Reference< XComponentContext > xContext = NULL ; 200 201 xManager = serviceManager( xContext , OUString::createFromAscii( "local" ), OUString::createFromAscii( argv[3] ) ) ; 202 OSL_ENSURE( xManager.is() , 203 "ServicesManager - " 204 "Cannot get service manager" ) ; 205 206 //Create signature template 207 Reference< XInterface > element = 208 xManager->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLElementWrapper_XmlSecImpl" ) , xContext ) ; 209 OSL_ENSURE( element.is() , 210 "Signer - " 211 "Cannot get service instance of \"wrapper.XMLElementWrapper\"" ) ; 212 213 Reference< XXMLElementWrapper > xElement( element , UNO_QUERY ) ; 214 OSL_ENSURE( xElement.is() , 215 "Signer - " 216 "Cannot get interface of \"XXMLElement\" from service \"xsec.XMLElement\"" ) ; 217 218 Reference< XUnoTunnel > xEleTunnel( xElement , UNO_QUERY ) ; 219 OSL_ENSURE( xEleTunnel.is() , 220 "Signer - " 221 "Cannot get interface of \"XUnoTunnel\" from service \"xsec.XMLElement\"" ) ; 222 223 XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xEleTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; 224 OSL_ENSURE( pElement != NULL , 225 "Signer - " 226 "Cannot get implementation of \"xsec.XMLElement\"" ) ; 227 228 //Set signature template 229 pElement->setNativeElement( tplNode ) ; 230 231 //Build XML Signature template 232 Reference< XInterface > signtpl = 233 xManager->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignatureTemplate" ) , xContext ) ; 234 OSL_ENSURE( signtpl.is() , 235 "Signer - " 236 "Cannot get service instance of \"xsec.XMLSignatureTemplate\"" ) ; 237 238 Reference< XXMLSignatureTemplate > xTemplate( signtpl , UNO_QUERY ) ; 239 OSL_ENSURE( xTemplate.is() , 240 "Signer - " 241 "Cannot get interface of \"XXMLSignatureTemplate\" from service \"xsec.XMLSignatureTemplate\"" ) ; 242 243 //Import the signature template 244 xTemplate->setTemplate( xElement ) ; 245 246 //Import the URI/Stream binding 247 if( xUriBinding.is() ) 248 xTemplate->setBinding( xUriBinding ) ; 249 250 //Create security environment 251 //Build Security Environment 252 Reference< XInterface > xsecenv = 253 xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl"), xContext ) ; 254 OSL_ENSURE( xsecenv.is() , 255 "Signer - " 256 "Cannot get service instance of \"xsec.SecurityEnvironment\"" ) ; 257 258 Reference< XSecurityEnvironment > xSecEnv( xsecenv , UNO_QUERY ) ; 259 OSL_ENSURE( xSecEnv.is() , 260 "Signer - " 261 "Cannot get interface of \"XSecurityEnvironment\" from service \"xsec.SecurityEnvironment\"" ) ; 262 263 //Setup key slot and certDb 264 Reference< XUnoTunnel > xEnvTunnel( xsecenv , UNO_QUERY ) ; 265 OSL_ENSURE( xElement.is() , 266 "Signer - " 267 "Cannot get interface of \"XUnoTunnel\" from service \"xsec.SecurityEnvironment\"" ) ; 268 269 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xEnvTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; 270 OSL_ENSURE( pSecEnv != NULL , 271 "Signer - " 272 "Cannot get implementation of \"xsec.SecurityEnvironment\"" ) ; 273 274 //Setup key slot and certDb 275 if( n_hStoreHandle != NULL ) { 276 pSecEnv->setCryptoSlot( n_hStoreHandle ) ; 277 pSecEnv->setCertDb( n_hStoreHandle ) ; 278 } else { 279 pSecEnv->enableDefaultCrypt( sal_True ) ; 280 } 281 282 //Build XML Security Context 283 Reference< XInterface > xmlsecctx = 284 xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.XMLSecurityContext_MSCryptImpl"), xContext ) ; 285 OSL_ENSURE( xsecenv.is() , 286 "Signer - " 287 "Cannot get service instance of \"xsec.XMLSecurityContext\"" ) ; 288 289 Reference< XXMLSecurityContext > xSecCtx( xmlsecctx , UNO_QUERY ) ; 290 OSL_ENSURE( xSecCtx.is() , 291 "Signer - " 292 "Cannot get interface of \"XXMLSecurityContext\" from service \"xsec.XMLSecurityContext\"" ) ; 293 294 xSecCtx->addSecurityEnvironment( xSecEnv ) ; 295 296 //Generate XML signature 297 Reference< XInterface > xmlsigner = 298 xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.XMLSignature_MSCryptImpl"), xContext ) ; 299 OSL_ENSURE( xmlsigner.is() , 300 "Signer - " 301 "Cannot get service instance of \"xsec.XMLSignature\"" ) ; 302 303 Reference< XXMLSignature > xSigner( xmlsigner , UNO_QUERY ) ; 304 OSL_ENSURE( xSigner.is() , 305 "Signer - " 306 "Cannot get interface of \"XXMLSignature\" from service \"xsec.XMLSignature\"" ) ; 307 308 //perform signature 309 xTemplate = xSigner->generate( xTemplate , xSecEnv ) ; 310 OSL_ENSURE( xTemplate.is() , 311 "Signer - " 312 "Cannot generate the xml signature" ) ; 313 314 SecurityOperationStatus m_nStatus = xTemplate->getStatus(); 315 316 if (m_nStatus == SecurityOperationStatus_OPERATION_SUCCEEDED) 317 { 318 fprintf( stdout, "Operation succeeds.\n") ; 319 } 320 else 321 { 322 fprintf( stdout, "Operation fails.\n") ; 323 } 324 } catch( Exception& e ) { 325 fprintf( stderr , "Error Message: %s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() ) ; 326 goto done ; 327 } 328 329 dstFile = fopen( argv[2], "w" ) ; 330 if( dstFile == NULL ) { 331 fprintf( stderr , "### Can not open file %s\n", argv[2] ) ; 332 goto done ; 333 } 334 335 //Save result 336 xmlDocDump( dstFile, doc ) ; 337 338 done: 339 if( uri != NULL ) 340 delete uri ; 341 342 if( dstFile != NULL ) 343 fclose( dstFile ) ; 344 345 if( doc != NULL ) 346 xmlFreeDoc( doc ) ; 347 348 if( n_hStoreHandle != NULL ) 349 CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; 350 351 xmlSecMSCryptoAppShutdown() ; 352 353 /* Shutdown libxslt/libxml */ 354 #ifndef XMLSEC_NO_XSLT 355 xsltCleanupGlobals(); 356 #endif /* XMLSEC_NO_XSLT */ 357 xmlCleanupParser(); 358 359 } 360 361 return 0; 362 } 363 364