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