• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

libkpgp

kpgpbase6.cpp

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

libkpgp

Skip menu "libkpgp"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  •   doc
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal