00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <fstream>
00014 #include <sys/file.h>
00015 #include <cstdio>
00016 #include <unistd.h>
00017
00018 #include <boost/format.hpp>
00019
00020 #include "zypp/TmpPath.h"
00021 #include "zypp/ZYppFactory.h"
00022 #include "zypp/ZYpp.h"
00023
00024 #include "zypp/base/LogTools.h"
00025 #include "zypp/base/IOStream.h"
00026 #include "zypp/base/String.h"
00027 #include "zypp/base/Regex.h"
00028 #include "zypp/base/Gettext.h"
00029 #include "zypp/base/WatchFile.h"
00030 #include "zypp/PathInfo.h"
00031 #include "zypp/KeyRing.h"
00032 #include "zypp/ExternalProgram.h"
00033 #include "zypp/TmpPath.h"
00034
00035 using std::endl;
00036
00037 #undef ZYPP_BASE_LOGGER_LOGGROUP
00038 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
00039
00040 #define GPG_BINARY "/usr/bin/gpg2"
00041
00043 namespace zypp
00044 {
00045
00046 IMPL_PTR_TYPE(KeyRing);
00047
00048 namespace
00049 {
00050 KeyRing::DefaultAccept _keyRingDefaultAccept( KeyRing::ACCEPT_NOTHING );
00051 }
00052
00053 KeyRing::DefaultAccept KeyRing::defaultAccept()
00054 { return _keyRingDefaultAccept; }
00055
00056 void KeyRing::setDefaultAccept( DefaultAccept value_r )
00057 {
00058 MIL << "Set new KeyRing::DefaultAccept: " << value_r << endl;
00059 _keyRingDefaultAccept = value_r;
00060 }
00061
00062 bool KeyRingReport::askUserToAcceptUnsignedFile( const std::string & file, const KeyContext & keycontext )
00063 { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNSIGNED_FILE ); }
00064
00065 KeyRingReport::KeyTrust
00066 KeyRingReport::askUserToAcceptKey( const PublicKey & key, const KeyContext & keycontext )
00067 {
00068 if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_KEY_TEMPORARILY ) )
00069 return KEY_TRUST_TEMPORARILY;
00070 if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_AND_IMPORT_KEY ) )
00071 return KEY_TRUST_AND_IMPORT;
00072 return KEY_DONT_TRUST;
00073 }
00074
00075 bool KeyRingReport::askUserToAcceptUnknownKey( const std::string & file, const std::string & id, const KeyContext & keycontext )
00076 { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNKNOWNKEY ); }
00077
00078 bool KeyRingReport::askUserToAcceptVerificationFailed( const std::string & file, const PublicKey & key, const KeyContext & keycontext )
00079 { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_VERIFICATION_FAILED ); }
00080
00081 namespace
00082 {
00090 struct CachedPublicKeyData
00091 {
00092 const std::list<PublicKeyData> & operator()( const Pathname & keyring_r ) const
00093 { return getData( keyring_r ); }
00094
00095 private:
00096 struct Cache
00097 {
00098 scoped_ptr<WatchFile> _keyringP;
00099 std::list<PublicKeyData> _data;
00100
00101
00102
00103 Cache() {}
00104 Cache( const Cache & rhs ) {}
00105 };
00106
00107 typedef std::map<Pathname,Cache> CacheMap;
00108
00109 const std::list<PublicKeyData> & getData( const Pathname & keyring_r ) const
00110 {
00111 Cache & cache( _cacheMap[keyring_r] );
00112 if ( ! cache._keyringP )
00113 {
00114
00115 cache._keyringP.reset( new WatchFile( keyring_r/"pubring.gpg", WatchFile::NO_INIT ) );
00116 }
00117 return getData( keyring_r, cache );
00118 }
00119
00120 const std::list<PublicKeyData> & getData( const Pathname & keyring_r, Cache & cache_r ) const
00121 {
00122 if ( cache_r._keyringP->hasChanged() )
00123 {
00124 const char* argv[] =
00125 {
00126 GPG_BINARY,
00127 "--list-sigs",
00128 "--homedir", keyring_r.c_str(),
00129 "--no-default-keyring",
00130 "--quiet",
00131 "--with-colons",
00132 "--fixed-list-mode",
00133 "--with-fingerprint",
00134 "--no-tty",
00135 "--no-greeting",
00136 "--batch",
00137 "--status-fd", "1",
00138 NULL
00139 };
00140
00141 PublicKeyScanner scanner;
00142 ExternalProgram prog( argv ,ExternalProgram::Discard_Stderr, false, -1, true );
00143 for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
00144 {
00145 scanner.scan( line );
00146 }
00147 prog.close();
00148
00149 cache_r._data.swap( scanner._keys );
00150 MIL << "Found keys: " << cache_r._data << endl;
00151 }
00152 return cache_r._data;
00153 }
00154
00155 mutable CacheMap _cacheMap;
00156 };
00158 }
00159
00161
00162
00163
00165 struct KeyRing::Impl
00166 {
00167 Impl( const Pathname & baseTmpDir )
00168 : _trusted_tmp_dir( baseTmpDir, "zypp-trusted-kr" )
00169 , _general_tmp_dir( baseTmpDir, "zypp-general-kr" )
00170 , _base_dir( baseTmpDir )
00171 {
00172 MIL << "Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
00173 }
00174
00175 void importKey( const PublicKey & key, bool trusted = false );
00176 void multiKeyImport( const Pathname & keyfile_r, bool trusted_r = false );
00177 void deleteKey( const std::string & id, bool trusted );
00178
00179 std::string readSignatureKeyId( const Pathname & signature );
00180
00181 bool isKeyTrusted( const std::string & id )
00182 { return bool(publicKeyExists( id, trustedKeyRing() )); }
00183 bool isKeyKnown( const std::string & id )
00184 { return publicKeyExists( id, trustedKeyRing() ) || publicKeyExists( id, generalKeyRing() ); }
00185
00186 std::list<PublicKey> trustedPublicKeys()
00187 { return publicKeys( trustedKeyRing() ); }
00188 std::list<PublicKey> publicKeys()
00189 { return publicKeys( generalKeyRing() ); }
00190
00191 const std::list<PublicKeyData> & trustedPublicKeyData()
00192 { return publicKeyData( trustedKeyRing() ); }
00193 const std::list<PublicKeyData> & publicKeyData()
00194 { return publicKeyData( generalKeyRing() ); }
00195
00196 void dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
00197 { dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream ); }
00198
00199 PublicKey exportPublicKey( const PublicKeyData & keyData )
00200 { return exportKey( keyData, generalKeyRing() ); }
00201 PublicKey exportTrustedPublicKey( const PublicKeyData & keyData )
00202 { return exportKey( keyData, trustedKeyRing() ); }
00203
00204 bool verifyFileSignatureWorkflow(
00205 const Pathname & file,
00206 const std::string & filedesc,
00207 const Pathname & signature,
00208 const KeyContext & keycontext = KeyContext());
00209
00210 bool verifyFileSignature( const Pathname & file, const Pathname & signature )
00211 { return verifyFile( file, signature, generalKeyRing() ); }
00212 bool verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
00213 { return verifyFile( file, signature, trustedKeyRing() ); }
00214
00215 private:
00216 bool verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring );
00217 void importKey( const Pathname & keyfile, const Pathname & keyring );
00218
00219 PublicKey exportKey( const std::string & id, const Pathname & keyring );
00220 PublicKey exportKey( const PublicKeyData & keyData, const Pathname & keyring );
00221
00222 void dumpPublicKey( const std::string & id, const Pathname & keyring, std::ostream & stream );
00223 filesystem::TmpFile dumpPublicKeyToTmp( const std::string & id, const Pathname & keyring );
00224
00225 void deleteKey( const std::string & id, const Pathname & keyring );
00226
00227 std::list<PublicKey> publicKeys( const Pathname & keyring);
00228 const std::list<PublicKeyData> & publicKeyData( const Pathname & keyring )
00229 { return cachedPublicKeyData( keyring ); }
00230
00232 PublicKeyData publicKeyExists( const std::string & id, const Pathname & keyring );
00233
00234 const Pathname generalKeyRing() const
00235 { return _general_tmp_dir.path(); }
00236 const Pathname trustedKeyRing() const
00237 { return _trusted_tmp_dir.path(); }
00238
00239
00240 filesystem::TmpDir _trusted_tmp_dir;
00241 filesystem::TmpDir _general_tmp_dir;
00242 Pathname _base_dir;
00243
00244 private:
00250 CachedPublicKeyData cachedPublicKeyData;
00251
00252 public:
00254 static shared_ptr<Impl> nullimpl()
00255 {
00256 static shared_ptr<Impl> _nullimpl( new Impl( filesystem::TmpPath::defaultLocation() ) );
00257 return _nullimpl;
00258 }
00259
00260 private:
00261 friend Impl * rwcowClone<Impl>( const Impl * rhs );
00263 Impl * clone() const
00264 { return new Impl( *this ); }
00265 };
00267
00268
00269 void KeyRing::Impl::importKey( const PublicKey & key, bool trusted )
00270 {
00271 importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
00272
00273 if ( trusted )
00274 {
00275 callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
00276 callback::SendReport<KeyRingSignals> emitSignal;
00277
00278 rpmdbEmitSignal->trustedKeyAdded( key );
00279 emitSignal->trustedKeyAdded( key );
00280 }
00281 }
00282
00283 void KeyRing::Impl::multiKeyImport( const Pathname & keyfile_r, bool trusted_r )
00284 {
00285 importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
00286 }
00287
00288 void KeyRing::Impl::deleteKey( const std::string & id, bool trusted )
00289 {
00290 PublicKey key;
00291
00292 if ( trusted )
00293 {
00294 key = exportKey( id, trustedKeyRing() );
00295 }
00296
00297 deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
00298
00299 if ( trusted )
00300 {
00301 callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
00302 callback::SendReport<KeyRingSignals> emitSignal;
00303
00304 rpmdbEmitSignal->trustedKeyRemoved( key );
00305 emitSignal->trustedKeyRemoved( key );
00306 }
00307 }
00308
00309 PublicKeyData KeyRing::Impl::publicKeyExists( const std::string & id, const Pathname & keyring )
00310 {
00311 MIL << "Searching key [" << id << "] in keyring " << keyring << endl;
00312 const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
00313 for_( it, keys.begin(), keys.end() )
00314 {
00315 if ( id == (*it).id() )
00316 {
00317 return *it;
00318 }
00319 }
00320 return PublicKeyData();
00321 }
00322
00323 PublicKey KeyRing::Impl::exportKey( const PublicKeyData & keyData, const Pathname & keyring )
00324 {
00325 return PublicKey( dumpPublicKeyToTmp( keyData.id(), keyring ), keyData );
00326 }
00327
00328 PublicKey KeyRing::Impl::exportKey( const std::string & id, const Pathname & keyring )
00329 {
00330 PublicKeyData keyData( publicKeyExists( id, keyring ) );
00331 if ( keyData )
00332 return PublicKey( dumpPublicKeyToTmp( keyData.id(), keyring ), keyData );
00333
00334
00335 WAR << "No key " << id << " to export from " << keyring << endl;
00336 return PublicKey();
00337 }
00338
00339
00340 void KeyRing::Impl::dumpPublicKey( const std::string & id, const Pathname & keyring, std::ostream & stream )
00341 {
00342 const char* argv[] =
00343 {
00344 GPG_BINARY,
00345 "-a",
00346 "--export",
00347 "--homedir", keyring.asString().c_str(),
00348 "--no-default-keyring",
00349 "--quiet",
00350 "--no-tty",
00351 "--no-greeting",
00352 "--no-permission-warning",
00353 "--batch",
00354 id.c_str(),
00355 NULL
00356 };
00357 ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
00358 for ( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
00359 {
00360 stream << line;
00361 }
00362 prog.close();
00363 }
00364
00365 filesystem::TmpFile KeyRing::Impl::dumpPublicKeyToTmp( const std::string & id, const Pathname & keyring )
00366 {
00367 filesystem::TmpFile tmpFile( _base_dir, "pubkey-"+id+"-" );
00368 MIL << "Going to export key " << id << " from " << keyring << " to " << tmpFile.path() << endl;
00369
00370 std::ofstream os( tmpFile.path().c_str() );
00371 dumpPublicKey( id, keyring, os );
00372 os.close();
00373 return tmpFile;
00374 }
00375
00376 bool KeyRing::Impl::verifyFileSignatureWorkflow(
00377 const Pathname & file,
00378 const std::string & filedesc,
00379 const Pathname & signature,
00380 const KeyContext & context )
00381 {
00382 callback::SendReport<KeyRingReport> report;
00383 MIL << "Going to verify signature for " << filedesc << " ( " << file << " ) with " << signature << endl;
00384
00385
00386 if( signature.empty() || (!PathInfo( signature ).isExist()) )
00387 {
00388 bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
00389 MIL << "User decision on unsigned file: " << res << endl;
00390 return res;
00391 }
00392
00393
00394 std::string id = readSignatureKeyId( signature );
00395
00396
00397 PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) );
00398 if ( trustedKeyData )
00399 {
00400 MIL << "Key is trusted: " << trustedKeyData << endl;
00401
00402
00403
00404 PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
00405 if ( generalKeyData )
00406 {
00407
00408
00409 if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
00410 && trustedKeyData.created() < generalKeyData.created() )
00411 {
00412 MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
00413 importKey( exportKey( generalKeyData, generalKeyRing() ), true );
00414 trustedKeyData = generalKeyData = PublicKeyData();
00415 }
00416 }
00417
00418
00419 if ( verifyFile( file, signature, trustedKeyRing() ) )
00420 return true;
00421 else
00422 {
00423 if ( ! trustedKeyData )
00424 trustedKeyData = publicKeyExists( id, trustedKeyRing() );
00425 return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
00426 }
00427 }
00428 else
00429 {
00430 PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
00431 if ( generalKeyData )
00432 {
00433 PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
00434 MIL << "Exported key " << id << " to " << key.path() << endl;
00435 MIL << "Key " << id << " " << key.name() << " is not trusted" << endl;
00436
00437
00438 KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context );
00439 if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY ||
00440 reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
00441 {
00442 MIL << "User wants to trust key " << id << " " << key.name() << endl;
00443
00444
00445 Pathname whichKeyring;
00446 if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
00447 {
00448 MIL << "User wants to import key " << id << " " << key.name() << endl;
00449 importKey( key, true );
00450 whichKeyring = trustedKeyRing();
00451 }
00452 else
00453 whichKeyring = generalKeyRing();
00454
00455
00456 if ( verifyFile( file, signature, whichKeyring ) )
00457 {
00458 MIL << "File signature is verified" << endl;
00459 return true;
00460 }
00461 else
00462 {
00463 MIL << "File signature check fails" << endl;
00464 if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
00465 {
00466 MIL << "User continues anyway." << endl;
00467 return true;
00468 }
00469 else
00470 {
00471 MIL << "User does not want to continue" << endl;
00472 return false;
00473 }
00474 }
00475 }
00476 else
00477 {
00478 MIL << "User does not want to trust key " << id << " " << key.name() << endl;
00479 return false;
00480 }
00481 }
00482 else
00483 {
00484
00485 MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
00486 if ( report->askUserToAcceptUnknownKey( filedesc, id, context ) )
00487 {
00488 MIL << "User wants to accept unknown key " << id << endl;
00489 return true;
00490 }
00491 else
00492 {
00493 MIL << "User does not want to accept unknown key " << id << endl;
00494 return false;
00495 }
00496 }
00497 }
00498 return false;
00499 }
00500
00501 std::list<PublicKey> KeyRing::Impl::publicKeys( const Pathname & keyring )
00502 {
00503 const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
00504 std::list<PublicKey> ret;
00505
00506 for_( it, keys.begin(), keys.end() )
00507 {
00508 PublicKey key( exportKey( *it, keyring ) );
00509 ret.push_back( key );
00510 MIL << "Found key " << key << endl;
00511 }
00512 return ret;
00513 }
00514
00515 void KeyRing::Impl::importKey( const Pathname & keyfile, const Pathname & keyring )
00516 {
00517 if ( ! PathInfo( keyfile ).isExist() )
00518
00519 ZYPP_THROW(KeyRingException(boost::str(boost::format(
00520 _("Tried to import not existent key %s into keyring %s"))
00521 % keyfile.asString() % keyring.asString())));
00522
00523 const char* argv[] =
00524 {
00525 GPG_BINARY,
00526 "--import",
00527 "--homedir", keyring.asString().c_str(),
00528 "--no-default-keyring",
00529 "--quiet",
00530 "--no-tty",
00531 "--no-greeting",
00532 "--no-permission-warning",
00533 "--status-fd", "1",
00534 keyfile.asString().c_str(),
00535 NULL
00536 };
00537
00538 ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
00539 prog.close();
00540 }
00541
00542 void KeyRing::Impl::deleteKey( const std::string & id, const Pathname & keyring )
00543 {
00544 const char* argv[] =
00545 {
00546 GPG_BINARY,
00547 "--delete-keys",
00548 "--homedir", keyring.asString().c_str(),
00549 "--no-default-keyring",
00550 "--yes",
00551 "--quiet",
00552 "--no-tty",
00553 "--batch",
00554 "--status-fd", "1",
00555 id.c_str(),
00556 NULL
00557 };
00558
00559 ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
00560
00561 int code = prog.close();
00562 if ( code )
00563 ZYPP_THROW(Exception(_("Failed to delete key.")));
00564 else
00565 MIL << "Deleted key " << id << " from keyring " << keyring << endl;
00566 }
00567
00568
00569 std::string KeyRing::Impl::readSignatureKeyId( const Pathname & signature )
00570 {
00571 if ( ! PathInfo( signature ).isFile() )
00572 ZYPP_THROW(Exception(boost::str(boost::format(
00573 _("Signature file %s not found"))% signature.asString())));
00574
00575 MIL << "Determining key id if signature " << signature << endl;
00576
00577 filesystem::TmpDir dir( _base_dir, "fake-keyring" );
00578
00579 const char* argv[] =
00580 {
00581 GPG_BINARY,
00582 "--homedir", dir.path().asString().c_str(),
00583 "--no-default-keyring",
00584 "--quiet",
00585 "--no-tty",
00586 "--no-greeting",
00587 "--batch",
00588 "--status-fd", "1",
00589 signature.asString().c_str(),
00590 NULL
00591 };
00592
00593 ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
00594
00595 std::string line;
00596 int count = 0;
00597
00598 str::regex rxNoKey( "^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
00599 std::string id;
00600 for( line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
00601 {
00602
00603 str::smatch what;
00604 if( str::regex_match( line, what, rxNoKey ) )
00605 {
00606 if ( what.size() >= 1 )
00607 {
00608 id = what[1];
00609 break;
00610 }
00611
00612 }
00613 }
00614
00615 if ( count == 0 )
00616 {
00617 MIL << "no output" << endl;
00618 }
00619
00620 MIL << "Determined key id [" << id << "] for signature " << signature << endl;
00621 prog.close();
00622 return id;
00623 }
00624
00625 bool KeyRing::Impl::verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring )
00626 {
00627 const char* argv[] =
00628 {
00629 GPG_BINARY,
00630 "--verify",
00631 "--homedir", keyring.asString().c_str(),
00632 "--no-default-keyring",
00633 "--quiet",
00634 "--no-tty",
00635 "--batch",
00636 "--no-greeting",
00637 "--status-fd", "1",
00638 signature.asString().c_str(),
00639 file.asString().c_str(),
00640 NULL
00641 };
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
00654
00655 return ( prog.close() == 0 ) ? true : false;
00656 }
00657
00659
00661
00662
00663
00665
00666 KeyRing::KeyRing( const Pathname & baseTmpDir )
00667 : _pimpl( new Impl( baseTmpDir ) )
00668 {}
00669
00670 KeyRing::~KeyRing()
00671 {}
00672
00673
00674 void KeyRing::importKey( const PublicKey & key, bool trusted )
00675 { _pimpl->importKey( key, trusted ); }
00676
00677 void KeyRing::multiKeyImport( const Pathname & keyfile_r, bool trusted_r )
00678 { _pimpl->multiKeyImport( keyfile_r, trusted_r ); }
00679
00680 std::string KeyRing::readSignatureKeyId( const Pathname & signature )
00681 { return _pimpl->readSignatureKeyId( signature ); }
00682
00683 void KeyRing::deleteKey( const std::string & id, bool trusted )
00684 { _pimpl->deleteKey( id, trusted ); }
00685
00686 std::list<PublicKey> KeyRing::publicKeys()
00687 { return _pimpl->publicKeys(); }
00688
00689 std:: list<PublicKey> KeyRing::trustedPublicKeys()
00690 { return _pimpl->trustedPublicKeys(); }
00691
00692 std::list<PublicKeyData> KeyRing::publicKeyData()
00693 { return _pimpl->publicKeyData(); }
00694
00695 std::list<PublicKeyData> KeyRing::trustedPublicKeyData()
00696 { return _pimpl->trustedPublicKeyData(); }
00697
00698 std::list<std::string> KeyRing::publicKeyIds()
00699 {
00700 const std::list<PublicKeyData> & keys( publicKeyData() );
00701 std::list<std::string> ret;
00702 for_( it, keys.begin(), keys.end() )
00703 {
00704 ret.push_back( (*it).id() );
00705 }
00706 return ret;
00707 }
00708
00709 std::list<std::string> KeyRing::trustedPublicKeyIds()
00710 {
00711 const std::list<PublicKeyData> & keys( trustedPublicKeyData() );
00712 std::list<std::string> ret;
00713 for_( it, keys.begin(), keys.end() )
00714 {
00715 ret.push_back( (*it).id() );
00716 }
00717 return ret;
00718 }
00719
00720 bool KeyRing::verifyFileSignatureWorkflow(
00721 const Pathname & file,
00722 const std::string filedesc,
00723 const Pathname & signature,
00724 const KeyContext & keycontext )
00725 { return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, keycontext ); }
00726
00727 bool KeyRing::verifyFileSignature( const Pathname & file, const Pathname & signature )
00728 { return _pimpl->verifyFileSignature( file, signature ); }
00729
00730 bool KeyRing::verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
00731 { return _pimpl->verifyFileTrustedSignature( file, signature ); }
00732
00733 void KeyRing::dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
00734 { _pimpl->dumpPublicKey( id, trusted, stream ); }
00735
00736 PublicKey KeyRing::exportPublicKey( const PublicKeyData & keyData )
00737 { return _pimpl->exportPublicKey( keyData ); }
00738
00739 PublicKey KeyRing::exportTrustedPublicKey( const PublicKeyData & keyData )
00740 { return _pimpl->exportTrustedPublicKey( keyData ); }
00741
00742 bool KeyRing::isKeyTrusted( const std::string & id )
00743 { return _pimpl->isKeyTrusted( id ); }
00744
00745 bool KeyRing::isKeyKnown( const std::string & id )
00746 { return _pimpl->isKeyKnown( id ); }
00747
00749 }