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