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