1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
|
/*---------------------------------------------------------------------\
| ____ _ __ __ ___ |
| |__ / \ / / . \ . \ |
| / / \ V /| _/ _/ |
| / /__ | | | | | | |
| /_____||_| |_| |_| |
| |
\---------------------------------------------------------------------*/
/** \file zypp/PublicKey.h
*
*/
#ifndef ZYPP_PUBLICKEY_H
#define ZYPP_PUBLICKEY_H
#include <iosfwd>
#include <list>
#include <string>
#include <utility>
#include <zypp-common/base/DrunkenBishop.h>
#include <zypp/base/Iterable.h>
#include <zypp/base/PtrTypes.h>
#include <zypp/base/Exception.h>
#include <zypp/Pathname.h>
#include <zypp/Edition.h>
#include <zypp/Date.h>
struct _gpgme_key;
struct _gpgme_subkey;
struct _gpgme_key_sig;
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
namespace filesystem
{
class TmpFile;
}
class PublicKeyData;
class KeyManagerCtx;
///////////////////////////////////////////////////////////////////
/// \class BadKeyException
/// \brief Exception thrown when the supplied key is not a valid gpg key
///////////////////////////////////////////////////////////////////
class ZYPP_API BadKeyException : public Exception
{
public:
/** Ctor taking message.
* Use \ref ZYPP_THROW to throw exceptions.
*/
BadKeyException()
: Exception( "Bad Key Exception" )
{}
Pathname keyFile() const
{ return _keyfile; }
/** Ctor taking message.
* Use \ref ZYPP_THROW to throw exceptions.
*/
BadKeyException( const std::string & msg_r, Pathname keyfile = Pathname() )
: Exception( msg_r ), _keyfile(std::move(keyfile))
{}
/** Dtor. */
~BadKeyException() throw() override {};
private:
Pathname _keyfile;
};
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/// \class PublicSubkeyData
/// \brief Class representing a GPG Public Keys subkeys.
/// \see \ref PublicKeyData.
///////////////////////////////////////////////////////////////////
class ZYPP_API PublicSubkeyData
{
public:
/** Default constructed: empty data. */
PublicSubkeyData();
~PublicSubkeyData();
/** Whether this contains valid data (not default constructed). */
explicit operator bool() const;
public:
/** Subkey ID. */
std::string id() const;
/** Creation date. */
Date created() const;
/** Expiry date, or \c Date() if the key never expires. */
Date expires() const;
/** Whether the key has expired. */
bool expired() const;
/** Number of days (24h) until the key expires (or since it exired).
* A value of \c 0 means the key will expire within the next 24h.
* Negative values indicate the key has expired less than \c N days ago.
* For keys without expiration date \c INT_MAX is returned.
*/
int daysToLive() const;
/** Simple string representation.
* Encodes \ref id, \ref created and \ref expires
* \code
* 640DB551 2016-04-12 [expires: 2019-04-12]
* \endcode
*/
std::string asString() const;
private:
struct Impl;
RWCOW_pointer<Impl> _pimpl;
friend class PublicKeyData;
friend std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj );
PublicSubkeyData(const _gpgme_subkey *rawSubKeyData);
};
///////////////////////////////////////////////////////////////////
/** \relates PublicSubkeyData Stream output */
inline std::ostream & operator<<( std::ostream & str, const PublicSubkeyData & obj )
{ return str << obj.asString(); }
///////////////////////////////////////////////////////////////////
/// \class PublicKeySignatureData
/// \brief Class representing a signature on a GPG Public Key.
/// \see \ref PublicKeyData.
///////////////////////////////////////////////////////////////////
class ZYPP_API PublicKeySignatureData
{
public:
/** Default constructed: empty data. */
PublicKeySignatureData();
~PublicKeySignatureData();
/** Whether this contains valid data (not default constructed). */
explicit operator bool() const;
public:
/** The key ID of key used to create the signature. */
std::string id() const;
/** The user ID associated with this key, if present. */
std::string name() const;
/** Creation date. */
Date created() const;
/** Expiry date, or \c Date() if the key never expires. */
Date expires() const;
/** Whether the key has expired. */
bool expired() const;
/** Number of days (24h) until the key expires (or since it expired).
* A value of \c 0 means the key will expire within the next 24h.
* Negative values indicate the key has expired less than \c N days ago.
* For keys without expiration date \c INT_MAX is returned.
*/
int daysToLive() const;
/** Simple string representation.
* Encodes \ref id, \ref created and \ref expires
* \code
* 640DB551 2016-04-12 [expires: 2019-04-12]
* \endcode
*/
std::string asString() const;
private:
struct Impl;
RWCOW_pointer<Impl> _pimpl;
friend class PublicKeyData;
friend std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj );
PublicKeySignatureData(const _gpgme_key_sig *rawKeySignatureData);
};
///////////////////////////////////////////////////////////////////
/** \relates PublicKeySignatureData Stream output */
inline std::ostream & operator<<( std::ostream & str, const PublicKeySignatureData & obj )
{ return str << obj.asString(); }
///////////////////////////////////////////////////////////////////
/// \class PublicKeyData
/// \brief Class representing one GPG Public Keys data.
/// \ref PublicKeyData are provided e.g. by a \ref PublicKey or
/// a \ref KeyRing. \ref PublicKeyData are usually easier to
/// retrieve and sufficient unless you actually need an ASCII
/// armored version of the key placed in a tempfile. In this
/// case use \ref PublicKey.
///////////////////////////////////////////////////////////////////
class ZYPP_API PublicKeyData
{
public:
/** Default constructed: empty data. */
PublicKeyData();
~PublicKeyData();
PublicKeyData(const PublicKeyData &) = default;
PublicKeyData(PublicKeyData &&) noexcept = default;
PublicKeyData &operator=(const PublicKeyData &) = default;
PublicKeyData &operator=(PublicKeyData &&) noexcept = default;
/** Whether this contains valid data (not default constructed). */
explicit operator bool() const;
public:
/** Key ID. */
std::string id() const;
/** Key name. */
std::string name() const;
/** Key fingerprint.*/
std::string fingerprint() const;
/** Key algorithm string like `RSA 2048` */
std::string algoName() const;
/** Creation / last modification date (latest selfsig). */
Date created() const;
/** Expiry date, or \c Date() if the key never expires. */
Date expires() const;
/** Whether the key has expired. */
bool expired() const;
/** Number of days (24h) until the key expires (or since it exired).
* A value of \c 0 means the key will expire within the next 24h.
* Negative values indicate the key has expired less than \c N days ago.
* For keys without expiration date \c INT_MAX is returned.
*/
int daysToLive() const;
/** * Expiry info in a human readable form.
* The expiry date plus an annotation if the key has expired, or will
* expire within 90 days.
* \code
* (does not expire)
* Tue May 11 13:37:33 CEST 2010
* Tue May 11 13:37:33 CEST 2010 (expires in 90 days)
* Tue May 11 13:37:33 CEST 2010 (expires in 1 day)
* Tue May 11 13:37:33 CEST 2010 (expires within 24h)
* Tue May 11 13:37:33 CEST 2010 (EXPIRED)
* \endcode
*/
std::string expiresAsString() const;
/** Gpg-pubkey version as computed by rpm (trailing 8 byte \ref id) */
std::string gpgPubkeyVersion() const;
/** Gpg-pubkey release as computed by rpm (hexencoded \ref created) */
std::string gpgPubkeyRelease() const;
/** Gpg-pubkey name as computed by rpm*/
std::string rpmName () const;
/** Gpg-pubkey \ref Edition built from version and release.*/
Edition gpgPubkeyEdition() const
{ return Edition( gpgPubkeyVersion(), gpgPubkeyRelease() ); }
/** Simple string representation.
* Encodes \ref id, \ref gpgPubkeyRelease, \ref name and \ref fingerprint.
* \code
* [E3A5C360307E3D54-4be01a65] [SuSE Package Signing Key <build@suse.de>] [4E98E67519D98DC7362A5990E3A5C360307E3D54]
* \endcode
*/
std::string asString() const;
public:
using SubkeyIterator = const PublicSubkeyData *;
using KeySignatureIterator = const PublicKeySignatureData *;
/** Whether \ref subkeys is not empty. */
bool hasSubkeys() const;
/** Iterate any subkeys. */
Iterable<SubkeyIterator> subkeys() const;
/** Iterate all key signatures. */
Iterable<KeySignatureIterator> signatures() const;
/** Whether \a id_r is the \ref id or \ref fingerprint of the primary key or of a subkey.
* As a convenience also allows to test the 8byte short ID e.g. rpm uses as version.
*/
bool providesKey( const std::string & id_r ) const;
/** Whether this is a long id (64bit/16byte) or even better a fingerprint.
* A short Id (32bit/8byte) is not considered to be a safe identifier for a key.
*/
static bool isSafeKeyId( const std::string & id_r )
{ return id_r.size() >= 16; }
public:
/** Whether \ref signatures is not empty. */
bool hasSignatures() const;
public:
/** Random art fingerprint visualization type (\ref base::DrunkenBishop). */
using AsciiArt = base::DrunkenBishop;
/** Random art fingerprint visualization (\ref base::DrunkenBishop).
* \code
* PublicKeyData key;
* cout << key.asciiArt( PublicKey::AsciiArt::USE_COLOR ) << endl;
* \endcode
*/
AsciiArt asciiArt() const;
private:
struct Impl;
RWCOW_pointer<Impl> _pimpl;
friend class KeyManagerCtx;
static PublicKeyData fromGpgmeKey(_gpgme_key *data);
PublicKeyData(shared_ptr<Impl> data);
friend std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj );
};
///////////////////////////////////////////////////////////////////
/** \relates PublicKeyData Stream output */
inline std::ostream & operator<<( std::ostream & str, const PublicKeyData & obj )
{ return str << obj.asString(); }
/** \relates PublicKeyData Detailed stream output */
std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj ) ZYPP_API;
/** \relates PublicKeyData Equal based on fingerprint anf creation date. */
bool operator==( const PublicKeyData & lhs, const PublicKeyData & rhs ) ZYPP_API;
/** \relates PublicKeyData NotEqual. */
inline bool operator!=( const PublicKeyData & lhs, const PublicKeyData & rhs )
{ return !( lhs == rhs ); }
///////////////////////////////////////////////////////////////////
/// \class PublicKey
/// \brief Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
///
/// If you don't need the ASCII armored version of the key stored in
/// a tempfile, using \ref PublicKeyData might be sufficient.
///
/// \note In case the ASCII armored blob actually contains multiple
/// keys, the \b last keys data are made available via the API. The
/// additional keys data are made available via \ref hiddenKeys.
///////////////////////////////////////////////////////////////////
class ZYPP_API PublicKey
{
public:
/** Implementation */
struct Impl;
public:
/** Default ctor. */
PublicKey();
/** Ctor taking the key from a file.
*
* This is quite expensive, as a copy of the file is created and
* used. If you can construct PublicKey from a \ref filesystem::TmpFile,
* this prevents copying.
*
* \throws when data does not make a key
*/
explicit PublicKey( const Pathname & keyFile_r );
/** Ctor reading the key from a \ref TmpFile.
*
* PublicKey holds a reference on the TmpFile providing the key.
*
* \throws when data does not make a key
*/
explicit PublicKey( const filesystem::TmpFile & sharedFile_r );
~PublicKey();
/** Static ctor returning an empty PublicKey rather than throwing. */
static PublicKey noThrow( const Pathname & keyFile_r );
public:
/** The public keys data (\see \ref PublicKeyData).*/
const PublicKeyData & keyData() const;
using SubkeyIterator = PublicKeyData::SubkeyIterator;
bool isValid() const
{ return ! ( id().empty() || fingerprint().empty() ); }
std::string id() const; //!< \see \ref PublicKeyData
std::string name() const; //!< \see \ref PublicKeyData
std::string fingerprint() const; //!< \see \ref PublicKeyData
std::string algoName() const; //!< \see \ref PublicKeyData
Date created() const; //!< \see \ref PublicKeyData
Date expires() const; //!< \see \ref PublicKeyData
std::string expiresAsString() const; //!< \see \ref PublicKeyData
bool expired() const; //!< \see \ref PublicKeyData
int daysToLive() const; //!< \see \ref PublicKeyData
std::string gpgPubkeyVersion() const; //!< \see \ref PublicKeyData
std::string gpgPubkeyRelease() const; //!< \see \ref PublicKeyData
std::string asString() const; //!< \see \ref PublicKeyData
std::string rpmName () const;
Edition gpgPubkeyEdition() const ///!< \see \ref PublicKeyData
{ return keyData().gpgPubkeyEdition(); }
bool hasSubkeys() const ///!< \see \ref PublicKeyData
{ return keyData().hasSubkeys(); }
Iterable<SubkeyIterator> subkeys() const ///!< \see \ref PublicKeyData
{ return keyData().subkeys(); }
bool providesKey( const std::string & id_r ) const ///!< \see \ref PublicKeyData
{ return keyData().providesKey( id_r ); }
static bool isSafeKeyId( const std::string & id_r ) ///!< \see \ref PublicKeyData
{ return PublicKeyData::isSafeKeyId(id_r); }
public:
using AsciiArt = PublicKeyData::AsciiArt; ///!< \see \ref PublicKeyData
AsciiArt asciiArt() const ///!< \see \ref PublicKeyData
{ return keyData().asciiArt(); }
public:
/** File containing the ASCII armored key. */
Pathname path() const;
/** Additional keys data in case the ASCII armored blob contains multiple keys. */
const std::list<PublicKeyData> & hiddenKeys() const;
/** Extends \ref providesKey to look at the hidden keys too.
* Those 'hidden' keys become visible when the file is imported into a keyring.
*/
bool fileProvidesKey( const std::string & id_r ) const;
public:
bool operator==( const PublicKey & rhs ) const;
bool operator!=( const PublicKey & rhs ) const
{ return not operator==( rhs ); }
bool operator==( const std::string & sid ) const;
bool operator!=( const std::string & sid ) const
{ return not operator==( sid ); }
private:
friend class KeyRingImpl;
/** KeyRing ctor: No need to parse file if KeyRing already had valid KeyData. */
PublicKey( const filesystem::TmpFile & sharedFile_r, const PublicKeyData & keyData_r );
/** KeyRing ctor: Legacy callback APIs take PublicKey, but just need the PublicKeyData No need to export to file. */
explicit PublicKey( const PublicKeyData & keyData_r );
private:
/** Pointer to implementation */
RWCOW_pointer<Impl> _pimpl;
};
///////////////////////////////////////////////////////////////////
/** \relates PublicKey Stream output */
inline std::ostream & operator<<( std::ostream & str, const PublicKey & obj )
{ return str << obj.asString(); }
/** \relates PublicKey Detailed stream output */
std::ostream & dumpOn( std::ostream & str, const PublicKey & obj ) ZYPP_API;
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#endif // ZYPP_PUBLICKEY_H
|