libzypp  17.38.9
KeyManager.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 #include <iostream>
10 #include "KeyManager.h"
11 #include "KeyRingException.h"
12 
13 #include <zypp-core/fs/PathInfo.h>
14 #include <zypp-core/base/Logger.h>
15 #include <zypp-core/fs/TmpPath.h>
16 #include <zypp-core/base/String.h>
17 #include <zypp-core/AutoDispose.h>
18 
19 #include <boost/thread/once.hpp>
20 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
21 #include <gpgme.h>
22 
23 #include <stdio.h>
24 using std::endl;
25 
26 #undef ZYPP_BASE_LOGGER_LOGGROUP
27 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::gpg"
28 
30 namespace zypp
31 {
33  namespace
34  {
35  // @TODO [threading]
36  // make sure to call the init code of gpgme only once
37  // this might need to be moved to a different location when
38  // threads are introduced into libzypp
39  boost::once_flag gpgme_init_once = BOOST_ONCE_INIT;
40 
41  void initGpgme ()
42  {
43  const char *version = gpgme_check_version(NULL);
44  if ( version )
45  {
46  MIL << "Initialized libgpgme version: " << version << endl;
47  }
48  else
49  {
50  MIL << "Initialized libgpgme with unknown version" << endl;
51  }
52  }
53 
54  //using boost::interprocess pointer because it allows a custom deleter
55  using GpgmeDataPtr = boost::interprocess::scoped_ptr<gpgme_data, boost::function<void (gpgme_data_t)>>;
56  using GpgmeKeyPtr = boost::interprocess::scoped_ptr<_gpgme_key, boost::function<void (gpgme_key_t)>>;
57  using FILEPtr = boost::interprocess::scoped_ptr<FILE, boost::function<int (FILE *)>>;
58 
59  struct GpgmeErr
60  {
61  GpgmeErr( gpgme_error_t err_r = GPG_ERR_NO_ERROR )
62  : _err( err_r )
63  {}
64  operator gpgme_error_t() const { return _err; }
65  private:
66  gpgme_error_t _err;
67  };
68 
69  std::ostream & operator<<( std::ostream & str, const GpgmeErr & obj )
70  { return str << "<" << gpgme_strsource(obj) << "> " << gpgme_strerror(obj); }
71 
73  [[maybe_unused]] std::ostream & operator<<( std::ostream & str, const _gpgme_op_import_result & obj )
74  {
75  str << "gpgme_op_import_result {" << endl;
76  str << " " << obj.considered << " The total number of considered keys." << endl;
77  str << " " << obj.no_user_id << " The number of keys without user ID." << endl;
78  str << " " << obj.imported << " The total number of imported keys." << endl;
79  str << " " << obj.imported_rsa << " imported RSA keys." << endl;
80  str << " " << obj.unchanged << " unchanged keys." << endl;
81  str << " " << obj.new_user_ids << " new user IDs." << endl;
82  str << " " << obj.new_sub_keys << " new sub keys." << endl;
83  str << " " << obj.new_signatures << " new signatures." << endl;
84  str << " " << obj.new_revocations << " new revocations." << endl;
85  str << " " << obj.secret_read << " secret keys read." << endl;
86  str << " " << obj.secret_imported << " imported secret keys." << endl;
87  str << " " << obj.secret_unchanged << " unchanged secret keys." << endl;
88  str << " " << obj.not_imported << " keys not imported." << endl;
89  for ( gpgme_import_status_t p = obj.imports; p; p = p->next )
90  {
91  str << " - " << p->fpr << ": " << p->result << endl;
92  }
93  // In V.1.11: str << " " << obj.skipped_v3_keys << " skipped v3 keys." << endl;
94  return str << "}";
95  }
96 
97  [[maybe_unused]] std::ostream & operator<<( std::ostream & str, const gpgme_sigsum_t & obj )
98  {
99  str << ((int)obj&(int)0xffff) << ":";
100 #define OSC(V) if ( V & (unsigned)obj ) str << " " << #V;
101  OSC(GPGME_SIGSUM_VALID );
102  OSC(GPGME_SIGSUM_GREEN );
103  OSC(GPGME_SIGSUM_RED );
104  OSC(GPGME_SIGSUM_KEY_REVOKED );
105  OSC(GPGME_SIGSUM_KEY_EXPIRED );
106  OSC(GPGME_SIGSUM_SIG_EXPIRED );
107  OSC(GPGME_SIGSUM_KEY_MISSING );
108  OSC(GPGME_SIGSUM_CRL_MISSING );
109  OSC(GPGME_SIGSUM_CRL_TOO_OLD );
110  OSC(GPGME_SIGSUM_BAD_POLICY );
111  OSC(GPGME_SIGSUM_SYS_ERROR );
112  OSC(GPGME_SIGSUM_TOFU_CONFLICT);
113 #undef OSC
114  return str;
115  }
116 
117  [[maybe_unused]] std::ostream & operator<<( std::ostream & str, const gpgme_signature_t & obj )
118  {
119  str << "gpgme_signature_t " << (void *)obj << " {" << endl;
120  str << " next: " << (void *)obj->next << endl;
121  str << " summary: " << obj->summary << endl;
122  str << " fpr: " << obj->fpr << endl;
123  str << " status: " << obj->status << " " << GpgmeErr(obj->status) << endl;
124  str << " timestamp: " << obj->timestamp << endl;
125  str << " exp_timestamp: " << obj->exp_timestamp << endl;
126  str << " wrong_key_usage: " << obj->wrong_key_usage << endl;
127  str << " pka_trust: " << obj->pka_trust << endl;
128  str << " chain_model: " << obj->chain_model << endl;
129  str << " is_de_vs: " << obj->is_de_vs << endl;
130  str << " validity: " << obj->validity << endl;
131  str << " validity_reason: " << obj->validity_reason << " " << GpgmeErr(obj->validity_reason) << endl;
132  str << " pubkey_algo: " << obj->pubkey_algo << endl;
133  str << " hash_algo: " << obj->hash_algo << endl;
134  str << " pka_address: " << (obj->pka_address ? obj->pka_address : "") << endl;
135  return str;
136  }
137 
138  } // namespace
140 
142  {
143  GpgmeException( const std::string & in_r, const GpgmeErr & err_r )
144  : KeyRingException( str::Format( "libgpgme error in '%1%': %2%" ) % in_r % err_r )
145  {}
146  };
147 
149  {
150  public:
152  { boost::call_once( gpgme_init_once, initGpgme ); }
153 
154  Impl(const Impl &) = delete;
155  Impl(Impl &&) = delete;
156  Impl &operator=(const Impl &) = delete;
157  Impl &operator=(Impl &&) = delete;
158 
159  ~Impl() {
160  if (_ctx)
161  gpgme_release(_ctx);
162  }
163 
165  std::list<std::string> readSignaturesFprs( const Pathname & signature_r )
166  { return readSignaturesFprsOptVerify( signature_r ); }
167 
169  std::list<std::string> readSignaturesFprs( const ByteArray & signature_r )
170  { return readSignaturesFprsOptVerify( signature_r ); }
171 
173  bool verifySignaturesFprs( const Pathname & file_r, const Pathname & signature_r )
174  {
175  bool verify = false;
176  readSignaturesFprsOptVerify( signature_r, file_r, &verify );
177  return verify;
178  }
179 
180  template< typename Callback >
181  bool importKey(GpgmeDataPtr &data, Callback &&calcDataSize );
182 
183  gpgme_ctx_t _ctx { nullptr };
184  bool _volatile { false };
185 
186  private:
192  std::list<std::string> readSignaturesFprsOptVerify( const Pathname & signature_r, const Pathname & file_r = "/dev/null", bool * verify_r = nullptr );
193  std::list<std::string> readSignaturesFprsOptVerify( const ByteArray& keyData_r, const Pathname & file_r = "/dev/null", bool * verify_r = nullptr );
194  std::list<std::string> readSignaturesFprsOptVerify( GpgmeDataPtr &sigData, const Pathname & file_r = "/dev/null", bool * verify_r = nullptr );
195  };
196 
197 std::list<std::string> KeyManagerCtx::Impl::readSignaturesFprsOptVerify( const Pathname & signature_r, const Pathname & file_r, bool * verify_r )
198 {
199  //lets be pessimistic
200  if ( verify_r )
201  *verify_r = false;
202 
203  if (!PathInfo( signature_r ).isExist())
204  return std::list<std::string>();
205 
206  FILEPtr sigFile(fopen(signature_r.c_str(), "rb"), fclose);
207  if (!sigFile) {
208  ERR << "Unable to open signature file '" << signature_r << "'" <<endl;
209  return std::list<std::string>();
210  }
211 
212  GpgmeDataPtr sigData(nullptr, gpgme_data_release);
213  GpgmeErr err = gpgme_data_new_from_stream (&sigData.get(), sigFile.get());
214  if (err) {
215  ERR << err << endl;
216  return std::list<std::string>();
217  }
218 
219  return readSignaturesFprsOptVerify( sigData, file_r, verify_r );
220 }
221 
222 std::list<std::string> KeyManagerCtx::Impl::readSignaturesFprsOptVerify( const ByteArray &keyData_r, const filesystem::Pathname &file_r, bool *verify_r )
223 {
224  //lets be pessimistic
225  if ( verify_r )
226  *verify_r = false;
227 
228  GpgmeDataPtr sigData(nullptr, gpgme_data_release);
229  GpgmeErr err = gpgme_data_new_from_mem(&sigData.get(), keyData_r.data(), keyData_r.size(), 1 );
230  if (err) {
231  ERR << err << endl;
232  return std::list<std::string>();
233  }
234 
235  return readSignaturesFprsOptVerify( sigData, file_r, verify_r );
236 }
237 
238 std::list<std::string> KeyManagerCtx::Impl::readSignaturesFprsOptVerify(GpgmeDataPtr &sigData, const filesystem::Pathname &file_r, bool *verify_r)
239 {
240  //lets be pessimistic
241  if ( verify_r )
242  *verify_r = false;
243 
244  FILEPtr dataFile(fopen(file_r.c_str(), "rb"), fclose);
245  if (!dataFile)
246  return std::list<std::string>();
247 
248  GpgmeDataPtr fileData(nullptr, gpgme_data_release);
249  GpgmeErr err = gpgme_data_new_from_stream (&fileData.get(), dataFile.get());
250  if (err) {
251  ERR << err << endl;
252  return std::list<std::string>();
253  }
254 
255  err = gpgme_op_verify(_ctx, sigData.get(), fileData.get(), NULL);
256  if (err != GPG_ERR_NO_ERROR) {
257  ERR << err << endl;
258  return std::list<std::string>();
259  }
260 
261  gpgme_verify_result_t res = gpgme_op_verify_result(_ctx);
262  if (!res || !res->signatures) {
263  ERR << "Unable to read signature fingerprints" <<endl;
264  return std::list<std::string>();
265  }
266 
267  bool foundBadSignature = false;
268  bool foundGoodSignature = false;
269  std::list<std::string> signatures;
270  for ( gpgme_signature_t sig = res->signatures; sig; sig = sig->next ) {
271  //DBG << "- " << sig << std::endl;
272  if ( sig->fpr )
273  {
274  // bsc#1100427: With libgpgme11-1.11.0 and if a recent gpg version was used
275  // to create the signature, the field may contain the full fingerprint, but
276  // we're expected to return the ID.
277  // [https://github.com/gpg/gpgme/commit/478d1650bbef84958ccce439fac982ef57b16cd0]
278  std::string id( sig->fpr );
279  if ( id.size() > 16 )
280  id = id.substr( id.size()-16 );
281 
282  DBG << "Found signature with ID: " << id << " in " << file_r << std::endl;
283  signatures.push_back( std::move(id) );
284  }
285 
286  if ( verify_r && sig->status != GPG_ERR_NO_ERROR ) {
287  const auto status = gpgme_err_code(sig->status);
288 
289  // bsc#1180721: libgpgme started to return signatures of unknown keys, which breaks
290  // our workflow when verifying files that have multiple signatures, including some that are
291  // not in the trusted keyring. We should not fail if we have unknown or expired keys and at least a good one.
292  // We will however keep the behaviour of failing if we find a bad signatures even if others are good.
293  switch ( status ) {
294  case GPG_ERR_KEY_EXPIRED:
295  // for now treat expired keys as good signature
296  foundGoodSignature = true;
297  WAR << "Accept good signature from expired key: " << file_r << " " << GpgmeErr(sig->status) << endl;
298  break;
299 
300  case GPG_ERR_NO_PUBKEY:
301  WAR << "Legacy: Ignore unknown key: " << file_r << " " << GpgmeErr(sig->status) << endl;
302  break;
303 
304  default:
305  WAR << "Failed signature check: " << file_r << " " << GpgmeErr(sig->status) << endl;
306  if ( !foundBadSignature )
307  foundBadSignature = true;
308  break;
309  }
310  } else {
311  foundGoodSignature = true;
312  }
313  }
314 
315  if ( verify_r )
316  *verify_r = (!foundBadSignature) && foundGoodSignature;
317  return signatures;
318 }
319 
321 : _pimpl( new Impl )
322 {}
323 
325 {
326  static Pathname tmppath( zypp::myTmpDir() / "PublicKey" );
327  filesystem::assert_dir( tmppath );
328 
329  KeyManagerCtx ret { createForOpenPGP( tmppath ) };
330  ret._pimpl->_volatile = true; // readKeyFromFile workaround bsc#1140670
331  return ret;
332 }
333 
335 {
336  // DBG << "createForOpenPGP(" << keyring_r << ")" << endl;
337 
338  KeyManagerCtx ret;
339  gpgme_ctx_t & ctx { ret._pimpl->_ctx };
340 
341  // create the context
342  GpgmeErr err = gpgme_new( &ctx );
343  if ( err != GPG_ERR_NO_ERROR )
344  ZYPP_THROW( GpgmeException( "gpgme_new", err ) );
345 
346  // use OpenPGP
347  err = gpgme_set_protocol( ctx, GPGME_PROTOCOL_OpenPGP );
348  if ( err != GPG_ERR_NO_ERROR )
349  ZYPP_THROW( GpgmeException( "gpgme_set_protocol", err ) );
350 
351  if ( !keyring_r.empty() ) {
352  // get engine information to read current state
353  gpgme_engine_info_t enginfo = gpgme_ctx_get_engine_info( ctx );
354  if ( !enginfo )
355  ZYPP_THROW( GpgmeException( "gpgme_ctx_get_engine_info", err ) );
356 
357  err = gpgme_ctx_set_engine_info( ctx, GPGME_PROTOCOL_OpenPGP, enginfo->file_name, keyring_r.c_str() );
358  if ( err != GPG_ERR_NO_ERROR )
359  ZYPP_THROW( GpgmeException( "gpgme_ctx_set_engine_info", err ) );
360  }
361 #if 0
362  DBG << "createForOpenPGP {" << endl;
363  for ( const auto & key : ret.listKeys() ) {
364  DBG << " " << key << endl;
365  }
366  DBG << "}" << endl;
367 #endif
368  return ret;
369 }
370 
372 {
373  Pathname ret;
374  if ( gpgme_engine_info_t enginfo = gpgme_ctx_get_engine_info( _pimpl->_ctx ) )
375  ret = enginfo->home_dir;
376  return ret;
377 }
378 
379 std::list<PublicKeyData> KeyManagerCtx::listKeys()
380 {
381  std::list<PublicKeyData> ret;
382  GpgmeErr err = GPG_ERR_NO_ERROR;
383 
384  // Reset gpgme_keylist_mode on return!
385  AutoDispose<gpgme_keylist_mode_t> guard { gpgme_get_keylist_mode( _pimpl->_ctx ), bind( &gpgme_set_keylist_mode, _pimpl->_ctx, _1 ) };
386  // Let listed keys include signatures (required if PublicKeyData are created from the key)
387  if ( (err = gpgme_set_keylist_mode( _pimpl->_ctx, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS )) != GPG_ERR_NO_ERROR ) {
388  ERR << "gpgme_set_keylist_mode: " << err << endl;
389  return ret;
390  }
391 
392  if ( (err = gpgme_op_keylist_start( _pimpl->_ctx, NULL, 0 )) != GPG_ERR_NO_ERROR ) {
393  ERR << "gpgme_op_keylist_start: " << err << endl;
394  return ret;
395  }
396  // Close list operation on return!
397  AutoDispose<gpgme_ctx_t> guard2 { _pimpl->_ctx, &gpgme_op_keylist_end };
398 
399  AutoDispose<gpgme_key_t> key { nullptr, &gpgme_key_release };
400  for ( ; gpgme_op_keylist_next( _pimpl->_ctx, &(*key) ) == GPG_ERR_NO_ERROR; key.getDispose()( key ) ) {
402  if ( data )
403  ret.push_back( data );
404  }
405 
406  return ret;
407 }
408 
409 std::list<PublicKeyData> KeyManagerCtx::readKeyFromFile( const Pathname & keyfile_r )
410 {
411  // bsc#1140670: GPGME does not support reading keys from a keyfile using
412  // gpgme_data_t and gpgme_op_keylist_from_data_start. Despite GPGME_KEYLIST_MODE_SIGS
413  // the signatures are missing, but we need them to create proper PublicKeyData objects.
414  // While this is not resolved, we read into a temp. keyring. Impl::_volatile helps
415  // to detect whether we can clear and import into the current context or need to
416  // create a temp. one.
417  std::list<PublicKeyData> ret;
418 
419  if ( _pimpl->_volatile ) {
420  // in a volatile context we can simple clear the keyring...
422  if ( importKey( keyfile_r ) )
423  ret = listKeys();
424  } else {
425  // read in a volatile context
426  ret = createForOpenPGP().readKeyFromFile( keyfile_r );
427  }
428 
429  return ret;
430 }
431 
432 bool KeyManagerCtx::verify(const Pathname &file, const Pathname &signature)
433 {
434  return _pimpl->verifySignaturesFprs(file, signature);
435 }
436 
437 bool KeyManagerCtx::exportKey(const std::string &id, std::ostream &stream)
438 {
439  GpgmeErr err = GPG_ERR_NO_ERROR;
440 
441  GpgmeKeyPtr foundKey;
442 
443  //search for requested key id
444  gpgme_key_t key = nullptr;
445  gpgme_op_keylist_start(_pimpl->_ctx, NULL, 0);
446  while (!(err = gpgme_op_keylist_next(_pimpl->_ctx, &key))) {
447  if (key->subkeys && id == str::asString(key->subkeys->keyid)) {
448  GpgmeKeyPtr(key, gpgme_key_release).swap(foundKey);
449  break;
450  }
451  gpgme_key_release(key);
452  }
453  gpgme_op_keylist_end(_pimpl->_ctx);
454 
455  if (!foundKey) {
456  WAR << "Key " << id << "not found" << endl;
457  return false;
458  }
459 
460  //function needs a array of keys to export
461  gpgme_key_t keyarray[2];
462  keyarray[0] = foundKey.get();
463  keyarray[1] = NULL;
464 
465  GpgmeDataPtr out(nullptr, gpgme_data_release);
466  err = gpgme_data_new (&out.get());
467  if (err) {
468  ERR << err << endl;
469  return false;
470  }
471 
472  //format as ascii armored
473  gpgme_set_armor (_pimpl->_ctx, 1);
474  // bsc#1179222: Remove outdated self signatures when exporting the key.
475  // The keyring does not order the signatures when multiple versions of the
476  // same key are imported. Rpm however uses the 1st to compute the -release
477  // of the gpg-pubkey. So we export only the latest to get a proper-release.
478  err = gpgme_op_export_keys (_pimpl->_ctx, keyarray, GPGME_EXPORT_MODE_MINIMAL, out.get());
479  if (!err) {
480  int ret = gpgme_data_seek (out.get(), 0, SEEK_SET);
481  if (ret) {
482  ERR << "Unable to seek in exported key data" << endl;
483  return false;
484  }
485 
486  const int bufsize = 512;
487  char buf[bufsize + 1];
488  while ((ret = gpgme_data_read(out.get(), buf, bufsize)) > 0) {
489  stream.write(buf, ret);
490  }
491 
492  //failed to read from buffer
493  if (ret < 0) {
494  ERR << "Unable to read exported key data" << endl;
495  return false;
496  }
497  } else {
498  ERR << "Error exporting key: "<< err << endl;
499  return false;
500  }
501 
502  //if we reach this point export was successful
503  return true;
504 }
505 
506 bool KeyManagerCtx::importKey(const Pathname &keyfile)
507 {
508  if ( !PathInfo( keyfile ).isExist() ) {
509  ERR << "Keyfile '" << keyfile << "' does not exist.";
510  return false;
511  }
512 
513  GpgmeDataPtr data(nullptr, gpgme_data_release);
514  GpgmeErr err;
515 
516  err = gpgme_data_new_from_file(&data.get(), keyfile.c_str(), 1);
517  if (err) {
518  ERR << "Error importing key: "<< err << endl;
519  return false;
520  }
521 
522  return _pimpl->importKey( data, [&](){ return PathInfo(keyfile).size(); } );
523 }
524 
525 bool KeyManagerCtx::importKey( const ByteArray &keydata )
526 {
527  GpgmeDataPtr data(nullptr, gpgme_data_release);
528  GpgmeErr err;
529 
530  err = gpgme_data_new_from_mem( &data.get(), keydata.data(), keydata.size(), 1);
531  if (err) {
532  ERR << "Error importing key: "<< err << endl;
533  return false;
534  }
535 
536  return _pimpl->importKey( data, [&](){ return keydata.size(); } );
537 }
538 
539 template<typename Callback>
540 bool KeyManagerCtx::Impl::importKey(GpgmeDataPtr &data, Callback &&calcDataSize)
541 {
542  GpgmeErr err;
543  err = gpgme_op_import( _ctx, data.get() );
544  if (err) {
545  ERR << "Error importing key: "<< err << endl;
546  return false;
547  }
548 
549  // Work around bsc#1127220 [libgpgme] no error upon incomplete import due to signal received.
550  // We need this error, otherwise RpmDb will report the missing keys as 'probably v3'.
551  if ( gpgme_import_result_t res = gpgme_op_import_result(_ctx) )
552  {
553  if ( ! res->considered && std::forward<Callback>(calcDataSize)() )
554  {
555  DBG << *res << endl;
556  ERR << "Error importing key: No keys considered (bsc#1127220, [libgpgme] signal received?)" << endl;
557  return false;
558  }
559  }
560 
561  return (err == GPG_ERR_NO_ERROR);
562 }
563 
564 bool KeyManagerCtx::deleteKey(const std::string &id)
565 {
566  gpgme_key_t key = nullptr;
567  GpgmeErr err = GPG_ERR_NO_ERROR;
568 
569  gpgme_op_keylist_start(_pimpl->_ctx, NULL, 0);
570 
571  while (!(err = gpgme_op_keylist_next(_pimpl->_ctx, &key))) {
572  if (key->subkeys && id == str::asString(key->subkeys->keyid)) {
573  err = gpgme_op_delete(_pimpl->_ctx, key, 0);
574 
575  gpgme_key_release(key);
576  gpgme_op_keylist_end(_pimpl->_ctx);
577 
578  if (err) {
579  ERR << "Error deleting key: "<< err << endl;
580  return false;
581  }
582  return true;
583  }
584  gpgme_key_release(key);
585  }
586 
587  gpgme_op_keylist_end(_pimpl->_ctx);
588  WAR << "Key: '"<< id << "' not found." << endl;
589  return false;
590 }
591 
592 std::list<std::string> KeyManagerCtx::readSignatureFingerprints(const Pathname &signature)
593 { return _pimpl->readSignaturesFprs(signature); }
594 
595 std::list<std::string> KeyManagerCtx::readSignatureFingerprints(const ByteArray &keyData)
596 { return _pimpl->readSignaturesFprs(keyData); }
597 
598 } // namespace zypp
#define MIL
Definition: Logger.h:103
Impl & operator=(const Impl &)=delete
std::list< PublicKeyData > readKeyFromFile(const Pathname &file)
Returns a list of all PublicKeyData found in file.
Definition: KeyManager.cc:409
int assert_dir(const Pathname &path, unsigned mode)
Like &#39;mkdir -p&#39;.
Definition: PathInfo.cc:338
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:459
int clean_dir(const Pathname &path)
Like &#39;rm -r DIR/ *&#39;.
Definition: PathInfo.cc:461
std::list< std::string > readSignaturesFprs(const Pathname &signature_r)
Return all fingerprints found in signature_r.
Definition: KeyManager.cc:165
gpgme_error_t _err
Definition: KeyManager.cc:66
Class representing one GPG Public Keys data.
Definition: PublicKey.h:200
const char * c_str() const
String representation.
Definition: Pathname.h:113
String related utilities and Regular expression matching.
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition: String.h:140
bool verify(const Pathname &file, const Pathname &signature)
Tries to verify file using signature, returns true on success.
Definition: KeyManager.cc:432
static KeyManagerCtx createForOpenPGP()
Creates a new KeyManagerCtx for PGP using a volatile temp.
Definition: KeyManager.cc:324
#define ERR
Definition: Logger.h:105
bool exportKey(const std::string &id, std::ostream &stream)
Exports the key with id into the given stream, returns true on success.
Definition: KeyManager.cc:437
RW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: KeyManager.h:87
Pathname homedir() const
Return the homedir/keyring.
Definition: KeyManager.cc:371
bool empty() const
Test for an empty path.
Definition: Pathname.h:117
bool importKey(const Pathname &keyfile)
Tries to import a key from keyfile, returns true on success.
Definition: KeyManager.cc:506
repo::DownloadContextRef _ctx
Definition: rpmmd.cc:63
std::list< std::string > readSignaturesFprs(const ByteArray &signature_r)
Return all fingerprints found in signature_r.
Definition: KeyManager.cc:169
#define OSC(V)
bool verifySignaturesFprs(const Pathname &file_r, const Pathname &signature_r)
Tries to verify the file_r using signature_r.
Definition: KeyManager.cc:173
#define WAR
Definition: Logger.h:104
bool deleteKey(const std::string &id)
Tries to delete a key specified by id, returns true on success.
Definition: KeyManager.cc:564
bool importKey(GpgmeDataPtr &data, Callback &&calcDataSize)
Definition: KeyManager.cc:540
std::list< PublicKeyData > listKeys()
Returns a list of all public keys found in the current keyring.
Definition: KeyManager.cc:379
GpgmeException(const std::string &in_r, const GpgmeErr &err_r)
Definition: KeyManager.cc:143
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:94
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:225
std::list< std::string > readSignatureFingerprints(const Pathname &signature)
Reads all fingerprints from the signature file , returns a list of all found fingerprints.
Definition: KeyManager.cc:592
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition: Capabilities.cc:65
std::list< std::string > readSignaturesFprsOptVerify(const Pathname &signature_r, const Pathname &file_r="/dev/null", bool *verify_r=nullptr)
Return all fingerprints found in signature_r and optionally verify the file_r on the fly...
Definition: KeyManager.cc:197
static PublicKeyData fromGpgmeKey(_gpgme_key *data)
Definition: PublicKey.cc:406
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
Pathname myTmpDir()
Global access to the zypp.TMPDIR (created on demand, deleted when libzypp is unloaded) ...
Definition: TmpPath.cc:276
bool _volatile
readKeyFromFile workaround bsc#1140670
Definition: KeyManager.cc:184
#define DBG
Definition: Logger.h:102