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