xref: /trunk/main/xmlsecurity/tools/demo/util2.cxx (revision cdf0e10c)
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 <rtl/locale.h>
32 #include <osl/nlsupport.h>
33 #include <osl/process.h>
34 
35 #include <util.hxx>
36 
37 #include <stdio.h>
38 
39 #include <com/sun/star/registry/XImplementationRegistration.hpp>
40 #include <com/sun/star/security/KeyUsage.hpp>
41 #include <cppuhelper/bootstrap.hxx>
42 #include <xmlsecurity/biginteger.hxx>
43 #include <comphelper/processfactory.hxx>
44 #include <unotools/streamhelper.hxx>
45 
46 #include <rtl/ustrbuf.hxx>
47 #include <tools/string.hxx>
48 
49 namespace cssu = com::sun::star::uno;
50 namespace cssl = com::sun::star::lang;
51 namespace cssxc = com::sun::star::xml::crypto;
52 namespace cssi = com::sun::star::io;
53 
54 using namespace ::com::sun::star;
55 
56 /** convert util::DateTime to ISO Date String */
57 void convertDateTime( ::rtl::OUStringBuffer& rBuffer,
58 	const com::sun::star::util::DateTime& rDateTime )
59 {
60     String aString( String::CreateFromInt32( rDateTime.Year ) );
61     aString += '-';
62     if( rDateTime.Month < 10 )
63         aString += '0';
64     aString += String::CreateFromInt32( rDateTime.Month );
65     aString += '-';
66     if( rDateTime.Day < 10 )
67         aString += '0';
68     aString += String::CreateFromInt32( rDateTime.Day );
69 
70     if( rDateTime.Seconds != 0 ||
71         rDateTime.Minutes != 0 ||
72         rDateTime.Hours   != 0 )
73     {
74         aString += 'T';
75         if( rDateTime.Hours < 10 )
76             aString += '0';
77         aString += String::CreateFromInt32( rDateTime.Hours );
78         aString += ':';
79         if( rDateTime.Minutes < 10 )
80             aString += '0';
81         aString += String::CreateFromInt32( rDateTime.Minutes );
82         aString += ':';
83         if( rDateTime.Seconds < 10 )
84             aString += '0';
85         aString += String::CreateFromInt32( rDateTime.Seconds );
86 		if ( rDateTime.HundredthSeconds > 0)
87 		{
88 	        aString += ',';
89 			if (rDateTime.HundredthSeconds < 10)
90 				aString += '0';
91 			aString += String::CreateFromInt32( rDateTime.HundredthSeconds );
92 		}
93     }
94 
95     rBuffer.append( aString );
96 }
97 
98 ::rtl::OUString printHexString(cssu::Sequence< sal_Int8 > data)
99 {
100 	int length = data.getLength();
101 	::rtl::OUString result;
102 
103 	char number[4];
104 	for (int j=0; j<length; j++)
105 	{
106 		sprintf(number, "%02X ", (unsigned char)data[j]);
107 		result += rtl::OUString::createFromAscii( number );
108 	}
109 
110 	return result;
111 }
112 
113 
114 ::rtl::OUString getSignatureInformation(
115 	const SignatureInformation& infor,
116 	cssu::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& xSecurityEnvironment )
117 {
118 	char* status[50] = {
119 		"STATUS_UNKNOWN",
120 		"OPERATION_SUCCEEDED",
121 		"RUNTIMEERROR_FAILED",
122 		"ENGINE_FAILED",
123 		"MALLOC_FAILED",
124 		"STRDUP_FAILED",
125 		"CRYPTO_FAILED",
126 		"XML_FAILED",
127 		"XSLT_FAILED",
128 		"IO_FAILED",
129 		"DISABLED",
130 		"NOT_IMPLEMENTED",
131 		"INVALID_SIZE",
132 		"INVALID_DATA",
133 		"INVALID_RESULT",
134 		"INVALID_TYPE",
135 		"INVALID_OPERATION",
136 		"INVALID_STATUS",
137 		"INVALID_FORMAT",
138 		"DATA_NOT_MATCH",
139 		"INVALID_NODE",
140 		"INVALID_NODE_CONTENT",
141 		"INVALID_NODE_ATTRIBUTE",
142 		"MISSING_NODE_ATTRIBUTE",
143 		"NODE_ALREADY_PRESENT",
144 		"UNEXPECTED_NODE",
145 		"NODE_NOT_FOUND",
146 		"INVALID_TRANSFORM",
147 		"INVALID_TRANSFORM_KEY",
148 		"INVALID_URI_TYPE",
149 		"TRANSFORM_SAME_DOCUMENT_REQUIRED",
150 		"TRANSFORM_DISABLED",
151 		"INVALID_KEY_DATA",
152 		"KEY_DATA_NOT_FOUND",
153 		"KEY_DATA_ALREADY_EXIST",
154 		"INVALID_KEY_DATA_SIZE",
155 		"KEY_NOT_FOUND",
156 		"KEYDATA_DISABLED",
157 		"MAX_RETRIEVALS_LEVEL",
158 		"MAX_RETRIEVAL_TYPE_MISMATCH",
159 		"MAX_ENCKEY_LEVEL",
160 		"CERT_VERIFY_FAILED",
161 		"CERT_NOT_FOUND",
162 		"CERT_REVOKED",
163 		"CERT_ISSUER_FAILED",
164 		"CERT_NOT_YET_VALID",
165 		"CERT_HAS_EXPIRED",
166 		"DSIG_NO_REFERENCES",
167 		"DSIG_INVALID_REFERENCE",
168 		"ASSERTION"};
169 
170 	rtl::OUString result;
171 
172 	result += rtl::OUString::createFromAscii( "Security Id : " )
173 		+rtl::OUString::valueOf(infor.nSecurityId)
174 		+rtl::OUString::createFromAscii( "\n" );
175 	result += rtl::OUString::createFromAscii( "Status : [" )
176 		+rtl::OUString::valueOf((sal_Int32)(infor.nStatus))
177 		+rtl::OUString::createFromAscii( "] " )
178 		+rtl::OUString::createFromAscii(status[infor.nStatus])
179 		+rtl::OUString::createFromAscii( "\n" );
180 
181 	const SignatureReferenceInformations& rInfors = infor.vSignatureReferenceInfors;
182 	int i;
183 	int size = rInfors.size();
184 
185 	result += rtl::OUString::createFromAscii( "--References :\n" );
186 	for (i=0; i<size; i++)
187 	{
188         	result += rtl::OUString::createFromAscii( "---URI : " );
189 		result += rInfors[i].ouURI;
190 		result += rtl::OUString::createFromAscii( "\n" );
191         	result += rtl::OUString::createFromAscii( "---DigestValue : " );
192 		result += rInfors[i].ouDigestValue;
193 		result += rtl::OUString::createFromAscii( "\n" );
194 	}
195 
196         if (infor.ouX509IssuerName.getLength()>0)
197         {
198         	result += rtl::OUString::createFromAscii( "--X509IssuerName :\n" );
199         	result += infor.ouX509IssuerName;
200         	result += rtl::OUString::createFromAscii( "\n" );
201         }
202 
203         if (infor.ouX509SerialNumber.getLength()>0)
204         {
205         	result += rtl::OUString::createFromAscii( "--X509SerialNumber :\n" );
206         	result += infor.ouX509SerialNumber;
207         	result += rtl::OUString::createFromAscii( "\n" );
208         }
209 
210         if (infor.ouX509Certificate.getLength()>0)
211         {
212         	result += rtl::OUString::createFromAscii( "--X509Certificate :\n" );
213         	result += infor.ouX509Certificate;
214         	result += rtl::OUString::createFromAscii( "\n" );
215         }
216 
217         if (infor.ouSignatureValue.getLength()>0)
218         {
219         	result += rtl::OUString::createFromAscii( "--SignatureValue :\n" );
220         	result += infor.ouSignatureValue;
221         	result += rtl::OUString::createFromAscii( "\n" );
222         }
223 
224        	result += rtl::OUString::createFromAscii( "--Date :\n" );
225 
226 	::rtl::OUStringBuffer buffer;
227 	convertDateTime( buffer, infor.stDateTime );
228 	result += buffer.makeStringAndClear();
229        	result += rtl::OUString::createFromAscii( "\n" );
230 
231         if (infor.ouX509IssuerName.getLength()>0 && infor.ouX509SerialNumber.getLength()>0 && xSecurityEnvironment.is())
232         {
233         	result += rtl::OUString::createFromAscii( "--Certificate Path :\n" );
234         	cssu::Reference< ::com::sun::star::security::XCertificate > xCert = xSecurityEnvironment->getCertificate( infor.ouX509IssuerName, numericStringToBigInteger(infor.ouX509SerialNumber) );
235         	cssu::Sequence < cssu::Reference< ::com::sun::star::security::XCertificate > > xCertPath;
236 			if(! xCert.is() )
237 			{
238 				fprintf(stdout , " xCert is NULL , so can not buildCertificatePath\n");
239 				return result ;
240 			}
241 			else
242 			{
243 				xCertPath = xSecurityEnvironment->buildCertificatePath( xCert ) ;
244 			}
245 
246 		for( int i = 0; i < xCertPath.getLength(); i++ )
247 		{
248 			result += xCertPath[i]->getSubjectName();
249                 	result += rtl::OUString::createFromAscii( "\n    Subject public key algorithm : " );
250                 	result += xCertPath[i]->getSubjectPublicKeyAlgorithm();
251                 	result += rtl::OUString::createFromAscii( "\n    Signature algorithm : " );
252                 	result += xCertPath[i]->getSignatureAlgorithm();
253 
254                 	result += rtl::OUString::createFromAscii( "\n    Subject public key value : " );
255                 	cssu::Sequence< sal_Int8 > keyValue = xCertPath[i]->getSubjectPublicKeyValue();
256                 	result += printHexString(keyValue);
257 
258                 	result += rtl::OUString::createFromAscii( "\n    Thumbprint (SHA1) : " );
259                 	cssu::Sequence< sal_Int8 > SHA1Thumbprint = xCertPath[i]->getSHA1Thumbprint();
260                 	result += printHexString(SHA1Thumbprint);
261 
262                 	result += rtl::OUString::createFromAscii( "\n    Thumbprint (MD5) : " );
263                 	cssu::Sequence< sal_Int8 > MD5Thumbprint = xCertPath[i]->getMD5Thumbprint();
264                 	result += printHexString(MD5Thumbprint);
265 
266                 	result += rtl::OUString::createFromAscii( "\n  <<\n" );
267 		}
268 
269                	result += rtl::OUString::createFromAscii( "\n    Key Usage : " );
270                	sal_Int32 usage = xCert->getCertificateUsage();
271 
272                	if (usage & ::com::sun::star::security::KeyUsage::DIGITAL_SIGNATURE)
273                	{
274                		result += rtl::OUString::createFromAscii( "DIGITAL_SIGNATURE " );
275                	}
276 
277                	if (usage & ::com::sun::star::security::KeyUsage::NON_REPUDIATION)
278                	{
279                		result += rtl::OUString::createFromAscii( "NON_REPUDIATION " );
280                	}
281 
282                	if (usage & ::com::sun::star::security::KeyUsage::KEY_ENCIPHERMENT)
283                	{
284                		result += rtl::OUString::createFromAscii( "KEY_ENCIPHERMENT " );
285                	}
286 
287                	if (usage & ::com::sun::star::security::KeyUsage::DATA_ENCIPHERMENT)
288                	{
289                		result += rtl::OUString::createFromAscii( "DATA_ENCIPHERMENT " );
290                	}
291 
292                	if (usage & ::com::sun::star::security::KeyUsage::KEY_AGREEMENT)
293                	{
294                		result += rtl::OUString::createFromAscii( "KEY_AGREEMENT " );
295                	}
296 
297                	if (usage & ::com::sun::star::security::KeyUsage::KEY_CERT_SIGN)
298                	{
299                		result += rtl::OUString::createFromAscii( "KEY_CERT_SIGN " );
300                	}
301 
302                	if (usage & ::com::sun::star::security::KeyUsage::CRL_SIGN)
303                	{
304                		result += rtl::OUString::createFromAscii( "CRL_SIGN " );
305                	}
306 
307                	result += rtl::OUString::createFromAscii( "\n" );
308         }
309 
310 	result += rtl::OUString::createFromAscii( "\n" );
311 	return result;
312 }
313 
314 ::rtl::OUString getSignatureInformations(
315 	const SignatureInformations& SignatureInformations,
316 	cssu::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecurityEnvironment )
317 {
318 	rtl::OUString result;
319 	int i;
320 	int size = SignatureInformations.size();
321 
322 	for (i=0; i<size; i++)
323 	{
324 		const SignatureInformation& infor = SignatureInformations[i];
325 		result += getSignatureInformation( infor, xSecurityEnvironment );
326 	}
327 
328 	result += rtl::OUString::createFromAscii( "\n" );
329 
330 	return result;
331 }
332 
333 ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >
334 	getCertificateFromEnvironment( ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >	xSecurityEnvironment , sal_Bool nType)
335 {
336 	cssu::Sequence< cssu::Reference< ::com::sun::star::security::XCertificate > > xPersonalCerts ;
337 	int length = 0;
338 	int i;
339 
340 	// add By CP
341 	sal_uInt16 encoding ;
342 	rtl_Locale *pLocale = NULL ;
343 	osl_getProcessLocale( &pLocale ) ;
344 	encoding = osl_getTextEncodingFromLocale( pLocale ) ;
345 	// CP end
346 
347 	if( nType != sal_False )
348 		xPersonalCerts = xSecurityEnvironment->getPersonalCertificates() ;
349 	else
350 		return NULL; // not support then;
351 
352 	length = xPersonalCerts.getLength();
353 	if(length == 0)
354 	{
355 		fprintf( stdout, "\nNo certificate found!\n" ) ;
356 		return NULL;
357 	}
358 
359 	fprintf( stdout, "\nSelect a certificate:\n" ) ;
360 	for( i = 0; i < length; i ++ )
361 	{
362 		rtl::OUString xxxIssuer;
363 		rtl::OUString xxxSubject;
364 		rtl::OString yyyIssuer;
365 		rtl::OString yyySubject;
366 
367 		xxxIssuer=xPersonalCerts[i]->getIssuerName();
368 		yyyIssuer=rtl::OUStringToOString( xxxIssuer, encoding );
369 
370 		xxxSubject=xPersonalCerts[i]->getSubjectName();
371 		yyySubject=rtl::OUStringToOString( xxxSubject, encoding );
372 
373 		fprintf( stdout, "\n%d:\nsubject=[%s]\nissuer=[%s]\n",
374 			i+1,
375 			yyySubject.getStr(),
376 			yyyIssuer.getStr());
377 	}
378 
379 	int sel = QuerySelectNumber( 1, length ) -1;
380 	return xPersonalCerts[sel] ;
381 }
382 
383 void QueryPrintSignatureDetails( const SignatureInformations& SignatureInformations, ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > rSecEnv )
384 {
385 	char cShowDetails;
386 	fprintf( stdout, "\nDisplay details (y/n) [y]?" );
387 	fflush( stdout );
388 	fscanf( stdin, "%c", &cShowDetails);
389 	if ( cShowDetails == 'y' )
390 	{
391 		rtl_Locale *pLocale = NULL ;
392 		osl_getProcessLocale( &pLocale ) ;
393 		sal_uInt16 encoding = osl_getTextEncodingFromLocale( pLocale ) ;
394 
395 		fprintf( stdout, "------------- Signature details START -------------\n" );
396 		fprintf( stdout, "%s",
397 			rtl::OUStringToOString(
398 				getSignatureInformations( SignatureInformations, rSecEnv),
399 				encoding).getStr());
400 
401 		fprintf( stdout, "------------- Signature details END -------------\n" );
402 	}
403 }
404 
405 int QuerySelectNumber( int nMin, int nMax )
406 {
407 	fprintf( stdout, "\n" ) ;
408 	int sel = 0;
409 	do
410 	{
411 		fprintf( stdout, "\nSelect <%d-%d>:", nMin, nMax ) ;
412 		fflush( stdout );
413 		fscanf( stdin, "%d", &sel ) ;
414 	} while( ( sel < nMin ) || ( sel > nMax ) );
415 
416 	return sel;
417 }
418 
419 long QueryVerifySignature()
420 {
421 	char answer;
422 	fprintf( stdout, "\nFound a signature - verify this one (y/n) [y]?" );
423 	fflush( stdout );
424 	fscanf( stdin, "%c", &answer);
425 	return  (answer == 'n')?0:1;
426 }
427