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 */ 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 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 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 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 > 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 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 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 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