00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 #include <config.h>
00021 #endif
00022
00023 #include "kpgpbase.h"
00024 #include "kpgp.h"
00025
00026 #include <string.h>
00027 #include <assert.h>
00028
00029 #include <qdatetime.h>
00030
00031 #include <klocale.h>
00032 #include <kprocess.h>
00033 #include <kdebug.h>
00034
00035 #define PGP2 "pgp"
00036
00037 namespace Kpgp {
00038
00039 Base2::Base2()
00040 : Base()
00041 {
00042 }
00043
00044
00045 Base2::~Base2()
00046 {
00047 }
00048
00049
00050 int
00051 Base2::encrypt( Block& block, const KeyIDList& recipients )
00052 {
00053 return encsign( block, recipients, 0 );
00054 }
00055
00056
00057 int
00058 Base2::clearsign( Block& block, const char *passphrase )
00059 {
00060 return encsign( block, KeyIDList(), passphrase );
00061 }
00062
00063
00064 int
00065 Base2::encsign( Block& block, const KeyIDList& recipients,
00066 const char *passphrase )
00067 {
00068 QCString cmd;
00069 int exitStatus = 0;
00070
00071 if(!recipients.isEmpty() && passphrase != 0)
00072 cmd = PGP2 " +batchmode +language=en +verbose=1 -seat";
00073 else if(!recipients.isEmpty())
00074 cmd = PGP2 " +batchmode +language=en +verbose=1 -eat";
00075 else if(passphrase != 0)
00076 cmd = PGP2 " +batchmode +language=en +verbose=1 -sat";
00077 else
00078 {
00079 kdDebug(5100) << "kpgpbase: Neither recipients nor passphrase specified." << endl;
00080 return OK;
00081 }
00082
00083 if(passphrase != 0)
00084 cmd += addUserId();
00085
00086 if(!recipients.isEmpty()) {
00087 if(Module::getKpgp()->encryptToSelf())
00088 {
00089 cmd += " 0x";
00090 cmd += Module::getKpgp()->user();
00091 }
00092
00093 for( KeyIDList::ConstIterator it = recipients.begin();
00094 it != recipients.end(); ++it ) {
00095 cmd += " 0x";
00096 cmd += (*it);
00097 }
00098 }
00099 cmd += " -f";
00100
00101 clear();
00102 input = block.text();
00103 exitStatus = run(cmd.data(), passphrase);
00104 if( !output.isEmpty() )
00105 block.setProcessedText( output );
00106 block.setError( error );
00107
00108 if(exitStatus != 0)
00109 status = ERROR;
00110
00111 #if 0
00112
00113
00114
00115 if(!recipients.isEmpty())
00116 {
00117 int index = 0;
00118 bool bad = FALSE;
00119 unsigned int num = 0;
00120 QCString badkeys = "";
00121 if (error.find("Cannot find the public key") != -1)
00122 {
00123 index = 0;
00124 num = 0;
00125 while((index = error.find("Cannot find the public key",index))
00126 != -1)
00127 {
00128 bad = TRUE;
00129 index = error.find('\'',index);
00130 int index2 = error.find('\'',index+1);
00131 if (num++)
00132 badkeys += ", ";
00133 badkeys += error.mid(index, index2-index+1);
00134 }
00135 if(bad)
00136 {
00137 badkeys.stripWhiteSpace();
00138 if(num == recipients.count())
00139 errMsg = i18n("Could not find public keys matching the userid(s)\n"
00140 "%1;\n"
00141 "the message is not encrypted.")
00142 .arg( badkeys.data() );
00143 else
00144 errMsg = i18n("Could not find public keys matching the userid(s)\n"
00145 "%1;\n"
00146 "these persons will not be able to read the message.")
00147 .arg( badkeys.data() );
00148 status |= MISSINGKEY;
00149 status |= ERROR;
00150 }
00151 }
00152 if (error.find("skipping userid") != -1)
00153 {
00154 index = 0;
00155 num = 0;
00156 while((index = error.find("skipping userid",index))
00157 != -1)
00158 {
00159 bad = TRUE;
00160 int index2 = error.find('\n',index+16);
00161 if (num++)
00162 badkeys += ", ";
00163 badkeys += error.mid(index+16, index2-index-16);
00164 index = index2;
00165 }
00166 if(bad)
00167 {
00168 badkeys.stripWhiteSpace();
00169 if(num == recipients.count())
00170 errMsg = i18n("Public keys not certified with trusted signature "
00171 "for userid(s)\n"
00172 "%1.\n"
00173 "The message is not encrypted.")
00174 .arg( badkeys.data() );
00175 else
00176 errMsg = i18n("Public keys not certified with trusted signature "
00177 "for userid(s)\n"
00178 "%1;\n"
00179 "these persons will not be able to read the message.")
00180 .arg( badkeys.data() );
00181 status |= BADKEYS;
00182 status |= ERROR;
00183 return status;
00184 }
00185 }
00186 }
00187 #endif
00188 if(passphrase != 0)
00189 {
00190 if(error.find("Pass phrase is good") != -1)
00191 {
00192
00193 status |= SIGNED;
00194 }
00195 if( error.find("Bad pass phrase") != -1)
00196 {
00197 errMsg = i18n("Bad passphrase; could not sign.");
00198 status |= BADPHRASE;
00199 status |= ERR_SIGNING;
00200 status |= ERROR;
00201 }
00202 }
00203 if (error.find("Signature error") != -1)
00204 {
00205 errMsg = i18n("Signing failed: please check your PGP User Identity, "
00206 "the PGP setup, and the key rings.");
00207 status |= NO_SEC_KEY;
00208 status |= ERR_SIGNING;
00209 status |= ERROR;
00210 }
00211 if (error.find("Encryption error") != -1)
00212 {
00213 errMsg = i18n("Encryption failed: please check your PGP setup "
00214 "and the key rings.");
00215 status |= NO_SEC_KEY;
00216 status |= BADKEYS;
00217 status |= ERROR;
00218 }
00219
00220
00221 block.setStatus( status );
00222 return status;
00223 }
00224
00225
00226 int
00227 Base2::decrypt( Block& block, const char *passphrase )
00228 {
00229 int index, index2;
00230 int exitStatus = 0;
00231
00232 clear();
00233 input = block.text();
00234 exitStatus = run(PGP2 " +batchmode +language=en -f", passphrase);
00235 if( !output.isEmpty() )
00236 block.setProcessedText( output );
00237 block.setError( error );
00238
00239
00240
00241 if(error.find("ASCII armor corrupted.") != -1)
00242 {
00243 kdDebug(5100) << "removing ASCII armor header" << endl;
00244 int index1 = input.find("-----BEGIN PGP SIGNED MESSAGE-----");
00245 if(index1 != -1)
00246 index1 = input.find("-----BEGIN PGP SIGNATURE-----", index1);
00247 else
00248 index1 = input.find("-----BEGIN PGP MESSAGE-----");
00249 index1 = input.find('\n', index1);
00250 index2 = input.find("\n\n", index1);
00251 input.remove(index1, index2 - index1);
00252 exitStatus = run(PGP2 " +batchmode +language=en -f", passphrase);
00253 if( !output.isEmpty() )
00254 block.setProcessedText( output );
00255 block.setError( error );
00256 }
00257
00258 if(exitStatus == -1) {
00259 errMsg = i18n("error running PGP");
00260 status = RUN_ERR;
00261 block.setStatus( status );
00262 return status;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 if(error.find("File is encrypted.") != -1)
00286 {
00287
00288 status |= ENCRYPTED;
00289 if((index = error.find("Key for user ID:")) != -1)
00290 {
00291
00292 index += 17;
00293 index2 = error.find('\n', index);
00294 block.setRequiredUserId( error.mid(index, index2 - index) );
00295
00296
00297 if((passphrase != 0) && (error.find("Bad pass phrase") != -1))
00298 {
00299 errMsg = i18n("Bad passphrase; could not decrypt.");
00300 kdDebug(5100) << "Base: passphrase is bad" << endl;
00301 status |= BADPHRASE;
00302 status |= ERROR;
00303 }
00304 }
00305 else
00306 {
00307
00308 status |= NO_SEC_KEY;
00309 status |= ERROR;
00310 errMsg = i18n("You do not have the secret key needed to decrypt this message.");
00311 kdDebug(5100) << "Base: no secret key for this message" << endl;
00312 }
00313
00314 #if 0
00315
00316
00317 index = error.find("can only be read by:");
00318 if(index != -1)
00319 {
00320 index = error.find('\n',index);
00321 int end = error.find("\n\n",index);
00322
00323 mRecipients.clear();
00324 while( (index2 = error.find('\n',index+1)) <= end )
00325 {
00326 QCString item = error.mid(index+1,index2-index-1);
00327 item.stripWhiteSpace();
00328 mRecipients.append(item);
00329 index = index2;
00330 }
00331 }
00332 #endif
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 if((index = error.find("File has signature")) != -1)
00396 {
00397
00398 index = error.find('\n', index+18) + 1;
00399
00400 status |= SIGNED;
00401
00402 if ((index2 = error.find("Signature made", index)) != -1) {
00403 index2 += 15;
00404 int index3 = error.find("using", index2);
00405 block.setSignatureDate( error.mid(index2, index3-index2-1) );
00406 kdDebug(5100) << "Message was signed on '" << block.signatureDate() << "'\n";
00407 index3 = error.find("key ID ", index3) + 7;
00408 block.setSignatureKeyId( error.mid(index3,8) );
00409 kdDebug(5100) << "Message was signed with key '" << block.signatureKeyId() << "'\n";
00410 }
00411 else {
00412
00413
00414 block.setSignatureDate( "" );
00415 block.setSignatureKeyId( "" );
00416 }
00417
00418 if( ( index2 = error.find("Key matching expected", index) ) != -1)
00419 {
00420 status |= UNKNOWN_SIG;
00421 status |= GOODSIG;
00422 int index3 = error.find("Key ID ", index2) + 7;
00423 block.setSignatureKeyId( error.mid(index3,8) );
00424 block.setSignatureUserId( QString::null );
00425 }
00426 else if( (index2 = error.find("Good signature from", index)) != -1 )
00427 {
00428 status |= GOODSIG;
00429
00430 index = error.find('"',index2+19);
00431 index2 = error.find('"', index+1);
00432 block.setSignatureUserId( error.mid(index+1, index2-index-1) );
00433 }
00434 else if( (index2 = error.find("Bad signature from", index)) != -1 )
00435 {
00436 status |= ERROR;
00437
00438 index = error.find('"',index2+19);
00439 index2 = error.find('"', index+1);
00440 block.setSignatureUserId( error.mid(index+1, index2-index-1) );
00441 }
00442 else if( error.find("Keyring file", index) != -1 )
00443 {
00444
00445 status |= UNKNOWN_SIG;
00446 status |= GOODSIG;
00447
00448 index = error.find('\'', index) + 1;
00449 index2 = error.find('\'', index);
00450 block.setSignatureUserId( i18n("The keyring file %1 does not exist.\n"
00451 "Please check your PGP setup.").arg(error.mid(index, index2-index)) );
00452 }
00453 else
00454 {
00455 status |= ERROR;
00456 block.setSignatureUserId( i18n("Unknown error") );
00457 }
00458 }
00459
00460 block.setStatus( status );
00461 return status;
00462 }
00463
00464
00465 Key*
00466 Base2::readPublicKey( const KeyID& keyID,
00467 const bool readTrust ,
00468 Key* key )
00469 {
00470 int exitStatus = 0;
00471
00472 status = 0;
00473 exitStatus = run( PGP2 " +batchmode +language=en +verbose=0 -kvc -f 0x" +
00474 keyID, 0, true );
00475
00476 if(exitStatus != 0) {
00477 status = ERROR;
00478 return 0;
00479 }
00480
00481 key = parsePublicKeyData( output, key );
00482
00483 if( key == 0 )
00484 {
00485 return 0;
00486 }
00487
00488 if( readTrust )
00489 {
00490 exitStatus = run( PGP2 " +batchmode +language=en +verbose=0 -kc -f",
00491 0, true );
00492
00493 if(exitStatus != 0) {
00494 status = ERROR;
00495 return 0;
00496 }
00497
00498 parseTrustDataForKey( key, error );
00499 }
00500
00501 return key;
00502 }
00503
00504
00505 KeyList
00506 Base2::publicKeys( const QStringList & patterns )
00507 {
00508 return doGetPublicKeys( PGP2 " +batchmode +language=en +verbose=0 -kvc -f",
00509 patterns );
00510 }
00511
00512 KeyList
00513 Base2::doGetPublicKeys( const QCString & cmd, const QStringList & patterns )
00514 {
00515 int exitStatus = 0;
00516 KeyList publicKeys;
00517
00518 status = 0;
00519 if ( patterns.isEmpty() ) {
00520 exitStatus = run( cmd, 0, true );
00521
00522 if ( exitStatus != 0 ) {
00523 status = ERROR;
00524 return KeyList();
00525 }
00526
00527
00528 publicKeys = parseKeyList( output, false );
00529 }
00530 else {
00531 typedef QMap<QCString, Key*> KeyMap;
00532 KeyMap map;
00533
00534 for ( QStringList::ConstIterator it = patterns.begin();
00535 it != patterns.end(); ++it ) {
00536 exitStatus = run( cmd + " " + KProcess::quote( *it ).local8Bit(),
00537 0, true );
00538
00539 if ( exitStatus != 0 ) {
00540 status = ERROR;
00541 return KeyList();
00542 }
00543
00544
00545 publicKeys = parseKeyList( output, false );
00546
00547
00548 while ( !publicKeys.isEmpty() ) {
00549 Key * key = publicKeys.take( 0 );
00550 if ( !map.contains( key->primaryFingerprint() ) )
00551 map.insert( key->primaryFingerprint(), key );
00552 else
00553 delete key;
00554 }
00555 }
00556
00557 for ( KeyMap::ConstIterator it = map.begin(); it != map.end(); ++it ) {
00558 publicKeys.append( it.data() );
00559 }
00560 }
00561
00562
00563 publicKeys.sort();
00564
00565 return publicKeys;
00566 }
00567
00568 KeyList
00569 Base2::secretKeys( const QStringList & patterns )
00570 {
00571 return publicKeys( patterns );
00572 }
00573
00574
00575 int
00576 Base2::signKey(const KeyID& keyID, const char *passphrase)
00577 {
00578 QCString cmd;
00579 int exitStatus = 0;
00580
00581 cmd = PGP2 " +batchmode +language=en -ks -f ";
00582 cmd += addUserId();
00583 cmd += " 0x" + keyID;
00584
00585 status = 0;
00586 exitStatus = run(cmd.data(),passphrase);
00587
00588 if (exitStatus != 0)
00589 status = ERROR;
00590
00591 return status;
00592 }
00593
00594
00595 QCString Base2::getAsciiPublicKey(const KeyID& keyID)
00596 {
00597 int exitStatus = 0;
00598
00599 if (keyID.isEmpty())
00600 return QCString();
00601
00602 status = 0;
00603 exitStatus = run( PGP2 " +batchmode +force +language=en -kxaf 0x" + keyID,
00604 0, true );
00605
00606 if(exitStatus != 0) {
00607 status = ERROR;
00608 return QCString();
00609 }
00610
00611 return output;
00612 }
00613
00614
00615 Key*
00616 Base2::parsePublicKeyData( const QCString& output, Key* key )
00617 {
00618 Subkey *subkey = 0;
00619 int index;
00620
00621
00622 if( !strncmp( output.data(), "pub", 3 ) ||
00623 !strncmp( output.data(), "sec", 3 ) )
00624 index = 0;
00625 else
00626 {
00627
00628
00629
00630
00631
00632 index = output.find( "\npub" );
00633 if( index == -1 )
00634 return 0;
00635 else
00636 index++;
00637 }
00638
00639 while( true )
00640 {
00641 int index2;
00642
00643
00644 if( ( index2 = output.find( '\n', index ) ) == -1 )
00645 break;
00646
00647 if( !strncmp( output.data() + index, "pub", 3 ) ||
00648 !strncmp( output.data() + index, "sec", 3 ) )
00649 {
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 int pos, pos2;
00660
00661 if( key == 0 )
00662 key = new Key();
00663 else
00664 key->clear();
00665
00666
00667 key->setCanEncrypt( true );
00668 key->setCanSign( true );
00669 key->setCanCertify( true );
00670
00671
00672 subkey = new Subkey( "", false );
00673 key->addSubkey( subkey );
00674
00675 subkey->setCanEncrypt( true );
00676 subkey->setCanSign( true );
00677 subkey->setCanCertify( true );
00678
00679 subkey->setExpirationDate( -1 );
00680
00681
00682 switch( output[index+3] )
00683 {
00684 case ' ':
00685 break;
00686 case '-':
00687 subkey->setDisabled( true );
00688 key->setDisabled( true );
00689 break;
00690 case '>':
00691 subkey->setExpired( true );
00692 key->setExpired( true );
00693 break;
00694 default:
00695 kdDebug(5100) << "Unknown key flag.\n";
00696 }
00697
00698
00699 pos = index + 4;
00700 while( output[pos] == ' ' )
00701 pos++;
00702 pos2 = output.find( '/', pos );
00703 subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
00704
00705
00706 pos = pos2 + 1;
00707 pos2 = output.find( ' ', pos );
00708 subkey->setKeyID( output.mid( pos, pos2-pos ) );
00709
00710
00711 pos = pos2 + 1;
00712 while( output[pos] == ' ' )
00713 pos++;
00714 pos2 = output.find( ' ', pos );
00715 int year = output.mid( pos, 4 ).toInt();
00716 int month = output.mid( pos+5, 2 ).toInt();
00717 int day = output.mid( pos+8, 2 ).toInt();
00718 QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00719 QDateTime epoch( QDate( 1970, 01, 01 ), QTime( 00, 00 ) );
00720
00721
00722
00723
00724 subkey->setCreationDate( epoch.secsTo( dt ) );
00725
00726
00727 pos = pos2 + 1;
00728 while( output[pos] == ' ' )
00729 pos++;
00730 QCString uid = output.mid( pos, index2-pos );
00731 if( uid != "*** KEY REVOKED ***" )
00732 key->addUserID( uid );
00733 else
00734 {
00735 subkey->setRevoked( true );
00736 key->setRevoked( true );
00737 }
00738 }
00739 else if( output[index] == ' ' )
00740 {
00741
00742 if( key == 0 )
00743 break;
00744 assert( subkey != 0 );
00745
00746 int pos = index + 1;
00747 while( output[pos] == ' ' )
00748 pos++;
00749
00750 if( !strncmp( output.data() + pos, "Key fingerprint = ", 18 ) )
00751 {
00752
00753
00754
00755 QCString fingerprint = output.mid( pos, index2-pos );
00756
00757 for ( int idx = 0 ; (idx = fingerprint.find(' ', idx)) >= 0 ; )
00758 fingerprint.replace( idx, 1, "" );
00759
00760 subkey->setFingerprint( fingerprint );
00761 }
00762 else if( !strncmp( output.data() + pos, "Expire: ", 8 ) ||
00763 !strncmp( output.data() + pos, "no expire ", 10 ) )
00764 {
00765
00766
00767
00768
00769
00770 if( output[pos] == 'E' )
00771 {
00772
00773 pos += 8;
00774 int year = output.mid( pos, 4 ).toInt();
00775 int month = output.mid( pos+5, 2 ).toInt();
00776 int day = output.mid( pos+8, 2 ).toInt();
00777 QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00778 QDateTime epoch( QDate( 1970, 01, 01 ), QTime( 00, 00 ) );
00779
00780 subkey->setExpirationDate( epoch.secsTo( dt ) );
00781 pos += 11;
00782 }
00783 else
00784 pos += 10;
00785
00786
00787 if( pos != index2 )
00788 {
00789 if( !strncmp( output.data() + pos, "SIGNature only", 14 ) )
00790 {
00791 subkey->setCanEncrypt( false );
00792 key->setCanEncrypt( false );
00793 }
00794 else if( !strncmp( output.data() + pos, "ENCRyption only", 15 ) )
00795 {
00796 subkey->setCanSign( false );
00797 key->setCanSign( false );
00798 subkey->setCanCertify( false );
00799 key->setCanCertify( false );
00800 }
00801 }
00802 }
00803 else
00804 {
00805
00806
00807
00808 key->addUserID( output.mid( pos, index2-pos ) );
00809 }
00810 }
00811 index = index2 + 1;
00812 }
00813
00814
00815
00816 return key;
00817 }
00818
00819
00820 void
00821 Base2::parseTrustDataForKey( Key* key, const QCString& str )
00822 {
00823 if( ( key == 0 ) || str.isEmpty() )
00824 return;
00825
00826 QCString keyID = key->primaryKeyID();
00827 UserIDList userIDs = key->userIDs();
00828
00829
00830 int index = str.find( '\n' ) + 1;
00831 while( ( index > 0 ) &&
00832 ( strncmp( str.data() + index+2, keyID.data(), 8 ) != 0 ) )
00833 index = str.find( '\n', index ) + 1;
00834
00835 if( index == 0 )
00836 return;
00837
00838 bool ultimateTrust = false;
00839 if( !strncmp( str.data() + index+11, "ultimate", 8 ) )
00840 ultimateTrust = true;
00841
00842 bool firstLine = true;
00843
00844 while( true )
00845 {
00846 int index2;
00847
00848
00849 if( ( index2 = str.find( '\n', index ) ) == -1 )
00850 break;
00851
00852
00853 if( !firstLine && ( str[index+2] != ' ' ) )
00854 break;
00855
00856 if( str[index+21] != ' ' )
00857 {
00858
00859
00860 Validity validity = KPGP_VALIDITY_UNKNOWN;
00861 if( !strncmp( str.data() + index+21, "complete", 8 ) )
00862 if( ultimateTrust )
00863 validity = KPGP_VALIDITY_ULTIMATE;
00864 else
00865 validity = KPGP_VALIDITY_FULL;
00866 else if( !strncmp( str.data() + index+21, "marginal", 8 ) )
00867 validity = KPGP_VALIDITY_MARGINAL;
00868 else if( !strncmp( str.data() + index+21, "never", 5 ) )
00869 validity = KPGP_VALIDITY_NEVER;
00870 else if( !strncmp( str.data() + index+21, "undefined", 9 ) )
00871 validity = KPGP_VALIDITY_UNDEFINED;
00872
00873
00874 int pos = index + 31;
00875 if( str[index+2] == ' ' )
00876 pos++;
00877 QString uid = str.mid( pos, index2-pos );
00878
00879
00880 for( UserIDListIterator it( userIDs ); it.current(); ++it )
00881 if( (*it)->text() == uid )
00882 {
00883 kdDebug(5100)<<"Setting the validity of "<<uid<<" to "<<validity<<endl;
00884 (*it)->setValidity( validity );
00885 break;
00886 }
00887 }
00888
00889 firstLine = false;
00890 index = index2 + 1;
00891 }
00892 }
00893
00894
00895 KeyList
00896 Base2::parseKeyList( const QCString& output, bool secretKeys )
00897 {
00898 kdDebug(5100) << "Kpgp::Base2::parseKeyList()" << endl;
00899 KeyList keys;
00900 Key *key = 0;
00901 Subkey *subkey = 0;
00902 int index;
00903
00904
00905 if( !strncmp( output.data(), "pub", 3 ) ||
00906 !strncmp( output.data(), "sec", 3 ) )
00907 index = 0;
00908 else
00909 {
00910 if( secretKeys )
00911 index = output.find( "\nsec" );
00912 else
00913 index = output.find( "\npub" );
00914 if( index == -1 )
00915 return keys;
00916 else
00917 index++;
00918 }
00919
00920 while( true )
00921 {
00922 int index2;
00923
00924
00925 if( ( index2 = output.find( '\n', index ) ) == -1 )
00926 break;
00927
00928 if( !strncmp( output.data() + index, "pub", 3 ) ||
00929 !strncmp( output.data() + index, "sec", 3 ) )
00930 {
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 int pos, pos2;
00941
00942 if( key != 0 )
00943 keys.append( key );
00944
00945 key = new Key();
00946 key->setSecret( secretKeys );
00947
00948 key->setCanEncrypt( true );
00949 key->setCanSign( true );
00950 key->setCanCertify( true );
00951
00952 subkey = new Subkey( "", secretKeys );
00953 key->addSubkey( subkey );
00954
00955 subkey->setCanEncrypt( true );
00956 subkey->setCanSign( true );
00957 subkey->setCanCertify( true );
00958
00959 subkey->setExpirationDate( -1 );
00960
00961
00962 switch( output[index+3] )
00963 {
00964 case ' ':
00965 break;
00966 case '-':
00967 subkey->setDisabled( true );
00968 key->setDisabled( true );
00969 break;
00970 case '>':
00971 subkey->setExpired( true );
00972 key->setExpired( true );
00973 break;
00974 default:
00975 kdDebug(5100) << "Unknown key flag.\n";
00976 }
00977
00978
00979 pos = index + 4;
00980 while( output[pos] == ' ' )
00981 pos++;
00982 pos2 = output.find( '/', pos );
00983 subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
00984
00985
00986 pos = pos2 + 1;
00987 pos2 = output.find( ' ', pos );
00988 subkey->setKeyID( output.mid( pos, pos2-pos ) );
00989
00990
00991 pos = pos2 + 1;
00992 while( output[pos] == ' ' )
00993 pos++;
00994 pos2 = output.find( ' ', pos );
00995 int year = output.mid( pos, 4 ).toInt();
00996 int month = output.mid( pos+5, 2 ).toInt();
00997 int day = output.mid( pos+8, 2 ).toInt();
00998 QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00999 QDateTime epoch( QDate( 1970, 01, 01 ), QTime( 00, 00 ) );
01000
01001
01002
01003
01004 subkey->setCreationDate( epoch.secsTo( dt ) );
01005
01006
01007 pos = pos2 + 1;
01008 while( output[pos] == ' ' )
01009 pos++;
01010 QCString uid = output.mid( pos, index2-pos );
01011 if( uid != "*** KEY REVOKED ***" )
01012 key->addUserID( uid );
01013 else
01014 {
01015 subkey->setRevoked( true );
01016 key->setRevoked( true );
01017 }
01018 }
01019 else if( output[index] == ' ' )
01020 {
01021
01022 if( key == 0 )
01023 break;
01024
01025 int pos = index + 1;
01026 while( output[pos] == ' ' )
01027 pos++;
01028
01029 if( !strncmp( output.data() + pos, "Key fingerprint = ", 18 ) )
01030 {
01031
01032
01033
01034 int pos2;
01035 pos2 = pos + 18;
01036 QCString fingerprint = output.mid( pos, index2-pos );
01037
01038 for ( int idx = 0 ; (idx = fingerprint.find(' ', idx)) >= 0 ; )
01039 fingerprint.replace( idx, 1, "" );
01040
01041 subkey->setFingerprint( fingerprint );
01042 }
01043 else if( !strncmp( output.data() + pos, "Expire: ", 8 ) ||
01044 !strncmp( output.data() + pos, "no expire ", 10 ) )
01045 {
01046
01047
01048
01049
01050
01051 if( output[pos] == 'E' )
01052 {
01053
01054 pos += 8;
01055 int year = output.mid( pos, 4 ).toInt();
01056 int month = output.mid( pos+5, 2 ).toInt();
01057 int day = output.mid( pos+8, 2 ).toInt();
01058 QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
01059 QDateTime epoch( QDate( 1970, 01, 01 ), QTime( 00, 00 ) );
01060
01061 subkey->setExpirationDate( epoch.secsTo( dt ) );
01062 pos += 11;
01063 }
01064 else
01065 pos += 10;
01066
01067
01068 if( pos != index2 )
01069 {
01070 if( !strncmp( output.data() + pos, "SIGNature only", 14 ) )
01071 {
01072 subkey->setCanEncrypt( false );
01073 key->setCanEncrypt( false );
01074 }
01075 else if( !strncmp( output.data() + pos, "ENCRyption only", 15 ) )
01076 {
01077 subkey->setCanSign( false );
01078 key->setCanSign( false );
01079 subkey->setCanCertify( false );
01080 key->setCanCertify( false );
01081 }
01082 }
01083 }
01084 else
01085 {
01086
01087
01088
01089 key->addUserID( output.mid( pos, index2-pos ) );
01090 }
01091 }
01092
01093 index = index2 + 1;
01094 }
01095
01096 if (key != 0)
01097 keys.append( key );
01098
01099
01100
01101 return keys;
01102 }
01103
01104
01105 }