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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 27 12:48:44 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003