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