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