libzypp  11.13.5
KeyRing.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <fstream>
14 #include <sys/file.h>
15 #include <cstdio>
16 #include <unistd.h>
17 
18 #include <boost/format.hpp>
19 
20 #include "zypp/TmpPath.h"
21 #include "zypp/ZYppFactory.h"
22 #include "zypp/ZYpp.h"
23 
24 #include "zypp/base/LogTools.h"
25 #include "zypp/base/IOStream.h"
26 #include "zypp/base/String.h"
27 #include "zypp/base/Regex.h"
28 #include "zypp/base/Gettext.h"
29 #include "zypp/base/WatchFile.h"
30 #include "zypp/PathInfo.h"
31 #include "zypp/KeyRing.h"
32 #include "zypp/ExternalProgram.h"
33 #include "zypp/TmpPath.h"
34 
35 using std::endl;
36 
37 #undef ZYPP_BASE_LOGGER_LOGGROUP
38 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
39 
40 #define GPG_BINARY "/usr/bin/gpg2"
41 
43 namespace zypp
44 {
45 
46  IMPL_PTR_TYPE(KeyRing);
47 
48  namespace
49  {
50  KeyRing::DefaultAccept _keyRingDefaultAccept( KeyRing::ACCEPT_NOTHING );
51  }
52 
53  KeyRing::DefaultAccept KeyRing::defaultAccept()
54  { return _keyRingDefaultAccept; }
55 
56  void KeyRing::setDefaultAccept( DefaultAccept value_r )
57  {
58  MIL << "Set new KeyRing::DefaultAccept: " << value_r << endl;
59  _keyRingDefaultAccept = value_r;
60  }
61 
62  bool KeyRingReport::askUserToAcceptUnsignedFile( const std::string & file, const KeyContext & keycontext )
63  { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNSIGNED_FILE ); }
64 
66  KeyRingReport::askUserToAcceptKey( const PublicKey & key, const KeyContext & keycontext )
67  {
68  if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_KEY_TEMPORARILY ) )
69  return KEY_TRUST_TEMPORARILY;
70  if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_AND_IMPORT_KEY ) )
71  return KEY_TRUST_AND_IMPORT;
72  return KEY_DONT_TRUST;
73  }
74 
75  bool KeyRingReport::askUserToAcceptUnknownKey( const std::string & file, const std::string & id, const KeyContext & keycontext )
76  { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNKNOWNKEY ); }
77 
78  bool KeyRingReport::askUserToAcceptVerificationFailed( const std::string & file, const PublicKey & key, const KeyContext & keycontext )
79  { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_VERIFICATION_FAILED ); }
80 
81  namespace
82  {
90  struct CachedPublicKeyData // : private base::NonCopyable - but KeyRing uses RWCOW though also NonCopyable :(
91  {
92  const std::list<PublicKeyData> & operator()( const Pathname & keyring_r ) const
93  { return getData( keyring_r ); }
94 
95  private:
96  struct Cache
97  {
99  std::list<PublicKeyData> _data;
100 
101  // Empty copy ctor to allow insert into std::map as
102  // scoped_ptr is noncopyable.
103  Cache() {}
104  Cache( const Cache & rhs ) {}
105  };
106 
107  typedef std::map<Pathname,Cache> CacheMap;
108 
109  const std::list<PublicKeyData> & getData( const Pathname & keyring_r ) const
110  {
111  Cache & cache( _cacheMap[keyring_r] );
112  if ( ! cache._keyringP )
113  {
114  // init new cache entry
115  cache._keyringP.reset( new WatchFile( keyring_r/"pubring.gpg", WatchFile::NO_INIT ) );
116  }
117  return getData( keyring_r, cache );
118  }
119 
120  const std::list<PublicKeyData> & getData( const Pathname & keyring_r, Cache & cache_r ) const
121  {
122  if ( cache_r._keyringP->hasChanged() )
123  {
124  const char* argv[] =
125  {
126  GPG_BINARY,
127  "--list-public-keys",
128  "--homedir", keyring_r.c_str(),
129  "--no-default-keyring",
130  "--quiet",
131  "--with-colons",
132  "--fixed-list-mode",
133  "--with-fingerprint",
134  "--with-sig-list",
135  "--no-tty",
136  "--no-greeting",
137  "--batch",
138  "--status-fd", "1",
139  NULL
140  };
141 
142  PublicKeyScanner scanner;
143  ExternalProgram prog( argv ,ExternalProgram::Discard_Stderr, false, -1, true );
144  for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
145  {
146  scanner.scan( line );
147  }
148  prog.close();
149 
150  cache_r._data.swap( scanner._keys );
151  MIL << "Found keys: " << cache_r._data << endl;
152  }
153  return cache_r._data;
154  }
155 
156  mutable CacheMap _cacheMap;
157  };
159  }
160 
162  //
163  // CLASS NAME : KeyRing::Impl
164  //
167  {
168  Impl( const Pathname & baseTmpDir )
169  : _trusted_tmp_dir( baseTmpDir, "zypp-trusted-kr" )
170  , _general_tmp_dir( baseTmpDir, "zypp-general-kr" )
171  , _base_dir( baseTmpDir )
172  {
173  MIL << "Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
174  }
175 
176  void importKey( const PublicKey & key, bool trusted = false );
177  void multiKeyImport( const Pathname & keyfile_r, bool trusted_r = false );
178  void deleteKey( const std::string & id, bool trusted );
179 
180  std::string readSignatureKeyId( const Pathname & signature );
181 
182  bool isKeyTrusted( const std::string & id )
183  { return bool(publicKeyExists( id, trustedKeyRing() )); }
184  bool isKeyKnown( const std::string & id )
185  { return publicKeyExists( id, trustedKeyRing() ) || publicKeyExists( id, generalKeyRing() ); }
186 
187  std::list<PublicKey> trustedPublicKeys()
188  { return publicKeys( trustedKeyRing() ); }
189  std::list<PublicKey> publicKeys()
190  { return publicKeys( generalKeyRing() ); }
191 
192  const std::list<PublicKeyData> & trustedPublicKeyData()
193  { return publicKeyData( trustedKeyRing() ); }
194  const std::list<PublicKeyData> & publicKeyData()
195  { return publicKeyData( generalKeyRing() ); }
196 
197  void dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
198  { dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream ); }
199 
201  { return exportKey( keyData, generalKeyRing() ); }
203  { return exportKey( keyData, trustedKeyRing() ); }
204 
206  const Pathname & file,
207  const std::string & filedesc,
208  const Pathname & signature,
209  const KeyContext & keycontext = KeyContext());
210 
211  bool verifyFileSignature( const Pathname & file, const Pathname & signature )
212  { return verifyFile( file, signature, generalKeyRing() ); }
213  bool verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
214  { return verifyFile( file, signature, trustedKeyRing() ); }
215 
216  private:
217  bool verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring );
218  void importKey( const Pathname & keyfile, const Pathname & keyring );
219 
220  PublicKey exportKey( const std::string & id, const Pathname & keyring );
221  PublicKey exportKey( const PublicKeyData & keyData, const Pathname & keyring );
222 
223  void dumpPublicKey( const std::string & id, const Pathname & keyring, std::ostream & stream );
224  filesystem::TmpFile dumpPublicKeyToTmp( const std::string & id, const Pathname & keyring );
225 
226  void deleteKey( const std::string & id, const Pathname & keyring );
227 
228  std::list<PublicKey> publicKeys( const Pathname & keyring);
229  const std::list<PublicKeyData> & publicKeyData( const Pathname & keyring )
230  { return cachedPublicKeyData( keyring ); }
231 
233  PublicKeyData publicKeyExists( const std::string & id, const Pathname & keyring );
234 
235  const Pathname generalKeyRing() const
236  { return _general_tmp_dir.path(); }
237  const Pathname trustedKeyRing() const
238  { return _trusted_tmp_dir.path(); }
239 
240  // Used for trusted and untrusted keyrings
243  Pathname _base_dir;
244 
245  private:
251  CachedPublicKeyData cachedPublicKeyData;
252 
253  public:
255  static shared_ptr<Impl> nullimpl()
256  {
257  static shared_ptr<Impl> _nullimpl( new Impl( filesystem::TmpPath::defaultLocation() ) );
258  return _nullimpl;
259  }
260 
261  private:
262  friend Impl * rwcowClone<Impl>( const Impl * rhs );
264  Impl * clone() const
265  { return new Impl( *this ); }
266  };
268 
269 
270  void KeyRing::Impl::importKey( const PublicKey & key, bool trusted )
271  {
272  importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
273 
274  if ( trusted )
275  {
278 
279  rpmdbEmitSignal->trustedKeyAdded( key );
280  emitSignal->trustedKeyAdded( key );
281  }
282  }
283 
284  void KeyRing::Impl::multiKeyImport( const Pathname & keyfile_r, bool trusted_r )
285  {
286  importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
287  }
288 
289  void KeyRing::Impl::deleteKey( const std::string & id, bool trusted )
290  {
291  PublicKey key;
292 
293  if ( trusted )
294  {
295  key = exportKey( id, trustedKeyRing() );
296  }
297 
298  deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
299 
300  if ( trusted )
301  {
304 
305  rpmdbEmitSignal->trustedKeyRemoved( key );
306  emitSignal->trustedKeyRemoved( key );
307  }
308  }
309 
310  PublicKeyData KeyRing::Impl::publicKeyExists( const std::string & id, const Pathname & keyring )
311  {
312  MIL << "Searching key [" << id << "] in keyring " << keyring << endl;
313  const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
314  for_( it, keys.begin(), keys.end() )
315  {
316  if ( id == (*it).id() )
317  {
318  return *it;
319  }
320  }
321  return PublicKeyData();
322  }
323 
324  PublicKey KeyRing::Impl::exportKey( const PublicKeyData & keyData, const Pathname & keyring )
325  {
326  return PublicKey( dumpPublicKeyToTmp( keyData.id(), keyring ), keyData );
327  }
328 
329  PublicKey KeyRing::Impl::exportKey( const std::string & id, const Pathname & keyring )
330  {
331  PublicKeyData keyData( publicKeyExists( id, keyring ) );
332  if ( keyData )
333  return PublicKey( dumpPublicKeyToTmp( keyData.id(), keyring ), keyData );
334 
335  // Here: key not found
336  WAR << "No key " << id << " to export from " << keyring << endl;
337  return PublicKey();
338  }
339 
340 
341  void KeyRing::Impl::dumpPublicKey( const std::string & id, const Pathname & keyring, std::ostream & stream )
342  {
343  const char* argv[] =
344  {
345  GPG_BINARY,
346  "-a",
347  "--export",
348  "--homedir", keyring.asString().c_str(),
349  "--no-default-keyring",
350  "--quiet",
351  "--no-tty",
352  "--no-greeting",
353  "--no-permission-warning",
354  "--batch",
355  id.c_str(),
356  NULL
357  };
358  ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
359  for ( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
360  {
361  stream << line;
362  }
363  prog.close();
364  }
365 
366  filesystem::TmpFile KeyRing::Impl::dumpPublicKeyToTmp( const std::string & id, const Pathname & keyring )
367  {
368  filesystem::TmpFile tmpFile( _base_dir, "pubkey-"+id+"-" );
369  MIL << "Going to export key " << id << " from " << keyring << " to " << tmpFile.path() << endl;
370 
371  std::ofstream os( tmpFile.path().c_str() );
372  dumpPublicKey( id, keyring, os );
373  os.close();
374  return tmpFile;
375  }
376 
378  const Pathname & file,
379  const std::string & filedesc,
380  const Pathname & signature,
381  const KeyContext & context )
382  {
384  MIL << "Going to verify signature for " << filedesc << " ( " << file << " ) with " << signature << endl;
385 
386  // if signature does not exists, ask user if he wants to accept unsigned file.
387  if( signature.empty() || (!PathInfo( signature ).isExist()) )
388  {
389  bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
390  MIL << "User decision on unsigned file: " << res << endl;
391  return res;
392  }
393 
394  // get the id of the signature
395  std::string id = readSignatureKeyId( signature );
396 
397  // doeskey exists in trusted keyring
398  PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) );
399  if ( trustedKeyData )
400  {
401  MIL << "Key is trusted: " << trustedKeyData << endl;
402 
403  // lets look if there is an updated key in the
404  // general keyring
405  PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
406  if ( generalKeyData )
407  {
408  // bnc #393160: Comment #30: Compare at least the fingerprint
409  // in case an attacker created a key the the same id.
410  if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
411  && trustedKeyData.created() < generalKeyData.created() )
412  {
413  MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
414  importKey( exportKey( generalKeyData, generalKeyRing() ), true );
415  trustedKeyData = generalKeyData = PublicKeyData(); // invalidated by import.
416  }
417  }
418 
419  // it exists, is trusted, does it validates?
420  if ( verifyFile( file, signature, trustedKeyRing() ) )
421  return true;
422  else
423  {
424  if ( ! trustedKeyData ) // invalidated by previous import
425  trustedKeyData = publicKeyExists( id, trustedKeyRing() );
426  return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
427  }
428  }
429  else
430  {
431  PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
432  if ( generalKeyData )
433  {
434  PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
435  MIL << "Exported key " << id << " to " << key.path() << endl;
436  MIL << "Key " << id << " " << key.name() << " is not trusted" << endl;
437 
438  // ok the key is not trusted, ask the user to trust it or not
439  KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context );
440  if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY ||
442  {
443  MIL << "User wants to trust key " << id << " " << key.name() << endl;
444  //dumpFile( unKey.path() );
445 
446  Pathname whichKeyring;
448  {
449  MIL << "User wants to import key " << id << " " << key.name() << endl;
450  importKey( key, true );
451  whichKeyring = trustedKeyRing();
452  }
453  else
454  whichKeyring = generalKeyRing();
455 
456  // emit key added
457  if ( verifyFile( file, signature, whichKeyring ) )
458  {
459  MIL << "File signature is verified" << endl;
460  return true;
461  }
462  else
463  {
464  MIL << "File signature check fails" << endl;
465  if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
466  {
467  MIL << "User continues anyway." << endl;
468  return true;
469  }
470  else
471  {
472  MIL << "User does not want to continue" << endl;
473  return false;
474  }
475  }
476  }
477  else
478  {
479  MIL << "User does not want to trust key " << id << " " << key.name() << endl;
480  return false;
481  }
482  }
483  else
484  {
485  // unknown key...
486  MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
487  if ( report->askUserToAcceptUnknownKey( filedesc, id, context ) )
488  {
489  MIL << "User wants to accept unknown key " << id << endl;
490  return true;
491  }
492  else
493  {
494  MIL << "User does not want to accept unknown key " << id << endl;
495  return false;
496  }
497  }
498  }
499  return false;
500  }
501 
502  std::list<PublicKey> KeyRing::Impl::publicKeys( const Pathname & keyring )
503  {
504  const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
505  std::list<PublicKey> ret;
506 
507  for_( it, keys.begin(), keys.end() )
508  {
509  PublicKey key( exportKey( *it, keyring ) );
510  ret.push_back( key );
511  MIL << "Found key " << key << endl;
512  }
513  return ret;
514  }
515 
516  void KeyRing::Impl::importKey( const Pathname & keyfile, const Pathname & keyring )
517  {
518  if ( ! PathInfo( keyfile ).isExist() )
519  // TranslatorExplanation first %s is key name, second is keyring name
520  ZYPP_THROW(KeyRingException(boost::str(boost::format(
521  _("Tried to import not existent key %s into keyring %s"))
522  % keyfile.asString() % keyring.asString())));
523 
524  const char* argv[] =
525  {
526  GPG_BINARY,
527  "--import",
528  "--homedir", keyring.asString().c_str(),
529  "--no-default-keyring",
530  "--quiet",
531  "--no-tty",
532  "--no-greeting",
533  "--no-permission-warning",
534  "--status-fd", "1",
535  keyfile.asString().c_str(),
536  NULL
537  };
538 
539  ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
540  prog.close();
541  }
542 
543  void KeyRing::Impl::deleteKey( const std::string & id, const Pathname & keyring )
544  {
545  const char* argv[] =
546  {
547  GPG_BINARY,
548  "--delete-keys",
549  "--homedir", keyring.asString().c_str(),
550  "--no-default-keyring",
551  "--yes",
552  "--quiet",
553  "--no-tty",
554  "--batch",
555  "--status-fd", "1",
556  id.c_str(),
557  NULL
558  };
559 
560  ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
561 
562  int code = prog.close();
563  if ( code )
564  ZYPP_THROW(Exception(_("Failed to delete key.")));
565  else
566  MIL << "Deleted key " << id << " from keyring " << keyring << endl;
567  }
568 
569 
570  std::string KeyRing::Impl::readSignatureKeyId( const Pathname & signature )
571  {
572  if ( ! PathInfo( signature ).isFile() )
573  ZYPP_THROW(Exception(boost::str(boost::format(
574  _("Signature file %s not found"))% signature.asString())));
575 
576  MIL << "Determining key id if signature " << signature << endl;
577  // HACK create a tmp keyring with no keys
578  filesystem::TmpDir dir( _base_dir, "fake-keyring" );
579 
580  const char* argv[] =
581  {
582  GPG_BINARY,
583  "--homedir", dir.path().asString().c_str(),
584  "--no-default-keyring",
585  "--quiet",
586  "--no-tty",
587  "--no-greeting",
588  "--batch",
589  "--status-fd", "1",
590  signature.asString().c_str(),
591  NULL
592  };
593 
594  ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
595 
596  std::string line;
597  int count = 0;
598 
599  str::regex rxNoKey( "^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
600  std::string id;
601  for( line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
602  {
603  //MIL << "[" << line << "]" << endl;
604  str::smatch what;
605  if( str::regex_match( line, what, rxNoKey ) )
606  {
607  if ( what.size() >= 1 )
608  {
609  id = what[1];
610  break;
611  }
612  //dumpRegexpResults( what );
613  }
614  }
615 
616  if ( count == 0 )
617  {
618  MIL << "no output" << endl;
619  }
620 
621  MIL << "Determined key id [" << id << "] for signature " << signature << endl;
622  prog.close();
623  return id;
624  }
625 
626  bool KeyRing::Impl::verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring )
627  {
628  const char* argv[] =
629  {
630  GPG_BINARY,
631  "--verify",
632  "--homedir", keyring.asString().c_str(),
633  "--no-default-keyring",
634  "--quiet",
635  "--no-tty",
636  "--batch",
637  "--no-greeting",
638  "--status-fd", "1",
639  signature.asString().c_str(),
640  file.asString().c_str(),
641  NULL
642  };
643 
644  // no need to parse output for now
645  // [GNUPG:] SIG_ID yCc4u223XRJnLnVAIllvYbUd8mQ 2006-03-29 1143618744
646  // [GNUPG:] GOODSIG A84EDAE89C800ACA SuSE Package Signing Key <build@suse.de>
647  // gpg: Good signature from "SuSE Package Signing Key <build@suse.de>"
648  // [GNUPG:] VALIDSIG 79C179B2E1C820C1890F9994A84EDAE89C800ACA 2006-03-29 1143618744 0 3 0 17 2 00 79C179B2E1C820C1890F9994A84EDAE89C800ACA
649  // [GNUPG:] TRUST_UNDEFINED
650 
651  // [GNUPG:] ERRSIG A84EDAE89C800ACA 17 2 00 1143618744 9
652  // [GNUPG:] NO_PUBKEY A84EDAE89C800ACA
653 
654  ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
655 
656  return ( prog.close() == 0 ) ? true : false;
657  }
658 
660 
662  //
663  // CLASS NAME : KeyRing
664  //
666 
667  KeyRing::KeyRing( const Pathname & baseTmpDir )
668  : _pimpl( new Impl( baseTmpDir ) )
669  {}
670 
672  {}
673 
674 
675  void KeyRing::importKey( const PublicKey & key, bool trusted )
676  { _pimpl->importKey( key, trusted ); }
677 
678  void KeyRing::multiKeyImport( const Pathname & keyfile_r, bool trusted_r )
679  { _pimpl->multiKeyImport( keyfile_r, trusted_r ); }
680 
681  std::string KeyRing::readSignatureKeyId( const Pathname & signature )
682  { return _pimpl->readSignatureKeyId( signature ); }
683 
684  void KeyRing::deleteKey( const std::string & id, bool trusted )
685  { _pimpl->deleteKey( id, trusted ); }
686 
687  std::list<PublicKey> KeyRing::publicKeys()
688  { return _pimpl->publicKeys(); }
689 
690  std:: list<PublicKey> KeyRing::trustedPublicKeys()
691  { return _pimpl->trustedPublicKeys(); }
692 
693  std::list<PublicKeyData> KeyRing::publicKeyData()
694  { return _pimpl->publicKeyData(); }
695 
696  std::list<PublicKeyData> KeyRing::trustedPublicKeyData()
697  { return _pimpl->trustedPublicKeyData(); }
698 
699  std::list<std::string> KeyRing::publicKeyIds() // deprecated: use publicKeyData
700  {
701  const std::list<PublicKeyData> & keys( publicKeyData() );
702  std::list<std::string> ret;
703  for_( it, keys.begin(), keys.end() )
704  {
705  ret.push_back( (*it).id() );
706  }
707  return ret;
708  }
709 
710  std::list<std::string> KeyRing::trustedPublicKeyIds() // deprecated: use trustedPublicKeyData
711  {
712  const std::list<PublicKeyData> & keys( trustedPublicKeyData() );
713  std::list<std::string> ret;
714  for_( it, keys.begin(), keys.end() )
715  {
716  ret.push_back( (*it).id() );
717  }
718  return ret;
719  }
720 
722  const Pathname & file,
723  const std::string filedesc,
724  const Pathname & signature,
725  const KeyContext & keycontext )
726  { return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, keycontext ); }
727 
728  bool KeyRing::verifyFileSignature( const Pathname & file, const Pathname & signature )
729  { return _pimpl->verifyFileSignature( file, signature ); }
730 
731  bool KeyRing::verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
732  { return _pimpl->verifyFileTrustedSignature( file, signature ); }
733 
734  void KeyRing::dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
735  { _pimpl->dumpPublicKey( id, trusted, stream ); }
736 
738  { return _pimpl->exportPublicKey( keyData ); }
739 
741  { return _pimpl->exportTrustedPublicKey( keyData ); }
742 
743  bool KeyRing::isKeyTrusted( const std::string & id )
744  { return _pimpl->isKeyTrusted( id ); }
745 
746  bool KeyRing::isKeyKnown( const std::string & id )
747  { return _pimpl->isKeyKnown( id ); }
748 
750 } // namespace zypp