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