- Fix reading of Traget::targetDistribution.
[platform/upstream/libzypp.git] / zypp / KeyRing.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/KeyRing.cc
10  *
11 */
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/Logger.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/PathInfo.h"
30 #include "zypp/KeyRing.h"
31 #include "zypp/ExternalProgram.h"
32 #include "zypp/TmpPath.h"
33
34 using namespace std;
35 using namespace zypp::filesystem;
36
37 #undef  ZYPP_BASE_LOGGER_LOGGROUP
38 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
39
40 #define GPG_BINARY "/usr/bin/gpg2"
41
42 ///////////////////////////////////////////////////////////////////
43 namespace zypp
44 { /////////////////////////////////////////////////////////////////
45
46   IMPL_PTR_TYPE(KeyRing);
47
48   static bool printLine( const string &line )
49   {
50     MIL <<  line << endl;
51     return true;
52   }
53
54   ///////////////////////////////////////////////////////////////////
55
56   namespace
57   {
58     KeyRingReport::DefaultAccept _keyRingDefaultAccept( KeyRingReport::ACCEPT_NOTHING );
59   }
60
61   KeyRingReport::DefaultAccept KeyRingReport::defaultAccept()
62   { return _keyRingDefaultAccept; }
63
64   void KeyRingReport::setDefaultAccept( DefaultAccept value_r )
65   {
66     MIL << "Set new default accept: " << value_r << endl;
67     _keyRingDefaultAccept = value_r;
68   }
69
70   ///////////////////////////////////////////////////////////////////
71
72   bool KeyRingReport::askUserToAcceptUnsignedFile( const string &file )
73   { return _keyRingDefaultAccept.testFlag( ACCEPT_UNSIGNED_FILE ); }
74
75   bool KeyRingReport::askUserToAcceptUnknownKey( const string &file, const string &id )
76   { return _keyRingDefaultAccept.testFlag( ACCEPT_UNKNOWNKEY ); }
77
78   bool KeyRingReport::askUserToTrustKey( const PublicKey &key )
79   { return _keyRingDefaultAccept.testFlag( TRUST_KEY ); }
80
81   bool KeyRingReport::askUserToImportKey( const PublicKey &key)
82   { return _keyRingDefaultAccept.testFlag( IMPORT_KEY ); }
83
84   bool KeyRingReport::askUserToAcceptVerificationFailed( const string &file, const PublicKey &key )
85   { return _keyRingDefaultAccept.testFlag( ACCEPT_VERIFICATION_FAILED ); }
86
87   ///////////////////////////////////////////////////////////////////
88   //
89   //    CLASS NAME : KeyRing::Impl
90   //
91   /** KeyRing implementation. */
92   struct KeyRing::Impl
93   {
94     Impl(const Pathname &baseTmpDir)
95     : _trusted_tmp_dir(baseTmpDir, "zypp-trusted-kr")
96    ,  _general_tmp_dir(baseTmpDir, "zypp-general-kr")
97    , _base_dir( baseTmpDir )
98
99     {
100     }
101
102     /*
103     Impl( const Pathname &general_kr, const Pathname &trusted_kr )
104     {
105       filesystem::assert_dir(general_kr);
106       filesystem::assert_dir(trusted_kr);
107
108       generalKeyRing() = general_kr;
109       trustedKeyRing() = trusted_kr;
110     }
111     */
112
113     void importKey( const PublicKey &key, bool trusted = false);
114     void deleteKey( const string &id, bool trusted );
115
116     string readSignatureKeyId( const Pathname &signature );
117
118     bool isKeyTrusted( const string &id);
119     bool isKeyKnown( const string &id );
120
121     list<PublicKey> trustedPublicKeys();
122     list<PublicKey> publicKeys();
123
124     list<string> trustedPublicKeyIds();
125     list<string> publicKeyIds();
126
127     void dumpPublicKey( const string &id, bool trusted, ostream &stream );
128
129     bool verifyFileSignatureWorkflow( const Pathname &file, const string filedesc, const Pathname &signature);
130
131     bool verifyFileSignature( const Pathname &file, const Pathname &signature);
132     bool verifyFileTrustedSignature( const Pathname &file, const Pathname &signature);
133   private:
134     //mutable map<Locale, string> translations;
135     bool verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring);
136     void importKey( const Pathname &keyfile, const Pathname &keyring);
137     PublicKey exportKey( string id, const Pathname &keyring);
138     void dumpPublicKey( const string &id, const Pathname &keyring, ostream &stream );
139     void deleteKey( const string &id, const Pathname &keyring );
140
141     list<PublicKey> publicKeys(const Pathname &keyring);
142     list<string> publicKeyIds(const Pathname &keyring);
143
144     bool publicKeyExists( string id, const Pathname &keyring);
145
146     const Pathname generalKeyRing() const;
147     const Pathname trustedKeyRing() const;
148
149     // Used for trusted and untrusted keyrings
150     TmpDir _trusted_tmp_dir;
151     TmpDir _general_tmp_dir;
152     Pathname _base_dir;
153   public:
154     /** Offer default Impl. */
155     static shared_ptr<Impl> nullimpl()
156     {
157       static shared_ptr<Impl> _nullimpl( new Impl( TmpPath::defaultLocation() ) );
158       return _nullimpl;
159     }
160
161   private:
162     friend Impl * rwcowClone<Impl>( const Impl * rhs );
163     /** clone for RWCOW_pointer */
164     Impl * clone() const
165     { return new Impl( *this ); }
166   };
167
168
169   const Pathname KeyRing::Impl::generalKeyRing() const
170   {
171     return _general_tmp_dir.path();
172   }
173
174   const Pathname KeyRing::Impl::trustedKeyRing() const
175   {
176     return _trusted_tmp_dir.path();
177   }
178
179   void KeyRing::Impl::importKey( const PublicKey &key, bool trusted)
180   {
181     callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
182     callback::SendReport<KeyRingSignals> emitSignal;
183
184     importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
185
186     if ( trusted )
187     {
188       rpmdbEmitSignal->trustedKeyAdded( key );
189       emitSignal->trustedKeyAdded( key );
190     }
191   }
192
193   void KeyRing::Impl::deleteKey( const string &id, bool trusted)
194   {
195     PublicKey key;
196
197     if (trusted)
198     {
199         key = exportKey(id, trustedKeyRing());
200     }
201
202     deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
203
204     if ( trusted )
205     {
206       callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
207       callback::SendReport<KeyRingSignals> emitSignal;
208
209       rpmdbEmitSignal->trustedKeyRemoved( key );
210       emitSignal->trustedKeyRemoved( key );
211     }
212   }
213
214   list<PublicKey> KeyRing::Impl::publicKeys()
215   {
216     return publicKeys( generalKeyRing() );
217   }
218
219   list<PublicKey> KeyRing::Impl::trustedPublicKeys()
220   {
221     return publicKeys( trustedKeyRing() );
222   }
223
224   list<string> KeyRing::Impl::publicKeyIds()
225   {
226     return publicKeyIds( generalKeyRing() );
227   }
228
229   list<string> KeyRing::Impl::trustedPublicKeyIds()
230   {
231     return publicKeyIds( trustedKeyRing() );
232   }
233
234   bool KeyRing::Impl::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
235   {
236     return verifyFile( file, signature, trustedKeyRing() );
237   }
238
239   bool KeyRing::Impl::verifyFileSignature( const Pathname &file, const Pathname &signature)
240   {
241     return verifyFile( file, signature, generalKeyRing() );
242   }
243
244   bool KeyRing::Impl::isKeyTrusted( const string &id)
245   {
246     return publicKeyExists( id, trustedKeyRing() );
247   }
248
249   bool KeyRing::Impl::isKeyKnown( const string &id )
250   {
251     MIL << endl;
252     if ( publicKeyExists( id, trustedKeyRing() ) )
253       return true;
254     else
255       return publicKeyExists( id, generalKeyRing() );
256   }
257
258   bool KeyRing::Impl::publicKeyExists( string id, const Pathname &keyring)
259   {
260     MIL << "Searching key [" << id << "] in keyring " << keyring << endl;
261     list<PublicKey> keys = publicKeys(keyring);
262     for (list<PublicKey>::const_iterator it = keys.begin(); it != keys.end(); it++)
263     {
264       if ( id == (*it).id() )
265
266         return true;
267     }
268     return false;
269   }
270
271   PublicKey KeyRing::Impl::exportKey( string id, const Pathname &keyring)
272   {
273     TmpFile tmp_file( _base_dir, "pubkey-"+id+"-" );
274     Pathname keyfile = tmp_file.path();
275     MIL << "Going to export key " << id << " from " << keyring << " to " << keyfile << endl;
276
277     try {
278       ofstream os(keyfile.asString().c_str());
279       dumpPublicKey( id, keyring, os );
280       os.close();
281       PublicKey key(keyfile);
282       return key;
283     }
284     catch (BadKeyException &e)
285     {
286       ERR << "Cannot create public key " << id << " from " << keyring << " keyring  to file " << e.keyFile() << endl;
287       // TranslatorExplanation first %s is key name, second is keyring name
288       // and third is keyfile name
289       ZYPP_THROW(Exception(boost::str(boost::format(
290           _("Cannot create public key %s from %s keyring to file %s"))
291           % id % keyring.asString() % e.keyFile().asString())));
292     }
293     catch (exception &e)
294     {
295       ERR << "Cannot export key " << id << " from " << keyring << " keyring  to file " << keyfile << endl;
296     }
297     return PublicKey();
298   }
299
300   void KeyRing::Impl::dumpPublicKey( const string &id, bool trusted, ostream &stream )
301   {
302      dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream );
303   }
304
305   void KeyRing::Impl::dumpPublicKey( const string &id, const Pathname &keyring, ostream &stream )
306   {
307     const char* argv[] =
308     {
309       GPG_BINARY,
310       "--no-default-keyring",
311       "--quiet",
312       "--no-tty",
313       "--no-greeting",
314       "--no-permission-warning",
315       "--batch",
316       "--homedir",
317       keyring.asString().c_str(),
318       "-a",
319       "--export",
320       id.c_str(),
321       NULL
322     };
323     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
324     string line;
325     int count;
326     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
327     {
328       stream << line;
329     }
330     prog.close();
331   }
332
333
334   bool KeyRing::Impl::verifyFileSignatureWorkflow( const Pathname &file, const string filedesc, const Pathname &signature)
335   {
336     callback::SendReport<KeyRingReport> report;
337     //callback::SendReport<KeyRingSignals> emitSignal;
338     MIL << "Going to verify signature for " << file << " with " << signature << endl;
339
340     // if signature does not exists, ask user if he wants to accept unsigned file.
341     if( signature.empty() || (!PathInfo(signature).isExist()) )
342     {
343       bool res = report->askUserToAcceptUnsignedFile( filedesc );
344       MIL << "User decision on unsigned file: " << res << endl;
345       return res;
346     }
347
348     // get the id of the signature
349     string id = readSignatureKeyId(signature);
350
351     // doeskey exists in trusted keyring
352     if ( publicKeyExists( id, trustedKeyRing() ) )
353     {
354       PublicKey key = exportKey( id, trustedKeyRing() );
355
356       // lets look if there is an updated key in the
357       // general keyring
358       if ( publicKeyExists( id, generalKeyRing() ) )
359       {
360         // bnc #393160: Comment #30: Compare at least the fingerprint
361         // in case an attacker created a key the the same id.
362         PublicKey untkey = exportKey( id, generalKeyRing() );
363         if ( untkey.fingerprint() == key.fingerprint()
364              && untkey.created() > key.created() )
365         {
366           MIL << "Key " << key << " was updated. Saving new version into trusted keyring." << endl;
367           importKey( untkey, true );
368           key = untkey;
369         }
370       }
371
372       MIL << "Key " << id << " " << key.name() << " is trusted" << endl;
373       // it exists, is trusted, does it validates?
374       if ( verifyFile( file, signature, trustedKeyRing() ) )
375         return true;
376       else
377         return report->askUserToAcceptVerificationFailed( filedesc, key );
378     }
379     else
380     {
381       if ( publicKeyExists( id, generalKeyRing() ) )
382       {
383         PublicKey key =  exportKey( id, generalKeyRing());
384         MIL << "Exported key " << id << " to " << key.path() << endl;
385         MIL << "Key " << id << " " << key.name() << " is not trusted" << endl;
386         // ok the key is not trusted, ask the user to trust it or not
387         #warning We need the key details passed to the callback
388         if ( report->askUserToTrustKey( key ) )
389         {
390           MIL << "User wants to trust key " << id << " " << key.name() << endl;
391           //dumpFile(unKey.path());
392
393           Pathname which_keyring;
394           if ( report->askUserToImportKey( key ) )
395           {
396             MIL << "User wants to import key " << id << " " << key.name() << endl;
397             importKey( key, true );
398             which_keyring = trustedKeyRing();
399           }
400           else
401           {
402             which_keyring = generalKeyRing();
403           }
404
405           // emit key added
406           if ( verifyFile( file, signature, which_keyring ) )
407           {
408             MIL << "File signature is verified" << endl;
409             return true;
410           }
411           else
412           {
413             MIL << "File signature check fails" << endl;
414             if ( report->askUserToAcceptVerificationFailed( filedesc, key ) )
415             {
416               MIL << "User continues anyway." << endl;
417               return true;
418             }
419             else
420             {
421               MIL << "User does not want to continue" << endl;
422               return false;
423             }
424           }
425         }
426         else
427         {
428           MIL << "User does not want to trust key " << id << " " << key.name() << endl;
429           return false;
430         }
431       }
432       else
433       {
434         // unknown key...
435         MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
436         if ( report->askUserToAcceptUnknownKey( filedesc, id ) )
437         {
438           MIL << "User wants to accept unknown key " << id << endl;
439           return true;
440         }
441         else
442         {
443           MIL << "User does not want to accept unknown key " << id << endl;
444           return false;
445         }
446       }
447     }
448     return false;
449   }
450
451   list<string> KeyRing::Impl::publicKeyIds(const Pathname &keyring)
452   {
453     static str::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
454     static str::regex rxColonsFpr("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
455
456     list<string> ids;
457
458     const char* argv[] =
459     {
460       GPG_BINARY,
461       "--no-default-keyring",
462       "--quiet",
463       "--list-public-keys",
464       "--with-colons",
465       "--with-fingerprint",
466       "--no-tty",
467       "--no-greeting",
468       "--batch",
469       "--status-fd",
470       "1",
471       "--homedir",
472       keyring.asString().c_str(),
473       NULL
474     };
475
476     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
477     string line;
478     int count = 0;
479
480     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
481     {
482       //MIL << line << endl;
483       str::smatch what;
484       if(str::regex_match(line, what, rxColons))
485       {
486         string id;
487         string fingerprint;
488         if ( what[1] == "pub" )
489         {
490           id = what[5];
491
492           string line2;
493           for(line2 = prog.receiveLine(); !line2.empty(); line2 = prog.receiveLine(), count++ )
494           {
495             str::smatch what2;
496             if (str::regex_match(line2, what2, rxColonsFpr))
497             {
498               if ( (what2[1] == "fpr") && (what2[1] != "pub") && (what2[1] !="sub"))
499               {
500                 fingerprint = what2[10];
501                 break;
502               }
503             }
504           }
505
506           ids.push_back(id);
507           MIL << "Found key " << "[" << id << "]" << endl;
508         }
509         //dumpRegexpResults(what);
510       }
511     }
512     prog.close();
513     return ids;
514   }
515
516   list<PublicKey> KeyRing::Impl::publicKeys(const Pathname &keyring)
517   {
518
519     list<PublicKey> keys;
520
521     list<string> ids = publicKeyIds(keyring);
522
523     for ( list<string>::const_iterator it = ids.begin(); it != ids.end(); ++it )
524     {
525       PublicKey key(exportKey( *it, keyring ));
526       keys.push_back(key);
527       MIL << "Found key " << "[" << key.id() << "]" << " [" << key.name() << "]" << " [" << key.fingerprint() << "]" << endl;
528     }
529     return keys;
530   }
531
532   void KeyRing::Impl::importKey( const Pathname &keyfile, const Pathname &keyring)
533   {
534     if ( ! PathInfo(keyfile).isExist() )
535       // TranslatorExplanation first %s is key name, second is keyring name
536       ZYPP_THROW(KeyRingException(boost::str(boost::format(
537           _("Tried to import not existant key %s into keyring %s"))
538           % keyfile.asString() % keyring.asString())));
539
540     const char* argv[] =
541     {
542       GPG_BINARY,
543       "--no-default-keyring",
544       "--quiet",
545       "--no-tty",
546       "--no-greeting",
547       "--no-permission-warning",
548       "--status-fd",
549       "1",
550       "--homedir",
551       keyring.asString().c_str(),
552       "--import",
553       keyfile.asString().c_str(),
554       NULL
555     };
556
557     int code;
558     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
559     code = prog.close();
560
561     //if ( code != 0 )
562     //  ZYPP_THROW(Exception("failed to import key"));
563   }
564
565   void KeyRing::Impl::deleteKey( const string &id, const Pathname &keyring )
566   {
567     const char* argv[] =
568     {
569       GPG_BINARY,
570       "--no-default-keyring",
571       "--yes",
572       "--quiet",
573       "--no-tty",
574       "--batch",
575       "--status-fd",
576       "1",
577       "--homedir",
578       keyring.asString().c_str(),
579       "--delete-keys",
580       id.c_str(),
581       NULL
582     };
583
584     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
585
586     int code = prog.close();
587     if ( code )
588       ZYPP_THROW(Exception(_("Failed to delete key.")));
589     else
590       MIL << "Deleted key " << id << " from keyring " << keyring << endl;
591   }
592
593
594   string KeyRing::Impl::readSignatureKeyId(const Pathname &signature )
595   {
596     if ( ! PathInfo(signature).isFile() )
597       ZYPP_THROW(Exception(boost::str(boost::format(
598           _("Signature file %s not found"))% signature.asString())));
599
600     MIL << "Determining key id if signature " << signature << endl;
601     // HACK create a tmp keyring with no keys
602     TmpDir dir(_base_dir, "fake-keyring");
603
604     const char* argv[] =
605     {
606       GPG_BINARY,
607       "--no-default-keyring",
608       "--quiet",
609       "--no-tty",
610       "--no-greeting",
611       "--batch",
612       "--status-fd",
613       "1",
614       "--homedir",
615       dir.path().asString().c_str(),
616       signature.asString().c_str(),
617       NULL
618     };
619
620     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
621
622     string line;
623     int count = 0;
624
625     str::regex rxNoKey("^\\[GNUPG:\\] NO_PUBKEY (.+)\n$");
626     string id;
627     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
628     {
629       //MIL << "[" << line << "]" << endl;
630       str::smatch what;
631       if(str::regex_match(line, what, rxNoKey))
632       {
633         if ( what.size() >= 1 )
634           id = what[1];
635         //dumpRegexpResults(what);
636       }
637       else
638       {
639         MIL << "'" << line << "'" << endl;
640       }
641     }
642
643     if ( count == 0 )
644     {
645       MIL << "no output" << endl;
646     }
647
648     MIL << "Determined key id [" << id << "] for signature " << signature << endl;
649     prog.close();
650     return id;
651   }
652
653   bool KeyRing::Impl::verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring)
654   {
655     const char* argv[] =
656     {
657       GPG_BINARY,
658       "--no-default-keyring",
659       "--quiet",
660       "--no-tty",
661       "--batch",
662       "--no-greeting",
663       "--status-fd",
664       "1",
665       "--homedir",
666       keyring.asString().c_str(),
667       "--verify",
668       signature.asString().c_str(),
669       file.asString().c_str(),
670       NULL
671     };
672
673     // no need to parse output for now
674     //     [GNUPG:] SIG_ID yCc4u223XRJnLnVAIllvYbUd8mQ 2006-03-29 1143618744
675     //     [GNUPG:] GOODSIG A84EDAE89C800ACA SuSE Package Signing Key <build@suse.de>
676     //     gpg: Good signature from "SuSE Package Signing Key <build@suse.de>"
677     //     [GNUPG:] VALIDSIG 79C179B2E1C820C1890F9994A84EDAE89C800ACA 2006-03-29 1143618744 0 3 0 17 2 00 79C179B2E1C820C1890F9994A84EDAE89C800ACA
678     //     [GNUPG:] TRUST_UNDEFINED
679
680     //     [GNUPG:] ERRSIG A84EDAE89C800ACA 17 2 00 1143618744 9
681     //     [GNUPG:] NO_PUBKEY A84EDAE89C800ACA
682
683     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
684
685     return (prog.close() == 0) ? true : false;
686   }
687
688   ///////////////////////////////////////////////////////////////////
689
690   ///////////////////////////////////////////////////////////////////
691   //
692   //    CLASS NAME : KeyRing
693   //
694   ///////////////////////////////////////////////////////////////////
695
696   ///////////////////////////////////////////////////////////////////
697   //
698   //    METHOD NAME : KeyRing::KeyRing
699   //    METHOD TYPE : Ctor
700   //
701   KeyRing::KeyRing(const Pathname &baseTmpDir)
702   : _pimpl( new Impl(baseTmpDir) )
703   {}
704
705   ///////////////////////////////////////////////////////////////////
706   //
707   //    METHOD NAME : KeyRing::KeyRing
708   //    METHOD TYPE : Ctor
709   //
710   //KeyRing::KeyRing( const Pathname &general_kr, const Pathname &trusted_kr )
711   //: _pimpl( new Impl(general_kr, trusted_kr) )
712   //{}
713
714   ///////////////////////////////////////////////////////////////////
715   //
716   //    METHOD NAME : KeyRing::~KeyRing
717   //    METHOD TYPE : Dtor
718   //
719   KeyRing::~KeyRing()
720   {}
721
722   ///////////////////////////////////////////////////////////////////
723   //
724   // Forward to implementation:
725   //
726   ///////////////////////////////////////////////////////////////////
727
728
729   void KeyRing::importKey( const PublicKey &key, bool trusted )
730   {
731     _pimpl->importKey( key, trusted );
732   }
733
734   string KeyRing::readSignatureKeyId( const Pathname &signature )
735   {
736     return _pimpl->readSignatureKeyId(signature);
737   }
738
739   void KeyRing::deleteKey( const string &id, bool trusted )
740   {
741     _pimpl->deleteKey(id, trusted);
742   }
743
744   list<PublicKey> KeyRing::publicKeys()
745   {
746     return _pimpl->publicKeys();
747   }
748
749   list<PublicKey> KeyRing::trustedPublicKeys()
750   {
751     return _pimpl->trustedPublicKeys();
752   }
753
754   list<string> KeyRing::publicKeyIds()
755   {
756     return _pimpl->publicKeyIds();
757   }
758
759   list<string> KeyRing::trustedPublicKeyIds()
760   {
761     return _pimpl->trustedPublicKeyIds();
762   }
763
764   bool KeyRing::verifyFileSignatureWorkflow( const Pathname &file, const string filedesc, const Pathname &signature)
765   {
766     return _pimpl->verifyFileSignatureWorkflow(file, filedesc, signature);
767   }
768
769   bool KeyRing::verifyFileSignature( const Pathname &file, const Pathname &signature)
770   {
771     return _pimpl->verifyFileSignature(file, signature);
772   }
773
774   bool KeyRing::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
775   {
776     return _pimpl->verifyFileTrustedSignature(file, signature);
777   }
778
779   void KeyRing::dumpPublicKey( const string &id, bool trusted, ostream &stream )
780   {
781     _pimpl->dumpPublicKey( id, trusted, stream);
782   }
783
784   bool KeyRing::isKeyTrusted( const string &id )
785   {
786     return _pimpl->isKeyTrusted(id);
787   }
788
789   bool KeyRing::isKeyKnown( const string &id )
790   {
791     return _pimpl->isKeyKnown(id);
792   }
793
794   /////////////////////////////////////////////////////////////////
795 } // namespace zypp
796 ///////////////////////////////////////////////////////////////////