libkdenetwork Library API Documentation

kpgpbase6.cpp

00001 /*
00002     kpgpbase6.cpp
00003 
00004     Copyright (C) 2001,2002 the KPGP authors
00005     See file AUTHORS.kpgp for details
00006 
00007     This file is part of KPGP, the KDE PGP/GnuPG support library.
00008 
00009     KPGP is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software Foundation,
00016     Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
00017  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #include <config.h>
00021 #endif
00022 
00023 #include "kpgpbase.h"
00024 
00025 #include <string.h> /* strncmp */
00026 
00027 #include <qdatetime.h>
00028 
00029 #include <klocale.h>
00030 #include <kdebug.h>
00031 
00032 #define PGP6 "pgp"
00033 
00034 namespace Kpgp {
00035 
00036 Base6::Base6()
00037   : Base2()
00038 {
00039 }
00040 
00041 
00042 Base6::~Base6()
00043 {
00044 }
00045 
00046 
00047 int
00048 Base6::decrypt( Block& block, const char *passphrase )
00049 {
00050   int index, index2;
00051   int exitStatus = 0;
00052 
00053   clear();
00054   input = block.text();
00055   exitStatus = run( PGP6 " +batchmode +language=C -f", passphrase);
00056   if( !output.isEmpty() )
00057     block.setProcessedText( output );
00058   block.setError( error );
00059 
00060   if(exitStatus == -1) {
00061     errMsg = i18n("error running PGP");
00062     status = RUN_ERR;
00063     block.setStatus( status );
00064     return status;
00065   }
00066 
00067   // encrypted message
00068   if( error.find("File is encrypted.") != -1)
00069   {
00070     //kdDebug(5100) << "kpgpbase: message is encrypted" << endl;
00071     status |= ENCRYPTED;
00072     if((index = error.find("Key for user ID")) != -1)
00073     {
00074       // Find out the key for which the phrase is needed
00075       index  = error.find(':', index) + 2;
00076       index2 = error.find('\n', index);
00077       block.setRequiredUserId( error.mid(index, index2 - index) );
00078       //kdDebug(5100) << "Base: key needed is \"" << block.requiredUserId() << "\"!\n";
00079 
00080       // Test output length to find out, if the passphrase is
00081       // bad. If someone knows a better way, please fix this.
00084       if (!passphrase || !output.length())
00085       {
00086     errMsg = i18n("Bad passphrase; could not decrypt.");
00087     //kdDebug(5100) << "Base: passphrase is bad" << endl;
00088         status |= BADPHRASE;
00089         status |= ERROR;
00090       }
00091     }
00092     else if( error.find("You do not have the secret key needed to decrypt this file.") != -1)
00093     {
00094       errMsg = i18n("You do not have the secret key for this message.");
00095       //kdDebug(5100) << "Base: no secret key for this message" << endl;
00096       status |= NO_SEC_KEY;
00097       status |= ERROR;
00098     }
00099   }
00100 
00101   // signed message
00102 
00103   // Examples (made with PGP 6.5.8)
00104   /* Example no. 1 (signed with unknown key):
00105    * File is signed.  signature not checked.
00106    * Signature made 2001/11/25 11:55 GMT
00107    * key does not meet validity threshold.
00108    *
00109    * WARNING:  Because this public key is not certified with a trusted
00110    * signature, it is not known with high confidence that this public key
00111    * actually belongs to: "(KeyID: 0x475027BD)".
00112    */
00113   /* Example no. 2 (signed with untrusted key):
00114    * File is signed.  Good signature from user "Joe User <joe@foo.bar>".
00115    * Signature made 2001/12/05 13:09 GMT
00116    *
00117    * WARNING:  Because this public key is not certified with a trusted
00118    * signature, it is not known with high confidence that this public key
00119    * actually belongs to: "Joe User <joe@foo.bar>".
00120    */
00121   /* Example no. 3 (signed with trusted key):
00122    * File is signed.  Good signature from user "Joe User <joe@foo.bar>".
00123    * Signature made 2001/12/05 13:09 GMT
00124    */
00125   if(((index = error.find("File is signed.")) != -1)
00126     || (error.find("Good signature") != -1 ))
00127   {
00128     //kdDebug(5100) << "Base: message is signed" << endl;
00129     status |= SIGNED;
00130     // determine the signature date
00131     if( ( index2 = error.find( "Signature made", index ) ) != -1 )
00132     {
00133       index2 += 15;
00134       int eol = error.find( '\n', index2 );
00135       block.setSignatureDate( error.mid( index2, eol-index2 ) );
00136       kdDebug(5100) << "Message was signed on '" << block.signatureDate() << "'\n";
00137     }
00138     else
00139       block.setSignatureDate( QCString() );
00140     // determine signature status and signature key
00141     if( error.find("signature not checked") != -1)
00142     {
00143       index = error.find("KeyID:",index);
00144       block.setSignatureKeyId( error.mid(index+9,8) );
00145       block.setSignatureUserId( QString::null );
00146       status |= UNKNOWN_SIG;
00147       status |= GOODSIG;
00148     }
00149     else if((index = error.find("Good signature")) != -1 )
00150     {
00151       status |= GOODSIG;
00152       // get signer
00153       index = error.find('"',index)+1;
00154       index2 = error.find('"', index);
00155       block.setSignatureUserId( error.mid(index, index2-index) );
00156 
00157       // get key ID of signer
00158       index = error.find("KeyID:",index2);
00159       if (index == -1)
00160         block.setSignatureKeyId( QCString() );
00161       else
00162         block.setSignatureKeyId( error.mid(index+9,8) );
00163     }
00164     else if( error.find("Can't find the right public key") != -1 )
00165     {
00166       // #### fix this hack
00167       // #### This doesn't happen with PGP 6.5.8 because it seems to
00168       // #### automatically create an empty pubring if it doesn't exist.
00169       status |= UNKNOWN_SIG;
00170       status |= GOODSIG; // this is a hack...
00171       block.setSignatureUserId( i18n("??? (file ~/.pgp/pubring.pkr not found)") );
00172       block.setSignatureKeyId( "???" );
00173     }
00174     else
00175     {
00176       status |= ERROR;
00177       block.setSignatureUserId( QString::null );
00178       block.setSignatureKeyId( QCString() );
00179     }
00180   }
00181   //kdDebug(5100) << "status = " << status << endl;
00182   block.setStatus( status );
00183   return status;
00184 }
00185 
00186 
00187 Key*
00188 Base6::readPublicKey( const KeyID& keyID,
00189                       const bool readTrust /* = false */,
00190                       Key* key /* = 0 */ )
00191 {
00192   int exitStatus = 0;
00193 
00194   status = 0;
00195   exitStatus = run( PGP6 " +batchmode -compatible +verbose=0 +language=C -kvvc "
00196                     "0x" + keyID, 0, true );
00197 
00198   if(exitStatus != 0) {
00199     status = ERROR;
00200     return 0;
00201   }
00202 
00203   key = parseSingleKey( output, key );
00204 
00205   if( key == 0 )
00206   {
00207     return 0;
00208   }
00209 
00210   if( readTrust )
00211   {
00212     exitStatus = run( PGP6 " +batchmode -compatible +verbose=0 +language=C -kc "
00213                       "0x" + keyID, 0, true );
00214 
00215     if(exitStatus != 0) {
00216       status = ERROR;
00217       return 0;
00218     }
00219 
00220     parseTrustDataForKey( key, output );
00221   }
00222 
00223   return key;
00224 }
00225 
00226 
00227 KeyList
00228 Base6::publicKeys( const QStringList & patterns )
00229 {
00230   return doGetPublicKeys( PGP6 " +batchmode -compatible +verbose=0 "
00231                           "+language=C -kvvc", patterns );
00232 }
00233 
00234 
00235 /*
00236 QStrList
00237 Base6::pubKeys()
00238 {
00239   int index, index2;
00240   int exitStatus = 0;
00241   int compatibleMode = 1;
00242 
00243   status = 0;
00244   exitStatus = run("pgp +batchmode +language=C -kv -f");
00245 
00246   if(exitStatus != 0) {
00247     status = ERROR;
00248     return 0;
00249   }
00250 
00251   //truncate trailing "\n"
00252   if (error.length() > 1) error.truncate(error.length()-1);
00253 
00254   QStrList publicKeys;
00255   index = error.find("bits/keyID",1); // skip first to "\n"
00256   if (index ==-1)
00257   {
00258     index = error.find("Type bits",1); // skip first to "\n"
00259     if (index == -1)
00260       return 0;
00261     else
00262       compatibleMode = 0;
00263   }
00264 
00265   while( (index = error.find("\n",index)) != -1)
00266   {
00267     //parse line
00268     QCString line;
00269     if( (index2 = error.find("\n",index+1)) != -1)
00270       // skip last line
00271     {
00272       int index3;
00273       if (compatibleMode)
00274       {
00275         int index_pub = error.find("pub ",index);
00276         int index_sec = error.find("sec ",index);
00277         if (index_pub < 0)
00278           index3 = index_sec;
00279         else if (index_sec < 0)
00280           index3 = index_pub;
00281         else
00282           index3 = (index_pub < index_sec ? index_pub : index_sec);
00283       }
00284       else
00285       {
00286         int index_rsa = error.find("RSA ",index);
00287         int index_dss = error.find("DSS ",index);
00288         if (index_rsa < 0)
00289           index3 = index_dss;
00290         else if (index_dss < 0)
00291           index3 = index_rsa;
00292         else
00293           index3 = (index_rsa < index_dss ? index_rsa : index_dss);
00294       }
00295 
00296       if( (index3 >index2) || (index3 == -1) )
00297       {
00298     // second address for the same key
00299     line = error.mid(index+1,index2-index-1);
00300     line = line.stripWhiteSpace();
00301       } else {
00302     // line with new key
00303     int index4 = error.find(QRegExp("/\\d{2}/\\d{2} "), index);
00304     line = error.mid(index4+7,index2-index4-7);
00305       }
00306       //kdDebug(5100) << "Base: found key for " << (const char *)line << endl;
00307 
00308       // don't add PGP's comments to the key list
00309       if (strncmp(line.data(),"*** KEY EXPIRED ***",19) &&
00310           line.find(QRegExp("^expires \\d{4}/\\d{2}/\\d{2}")) < 0 &&
00311           strncmp(line.data(),"*** DEFAULT SIGNING KEY ***",27)) {
00312         publicKeys.append(line);
00313       }
00314     }
00315     else
00316       break;
00317     index = index2;
00318   }
00319 
00320   // Also look for pgp key groups
00321   exitStatus = run("pgp +batchmode +language=C -gv -f");
00322 
00323   if(exitStatus != 0) {
00324     status = ERROR;
00325     return 0;
00326   }
00327 
00328   index = 0;
00329   while ( (index = error.find("\n >", index)) != -1 ) {
00330     QCString line;
00331     index += 4;
00332     index2 = error.find(" \"", index);
00333     line = error.mid(index, index2-index+1).stripWhiteSpace();
00334 
00335     //kdDebug(5100) << "Base6: found key group for " << line << endl;
00336     publicKeys.append(line);
00337   }
00338 
00339   return publicKeys;
00340 }
00341 */
00342 
00343 
00344 KeyList
00345 Base6::secretKeys( const QStringList & patterns )
00346 {
00347   return publicKeys( patterns );
00348 }
00349 
00350 
00351 int
00352 Base6::isVersion6()
00353 {
00354   int exitStatus = 0;
00355 
00356   exitStatus = run( PGP6, 0, true );
00357 
00358   if(exitStatus == -1) {
00359     errMsg = i18n("error running PGP");
00360     status = RUN_ERR;
00361     return 0;
00362   }
00363 
00364   if( error.find("Version 6") != -1)
00365   {
00366     //kdDebug(5100) << "kpgpbase: pgp version 6.x detected" << endl;
00367     return 1;
00368   }
00369 
00370   //kdDebug(5100) << "kpgpbase: not pgp version 6.x" << endl;
00371   return 0;
00372 }
00373 
00374 
00375 Key*
00376 Base6::parseKeyData( const QCString& output, int& offset, Key* key /* = 0 */ )
00377 // This function parses the data for a single key which is output by PGP 6
00378 // with the following command line arguments:
00379 //   +batchmode -compatible +verbose=0 +language=C -kvvc
00380 // It expects the key data to start at offset and returns the start of
00381 // the next key's data in offset.
00382 {
00383   if( ( strncmp( output.data() + offset, "DSS", 3 ) != 0 ) &&
00384       ( strncmp( output.data() + offset, "RSA", 3 ) != 0 ) )
00385   {
00386     kdDebug(5100) << "Unknown key type or corrupt key data.\n";
00387     return 0;
00388   }
00389 
00390   Subkey *subkey = 0;
00391   bool firstLine = true;
00392   bool canSign = false;
00393   bool canEncr = false;
00394   bool fpr = false;
00395 
00396   while( true )
00397   {
00398     int eol;
00399 
00400     // search the end of the current line
00401     if( ( eol = output.find( '\n', offset ) ) == -1 )
00402       break;
00403 
00404     //kdDebug(5100) << "Parsing: " << output.mid(offset, eol-offset) << endl;
00405 
00406     if( firstLine && ( !strncmp( output.data() + offset, "DSS", 3 ) ||
00407                        !strncmp( output.data() + offset, "RSA", 3 ) ) )
00408     { // line contains primary key data
00409       // Example 1:
00410       // RSA  1024      0xE2D074D3 2001/09/09 Test Key <testkey@xyz>
00411       // Example 2 (disabled key):
00412       // RSA@ 1024      0x8CCB2C1B 2001/11/04 Disabled Test Key <disabled@xyz>
00413       // Example 3 (expired key):
00414       // RSA  1024      0x7B94827D 2001/09/09 *** KEY EXPIRED ***
00415       // Example 4 (revoked key):
00416       // RSA  1024      0x956721F9 2001/09/09 *** KEY REVOKED ***
00417       // Example 5 (default signing key):
00418       // RSA  1024      0x12345678 2001/09/09 *** DEFAULT SIGNING KEY ***
00419       // Example 6 (expiring key):
00420       // RSA  2048      0xC11DB2E5 2000/02/24 expires 2001/12/31
00421       // Example 7 (complex example):
00422       // DSS  1024      0x80E104A7 2000/06/05 expires 2002/05/31
00423       // DSS  1024      0x80E104A7 2001/06/27 *** KEY REVOKED ***expires 2002/06/27
00424       //  DH  1024      0x80E104A7 2000/06/05 *** KEY REVOKED ****** KEY EXPIRED ***
00425       //kdDebug(5100)<<"Primary key data:\n";
00426       bool sign = false;
00427       bool encr = false;
00428 
00429       // set default key capabilities
00430       if( !strncmp( output.data() + offset, "DSS", 3 ) )
00431         sign = true;
00432       if( !strncmp( output.data() + offset, "RSA", 3 ) )
00433       {
00434         sign = true;
00435         encr = true;
00436       }
00437 
00438       int pos, pos2;
00439 
00440       if( key == 0 )
00441         key = new Key();
00442       else
00443         key->clear();
00444 
00445       subkey = new Subkey( "", false );
00446       key->addSubkey( subkey );
00447       // expiration date defaults to never
00448       subkey->setExpirationDate( -1 );
00449 
00450       // Key Flags
00451       switch( output[offset+3] )
00452       {
00453       case ' ': // nothing special
00454         break;
00455       case '@': // disabled key
00456         subkey->setDisabled( true );
00457         key->setDisabled( true );
00458         break;
00459       default:
00460         kdDebug(5100) << "Unknown key flag.\n";
00461       }
00462 
00463       // Key Length
00464       pos = offset + 4;
00465       while( output[pos] == ' ' )
00466         pos++;
00467       pos2 = output.find( ' ', pos );
00468       subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
00469       //kdDebug(5100) << "Key Length: "<<subkey->keyLength()<<endl;
00470 
00471       // Key ID
00472       pos = pos2 + 1;
00473       while( output[pos] == ' ' )
00474         pos++;
00475       pos += 2; // skip the '0x'
00476       pos2 = output.find( ' ', pos );
00477       subkey->setKeyID( output.mid( pos, pos2-pos ) );
00478       //kdDebug(5100) << "Key ID: "<<subkey->keyID()<<endl;
00479 
00480       // Creation Date
00481       pos = pos2 + 1;
00482       while( output[pos] == ' ' )
00483         pos++;
00484       pos2 = output.find( ' ', pos );
00485       int year = output.mid( pos, 4 ).toInt();
00486       int month = output.mid( pos+5, 2 ).toInt();
00487       int day = output.mid( pos+8, 2 ).toInt();
00488       QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00489       QDateTime epoch( QDate( 1970, 01, 01 ), QTime( 00, 00 ) );
00490       // The calculated creation date isn't exactly correct because QDateTime
00491       // doesn't know anything about timezones and always assumes local time
00492       // although epoch is of course UTC. But as PGP 6 anyway doesn't print
00493       // the time this doesn't matter too much.
00494       subkey->setCreationDate( epoch.secsTo( dt ) );
00495 
00496       // User ID or key properties
00497       pos = pos2 + 1;
00498       while( output[pos] == ' ' )
00499         pos++;
00500       while( pos < eol )
00501       { // loop over User ID resp. key properties
00502         if( !strncmp( output.data() + pos, "*** KEY REVOKED ***", 19 ) )
00503         {
00504           sign = false;
00505           encr = false;
00506           subkey->setRevoked( true );
00507           key->setRevoked( true );
00508           pos += 19;
00509           //kdDebug(5100) << "Key was revoked.\n";
00510         }
00511         else if( !strncmp( output.data() + pos, "*** KEY EXPIRED ***", 19 ) )
00512         {
00513           sign = false;
00514           encr = false;
00515           subkey->setExpired( true );
00516           key->setExpired( true );
00517           pos += 19;
00518           //kdDebug(5100) << "Key has expired.\n";
00519         }
00520         else if( !strncmp( output.data() + pos, "expires ", 8 ) )
00521         {
00522           pos += 8;
00523           int year = output.mid( pos, 4 ).toInt();
00524           int month = output.mid( pos+5, 2 ).toInt();
00525           int day = output.mid( pos+8, 2 ).toInt();
00526           QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00527           // Here the same comments as for the creation date are valid.
00528           subkey->setExpirationDate( epoch.secsTo( dt ) );
00529           pos += 10;
00530           //kdDebug(5100) << "Key expires...\n";
00531         }
00532         else if( !strncmp( output.data() + pos, "*** DEFAULT SIGNING KEY ***", 27 ) )
00533         {
00534           pos += 27;
00535           //kdDebug(5100) << "Key is default signing key.\n";
00536         }
00537         else
00538         {
00539           QCString uid = output.mid( pos, eol-pos );
00540           key->addUserID( uid );
00541           pos = eol;
00542           //kdDebug(5100) << "User ID:"<<uid<<endl;
00543         }
00544       }
00545       // set key capabilities of the primary subkey
00546       subkey->setCanEncrypt( encr );
00547       subkey->setCanSign( sign );
00548       subkey->setCanCertify( sign );
00549       // remember the global key capabilities
00550       canSign = sign;
00551       canEncr = encr;
00552     }
00553     else if( !strncmp( output.data() + offset, "DSS", 3 ) ||
00554              !strncmp( output.data() + offset, " DH", 3 ) ||
00555              !strncmp( output.data() + offset, "RSA", 3 ) )
00556     { // line contains secondary key data (or data for the next key)
00557       if( fpr )
00558         break; // here begins the next key's data
00559       //kdDebug(5100)<<"Secondary key data:\n";
00560 
00561       if( key == 0 )
00562         break;
00563 
00564       bool sign = false;
00565       bool encr = false;
00566 
00567       // set default key capabilities
00568       if( !strncmp( output.data() + offset, "DSS", 3 ) )
00569         sign = true;
00570       if( !strncmp( output.data() + offset, " DH", 3 ) )
00571         encr = true;
00572       if( !strncmp( output.data() + offset, "RSA", 3 ) )
00573       {
00574         sign = true;
00575         encr = true;
00576       }
00577 
00578       int pos, pos2;
00579 
00580       // Key Length of secondary key (ignored)
00581       pos = offset + 4;
00582       while( output[pos] == ' ' )
00583         pos++;
00584       pos2 = output.find( ' ', pos );
00585 
00586       // Key ID (ignored as it is anyway equal to the primary key id)
00587       pos = pos2 + 1;
00588       while( output[pos] == ' ' )
00589         pos++;
00590       pos2 = output.find( ' ', pos );
00591 
00592       // Creation Date of secondary key (ignored)
00593       pos = pos2 + 1;
00594       while( output[pos] == ' ' )
00595         pos++;
00596       pos2 = output.find( ' ', pos );
00597 
00598       // User ID or key properties
00599       pos = pos2 + 1;
00600       while( output[pos] == ' ' )
00601         pos++;
00602       while( pos < eol )
00603       { // loop over User ID resp. key properties
00604         if( !strncmp( output.data() + pos, "*** KEY REVOKED ***", 19 ) )
00605         {
00606           sign = false;
00607           encr = false;
00608           pos += 19;
00609           //kdDebug(5100) << "Key was revoked.\n";
00610         }
00611         else if( !strncmp( output.data() + pos, "*** KEY EXPIRED ***", 19 ) )
00612         {
00613           sign = false;
00614           encr = false;
00615           pos += 19;
00616           //kdDebug(5100) << "Key has expired.\n";
00617         }
00618         else if( !strncmp( output.data() + pos, "expires ", 8 ) )
00619         {
00620           pos += 18; // skip the expiration date
00621           //kdDebug(5100) << "Key expires...\n";
00622         }
00623         else if( !strncmp( output.data() + pos, "*** DEFAULT SIGNING KEY ***", 27 ) )
00624         {
00625           pos += 27;
00626           //kdDebug(5100) << "Key is default signing key.\n";
00627         }
00628         else
00629         {
00630           QCString uid = output.mid( pos, eol-pos );
00631           key->addUserID( uid );
00632           pos = eol;
00633           //kdDebug(5100) << "User ID:"<<uid<<endl;
00634         }
00635       }
00636       // store the global key capabilities
00637       canSign |= sign;
00638       canEncr |= encr;
00639     }
00640     else if( !strncmp( output.data() + offset, "Unknown type", 12 ) )
00641     { // line contains key data of unknown type (ignored)
00642       kdDebug(5100)<<"Unknown key type.\n";
00643     }
00644     else if( output[offset] == ' ' )
00645     { // line contains additional key data
00646       if( key == 0 )
00647         break;
00648       //kdDebug(5100)<<"Additional key data:\n";
00649 
00650       int pos = offset + 1;
00651       while( output[pos] == ' ' )
00652         pos++;
00653 
00654       if( !strncmp( output.data() + pos, "Key fingerprint = ", 18 ) )
00655       { // line contains a fingerprint
00656         // Example:
00657         //           Key fingerprint =  D0 6C BB 3A F5 16 82 C4  F3 A0 8A B3 7B 16 99 70
00658 
00659         fpr = true; // we found a fingerprint
00660 
00661         pos += 18;
00662         QCString fingerprint = output.mid( pos, eol-pos );
00663         // remove white space from the fingerprint
00664     for ( int idx = 0 ; (idx = fingerprint.find(' ', idx)) >= 0 ; )
00665       fingerprint.replace( idx, 1, "" );
00666 
00667         //kdDebug(5100)<<"Fingerprint: "<<fingerprint<<endl;
00668         subkey->setFingerprint( fingerprint );
00669       }
00670       else
00671       { // line contains an additional user id
00672         // Example:
00673         //                               Test key (2nd user ID) <abc@xyz>
00674 
00675         //kdDebug(5100)<<"User ID: "<<output.mid( pos, eol-pos )<<endl;
00676         key->addUserID( output.mid( pos, eol-pos ) );
00677       }
00678     }
00679     else if( !strncmp( output.data() + offset, "sig", 3 ) )
00680     { // line contains signature data (ignored)
00681       //kdDebug(5100)<<"Signature.\n";
00682     }
00683     else // end of key data
00684       break;
00685 
00686     firstLine = false;
00687     offset = eol + 1;
00688   }
00689 
00690   if( key != 0 )
00691   {
00692     // set the global key capabilities
00693     key->setCanEncrypt( canEncr );
00694     key->setCanSign( canSign );
00695     key->setCanCertify( canSign );
00696     //kdDebug(5100)<<"Key capabilities: "<<(canEncr?"E":"")<<(canSign?"SC":"")<<endl;
00697   }
00698 
00699   return key;
00700 }
00701 
00702 
00703 Key*
00704 Base6::parseSingleKey( const QCString& output, Key* key /* = 0 */ )
00705 {
00706   int offset;
00707 
00708   // search start of header line
00709   if( !strncmp( output.data(), "Type bits", 9 ) )
00710     offset = 9;
00711   else
00712   {
00713     offset = output.find( "\nType bits" );
00714     if( offset == -1 )
00715       return 0;
00716     else
00717       offset += 10;
00718   }
00719 
00720   // key data begins in the next line
00721   offset = output.find( '\n', offset ) + 1;
00722   if( offset == 0 )
00723     return 0;
00724 
00725   key = parseKeyData( output, offset, key );
00726 
00727   //kdDebug(5100) << "finished parsing keys" << endl;
00728 
00729   return key;
00730 }
00731 
00732 
00733 KeyList
00734 Base6::parseKeyList( const QCString& output, bool secretKeys )
00735 {
00736   kdDebug(5100) << "Kpgp::Base6::parseKeyList()" << endl;
00737   KeyList keys;
00738   Key *key = 0;
00739   int offset;
00740 
00741   // search start of header line
00742   if( !strncmp( output.data(), "Type bits", 9 ) )
00743     offset = 0;
00744   else
00745   {
00746     offset = output.find( "\nType bits" ) + 1;
00747     if( offset == 0 )
00748       return keys;
00749   }
00750 
00751   // key data begins in the next line
00752   offset = output.find( '\n', offset ) + 1;
00753   if( offset == -1 )
00754     return keys;
00755 
00756   do
00757   {
00758     key = parseKeyData( output, offset );
00759     if( key != 0 )
00760     {
00761       key->setSecret( secretKeys );
00762       keys.append( key );
00763     }
00764   }
00765   while( key != 0 );
00766 
00767   //kdDebug(5100) << "finished parsing keys" << endl;
00768 
00769   return keys;
00770 }
00771 
00772 
00773 void
00774 Base6::parseTrustDataForKey( Key* key, const QCString& str )
00775 {
00776   if( ( key == 0 ) || str.isEmpty() )
00777     return;
00778 
00779   QCString keyID = "0x" + key->primaryKeyID();
00780   UserIDList userIDs = key->userIDs();
00781 
00782   // search the start of the trust data
00783   int offset = str.find( "\n\n  KeyID" );
00784   if( offset == -1 )
00785     return;
00786 
00787   offset = str.find( '\n', offset ) + 1;
00788   if( offset == 0 )
00789     return;
00790 
00791   bool ultimateTrust = false;
00792   if( !strncmp( str.data() + offset+13, "ultimate", 8 ) )
00793     ultimateTrust = true;
00794 
00795   while( true )
00796   { // loop over all trust information about this key
00797 
00798     int eol;
00799 
00800     // search the end of the current line
00801     if( ( eol = str.find( '\n', offset ) ) == -1 )
00802       break;
00803 
00804     if( str[offset+23] != ' ' )
00805     { // line contains a validity value for a user ID
00806 
00807       // determine the validity
00808       Validity validity = KPGP_VALIDITY_UNKNOWN;
00809       if( !strncmp( str.data() + offset+23, "complete", 8 ) )
00810         if( ultimateTrust )
00811           validity = KPGP_VALIDITY_ULTIMATE;
00812         else
00813           validity = KPGP_VALIDITY_FULL;
00814       else if( !strncmp( str.data() + offset+23, "marginal", 8 ) )
00815         validity = KPGP_VALIDITY_MARGINAL;
00816       else if( !strncmp( str.data() + offset+23, "invalid", 7 ) )
00817         validity = KPGP_VALIDITY_UNDEFINED;
00818 
00819       // determine the user ID
00820       int pos = offset + 33;
00821       QString uid = str.mid( pos, eol-pos );
00822 
00823       // set the validity of the corresponding user ID
00824       for( UserIDListIterator it( userIDs ); it.current(); ++it )
00825         if( (*it)->text() == uid )
00826         {
00827           kdDebug(5100)<<"Setting the validity of "<<uid<<" to "<<validity<<endl;
00828           (*it)->setValidity( validity );
00829           break;
00830         }
00831     }
00832 
00833     offset = eol + 1;
00834   }
00835 }
00836 
00837 
00838 } // namespace Kpgp
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 17 09:52:21 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003