xref: /trunk/main/xmlsecurity/tools/demo/util2.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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