00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #include <gpgmepp/key.h>
00025
00026 #include "util.h"
00027
00028 #include <gpgme.h>
00029
00030 #include <string.h>
00031
00032 GpgME::Key GpgME::Key::null;
00033
00034 namespace GpgME {
00035
00036 using std::vector;
00037
00038 struct Key::Private {
00039 Private( gpgme_key_t aKey, unsigned int aMode )
00040 : key( aKey ),
00041 #ifdef HAVE_GPGME_KEY_T_KEYLIST_MODE
00042 mode( 0 )
00043 #else
00044 mode( aMode )
00045 #endif
00046 {}
00047 gpgme_key_t key;
00048 unsigned int mode;
00049 };
00050
00051 Key::Key() {
00052 d = new Private( 0, 0 );
00053 }
00054
00055 Key::Key( gpgme_key_t key, bool ref, unsigned int mode ) {
00056 d = new Private( key, mode );
00057 if ( ref && d->key )
00058 gpgme_key_ref( d->key );
00059 }
00060
00061 Key::Key( const Key & other ) {
00062 d = new Private( other.d->key, other.d->mode );
00063 if ( d->key )
00064 gpgme_key_ref( d->key );
00065 }
00066
00067 Key::~Key() {
00068 if ( d->key )
00069 gpgme_key_unref( d->key );
00070 delete d; d = 0;
00071 }
00072
00073 const Key & Key::operator=( const Key & other ) {
00074 if ( d == other.d ) return *this;
00075
00076 if ( other.d->key )
00077 gpgme_key_ref( other.d->key );
00078 if ( d->key )
00079 gpgme_key_unref( d->key );
00080 *d = *other.d;
00081 return *this;
00082 }
00083
00084 bool Key::isNull() const {
00085 return d->key == 0;
00086 }
00087
00088 gpgme_key_t Key::impl() const {
00089 return d->key;
00090 }
00091
00092
00093
00094 UserID Key::userID( unsigned int index ) const {
00095 return UserID( d->key, index );
00096 }
00097
00098 Subkey Key::subkey( unsigned int index ) const {
00099 return Subkey( d->key, index );
00100 }
00101
00102
00103 unsigned int Key::numUserIDs() const {
00104 if ( !d->key )
00105 return 0;
00106 unsigned int count = 0;
00107 for ( gpgme_user_id_t uid = d->key->uids ; uid ; uid = uid->next )
00108 ++count;
00109 return count;
00110 }
00111
00112 unsigned int Key::numSubkeys() const {
00113 if ( !d->key )
00114 return 0;
00115 unsigned int count = 0;
00116 for ( gpgme_sub_key_t subkey = d->key->subkeys ; subkey ; subkey = subkey->next )
00117 ++count;
00118 return count;
00119 }
00120
00121 vector<UserID> Key::userIDs() const {
00122 if ( !d->key )
00123 return vector<UserID>();
00124
00125 vector<UserID> v;
00126 v.reserve( numUserIDs() );
00127 for ( gpgme_user_id_t uid = d->key->uids ; uid ; uid = uid->next )
00128 v.push_back( UserID( d->key, uid ) );
00129 return v;
00130 }
00131
00132 vector<Subkey> Key::subkeys() const {
00133 if ( !d->key )
00134 return vector<Subkey>();
00135
00136 vector<Subkey> v;
00137 v.reserve( numSubkeys() );
00138 for ( gpgme_sub_key_t subkey = d->key->subkeys ; subkey ; subkey = subkey->next )
00139 v.push_back( Subkey( d->key, subkey ) );
00140 return v;
00141 }
00142
00143 Key::OwnerTrust Key::ownerTrust() const {
00144 if ( !d->key )
00145 return Unknown;
00146 switch ( d->key->owner_trust ) {
00147 default:
00148 case GPGME_VALIDITY_UNKNOWN: return Unknown;
00149 case GPGME_VALIDITY_UNDEFINED: return Undefined;
00150 case GPGME_VALIDITY_NEVER: return Never;
00151 case GPGME_VALIDITY_MARGINAL: return Marginal;
00152 case GPGME_VALIDITY_FULL: return Full;
00153 case GPGME_VALIDITY_ULTIMATE: return Ultimate;
00154 }
00155 }
00156 char Key::ownerTrustAsString() const {
00157 if ( !d->key )
00158 return '?';
00159 switch ( d->key->owner_trust ) {
00160 default:
00161 case GPGME_VALIDITY_UNKNOWN: return '?';
00162 case GPGME_VALIDITY_UNDEFINED: return 'q';
00163 case GPGME_VALIDITY_NEVER: return 'n';
00164 case GPGME_VALIDITY_MARGINAL: return 'm';
00165 case GPGME_VALIDITY_FULL: return 'f';
00166 case GPGME_VALIDITY_ULTIMATE: return 'u';
00167 }
00168 }
00169
00170 Context::Protocol Key::protocol() const {
00171 if ( !d->key )
00172 return Context::Unknown;
00173 switch ( d->key->protocol ) {
00174 case GPGME_PROTOCOL_CMS: return Context::CMS;
00175 case GPGME_PROTOCOL_OpenPGP: return Context::OpenPGP;
00176 default: return Context::Unknown;
00177 }
00178 }
00179
00180 const char * Key::protocolAsString() const {
00181 return d->key ? gpgme_get_protocol_name( d->key->protocol ) : 0 ;
00182 }
00183
00184 bool Key::isRevoked() const {
00185 return d->key && d->key->revoked;
00186 }
00187
00188 bool Key::isExpired() const {
00189 return d->key && d->key->expired;
00190 }
00191
00192 bool Key::isDisabled() const {
00193 return d->key && d->key->disabled;
00194 }
00195
00196 bool Key::isInvalid() const {
00197 return d->key && d->key->invalid;
00198 }
00199
00200 bool Key::hasSecret() const {
00201 return d->key && d->key->secret;
00202 }
00203
00204 bool Key::isRoot() const {
00205 return d->key && d->key->subkeys && d->key->subkeys->fpr && d->key->chain_id &&
00206 strcasecmp( d->key->subkeys->fpr, d->key->chain_id ) == 0;
00207 }
00208
00209 bool Key::canEncrypt() const {
00210 return d->key && d->key->can_encrypt;
00211 }
00212
00213 bool Key::canSign() const {
00214 #ifndef GPGME_CAN_SIGN_ON_SECRET_OPENPGP_KEYLISTING_NOT_BROKEN
00215 if ( d->key && d->key->protocol == GPGME_PROTOCOL_OpenPGP )
00216 return true;
00217 #endif
00218 return d->key && d->key->can_sign;
00219 }
00220
00221 bool Key::canCertify() const {
00222 return d->key && d->key->can_certify;
00223 }
00224
00225 bool Key::canAuthenticate() const {
00226 return d->key && d->key->can_authenticate;
00227 }
00228
00229 bool Key::isQualified() const {
00230 #ifdef HAVE_GPGME_KEY_T_IS_QUALIFIED
00231 return d->key && d->key->is_qualified;
00232 #else
00233 return false;
00234 #endif
00235 }
00236
00237 const char * Key::issuerSerial() const {
00238 return d->key ? d->key->issuer_serial : 0 ;
00239 }
00240 const char * Key::issuerName() const {
00241 return d->key ? d->key->issuer_name : 0 ;
00242 }
00243 const char * Key::chainID() const {
00244 return d->key ? d->key->chain_id : 0 ;
00245 }
00246
00247 const char * Key::keyID() const {
00248 #ifdef HAVE_GPGME_KEY_T_KEYID
00249 return d->key ? d->key->keyid : 0 ;
00250 #else
00251 if ( !d->key || !d->key->subkeys || !d->key->subkeys->fpr )
00252 return 0;
00253 const int len = strlen( d->key->subkeys->fpr );
00254 if ( len < 16 )
00255 return 0;
00256 return d->key->subkeys->fpr + len - 16;
00257 #endif
00258 }
00259
00260 const char * Key::shortKeyID() const {
00261 if ( const char * keyid = keyID() )
00262 return keyid + 8 ;
00263 else
00264 return 0;
00265 }
00266
00267 const char * Key::primaryFingerprint() const {
00268 #ifdef HAVE_GPGME_KEY_T_FPR
00269 return d->key ? d->key->fpr : 0 ;
00270 #else
00271 return d->key && d->key->subkeys ? d->key->subkeys->fpr : 0 ;
00272 #endif
00273 }
00274
00275 unsigned int Key::keyListMode() const {
00276 #ifdef HAVE_GPGME_KEY_T_KEYLIST_MODE
00277 return d->key ? convert_from_gpgme_keylist_mode_t( d->key->keylist_mode ) : 0 ;
00278 #else
00279 return d ? d->mode : 0 ;
00280 #endif
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 struct Subkey::Private {
00290 Private( gpgme_key_t aKey, unsigned int idx )
00291 : key( aKey ), subkey( 0 )
00292 {
00293 if ( key )
00294 for ( gpgme_sub_key_t s = key->subkeys ; s ; s = s->next, --idx )
00295 if ( idx == 0 ) {
00296 subkey = s;
00297 break;
00298 }
00299 if ( !subkey )
00300 key = 0;
00301 }
00302
00303 Private( gpgme_key_t aKey, gpgme_sub_key_t aSubkey )
00304 : key( aKey ), subkey( 0 )
00305 {
00306 if ( key )
00307 for ( gpgme_sub_key_t s = key->subkeys ; s ; s = s->next )
00308 if ( s == aSubkey ) {
00309 subkey = aSubkey;
00310 break;
00311 }
00312 if ( !subkey )
00313 key = 0;
00314 }
00315
00316 gpgme_key_t key;
00317 gpgme_sub_key_t subkey;
00318 };
00319
00320 Subkey::Subkey( gpgme_key_t key, unsigned int idx ) {
00321 d = new Private( key, idx );
00322 if ( d->key )
00323 gpgme_key_ref( d->key );
00324 }
00325
00326 Subkey::Subkey( gpgme_key_t key, gpgme_sub_key_t subkey ) {
00327 d = new Private( key, subkey );
00328 if ( d->key )
00329 gpgme_key_ref( d->key );
00330 }
00331
00332 Subkey::Subkey( const Subkey & other ) {
00333 d = new Private( other.d->key, other.d->subkey );
00334 if ( d->key )
00335 gpgme_key_ref( d->key );
00336 }
00337
00338 Subkey::~Subkey() {
00339 if ( d->key )
00340 gpgme_key_unref( d->key );
00341 delete d; d = 0;
00342 }
00343
00344 const Subkey & Subkey::operator=( const Subkey & other ) {
00345 if ( &other == this ) return *this;
00346
00347 if ( other.d->key )
00348 gpgme_key_ref( other.d->key );
00349 if ( d->key )
00350 gpgme_key_unref( d->key );
00351 *d = *other.d;
00352 return *this;
00353 }
00354
00355 bool Subkey::isNull() const {
00356 return !d || !d->key || !d->subkey;
00357 }
00358
00359 Key Subkey::parent() const {
00360 return Key( d->key, true );
00361 }
00362
00363 const char * Subkey::keyID() const {
00364 return d->subkey ? d->subkey->keyid : 0 ;
00365 }
00366
00367 const char * Subkey::fingerprint() const {
00368 return d->subkey ? d->subkey->fpr : 0 ;
00369 }
00370
00371 unsigned int Subkey::publicKeyAlgorithm() const {
00372 return d->subkey ? d->subkey->pubkey_algo : 0 ;
00373 }
00374
00375 const char * Subkey::publicKeyAlgorithmAsString() const {
00376 return gpgme_pubkey_algo_name( d->subkey ? d->subkey->pubkey_algo : (gpgme_pubkey_algo_t)0 );
00377 }
00378
00379 bool Subkey::canEncrypt() const {
00380 return d->subkey && d->subkey->can_encrypt;
00381 }
00382
00383 bool Subkey::canSign() const {
00384 return d->subkey && d->subkey->can_sign;
00385 }
00386
00387 bool Subkey::canCertify() const {
00388 return d->subkey && d->subkey->can_certify;
00389 }
00390
00391 bool Subkey::canAuthenticate() const {
00392 return d->subkey && d->subkey->can_authenticate;
00393 }
00394
00395 bool Subkey::isQualified() const {
00396 #ifdef HAVE_GPGME_SUBKEY_T_IS_QUALIFIED
00397 return d->subkey && d->subkey->is_qualified;
00398 #else
00399 return false;
00400 #endif
00401 }
00402
00403 unsigned int Subkey::length() const {
00404 return d->subkey ? d->subkey->length : 0 ;
00405 }
00406
00407 time_t Subkey::creationTime() const {
00408 return static_cast<time_t>( d->subkey ? d->subkey->timestamp : 0 );
00409 }
00410
00411 time_t Subkey::expirationTime() const {
00412 return static_cast<time_t>( d->subkey ? d->subkey->expires : 0 );
00413 }
00414
00415 bool Subkey::neverExpires() const {
00416 return expirationTime() == time_t(0);
00417 }
00418
00419 bool Subkey::isRevoked() const {
00420 return d->subkey && d->subkey->revoked;
00421 }
00422
00423 bool Subkey::isInvalid() const {
00424 return d->subkey && d->subkey->invalid;
00425 }
00426
00427 bool Subkey::isExpired() const {
00428 return d->subkey && d->subkey->expired;
00429 }
00430
00431 bool Subkey::isDisabled() const {
00432 return d->subkey && d->subkey->disabled;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 struct UserID::Private {
00442 Private( gpgme_key_t aKey, unsigned int idx )
00443 : key( aKey ), uid( 0 )
00444 {
00445 if ( key )
00446 for ( gpgme_user_id_t u = key->uids ; u ; u = u->next, --idx )
00447 if ( idx == 0 ) {
00448 uid = u;
00449 break;
00450 }
00451 if ( !uid )
00452 key = 0;
00453 }
00454
00455 Private( gpgme_key_t aKey, gpgme_user_id_t aUid )
00456 : key( aKey ), uid( 0 )
00457 {
00458 if ( key )
00459 for ( gpgme_user_id_t u = key->uids ; u ; u = u->next )
00460 if ( u == aUid ) {
00461 uid = u;
00462 break;
00463 }
00464 if ( !uid )
00465 key = 0;
00466 }
00467
00468 gpgme_key_t key;
00469 gpgme_user_id_t uid;
00470 };
00471
00472 UserID::UserID( gpgme_key_t key, gpgme_user_id_t uid ) {
00473 d = new Private( key, uid );
00474 if ( d->key )
00475 gpgme_key_ref( d->key );
00476 }
00477
00478 UserID::UserID( gpgme_key_t key, unsigned int idx ) {
00479 d = new Private( key, idx );
00480 if ( d->key )
00481 gpgme_key_ref( d->key );
00482 }
00483
00484 UserID::UserID( const UserID & other ) {
00485 d = new Private( other.d->key, other.d->uid );
00486 if ( d->key )
00487 gpgme_key_ref( d->key );
00488 }
00489
00490 UserID::~UserID() {
00491 if ( d->key )
00492 gpgme_key_unref( d->key );
00493 delete d; d = 0;
00494 }
00495
00496 const UserID & UserID::operator=( const UserID & other ) {
00497 if ( &other == this ) return *this;
00498
00499 if ( other.d->key )
00500 gpgme_key_ref( other.d->key );
00501 if ( d->key )
00502 gpgme_key_unref( d->key );
00503 *d = *other.d;
00504 return *this;
00505 }
00506
00507 bool UserID::isNull() const {
00508 return !d || !d->key || !d->uid;
00509 }
00510
00511 Key UserID::parent() const {
00512 return Key( d->key, true );
00513 }
00514
00515 UserID::Signature UserID::signature( unsigned int index ) const {
00516 return Signature( d->key, d->uid, index );
00517 }
00518
00519 unsigned int UserID::numSignatures() const {
00520 if ( !d->uid )
00521 return 0;
00522 unsigned int count = 0;
00523 for ( gpgme_key_sig_t sig = d->uid->signatures ; sig ; sig = sig->next )
00524 ++count;
00525 return count;
00526 }
00527
00528 vector<UserID::Signature> UserID::signatures() const {
00529 if ( !d->uid )
00530 return vector<Signature>();
00531
00532 vector<Signature> v;
00533 v.reserve( numSignatures() );
00534 for ( gpgme_key_sig_t sig = d->uid->signatures ; sig ; sig = sig->next )
00535 v.push_back( Signature( d->key, d->uid, sig ) );
00536 return v;
00537 }
00538
00539 const char * UserID::id() const {
00540 return d->uid ? d->uid->uid : 0 ;
00541 }
00542
00543 const char * UserID::name() const {
00544 return d->uid ? d->uid->name : 0 ;
00545 }
00546
00547 const char * UserID::email() const {
00548 return d->uid ? d->uid->email : 0 ;
00549 }
00550
00551 const char * UserID::comment() const {
00552 return d->uid ? d->uid->comment : 0 ;
00553 }
00554
00555 UserID::Validity UserID::validity() const {
00556 if ( !d->uid )
00557 return Unknown;
00558 switch ( d->uid->validity ) {
00559 default:
00560 case GPGME_VALIDITY_UNKNOWN: return Unknown;
00561 case GPGME_VALIDITY_UNDEFINED: return Undefined;
00562 case GPGME_VALIDITY_NEVER: return Never;
00563 case GPGME_VALIDITY_MARGINAL: return Marginal;
00564 case GPGME_VALIDITY_FULL: return Full;
00565 case GPGME_VALIDITY_ULTIMATE: return Ultimate;
00566 }
00567 }
00568
00569 char UserID::validityAsString() const {
00570 if ( !d->uid )
00571 return '?';
00572 switch ( d->uid->validity ) {
00573 default:
00574 case GPGME_VALIDITY_UNKNOWN: return '?';
00575 case GPGME_VALIDITY_UNDEFINED: return 'q';
00576 case GPGME_VALIDITY_NEVER: return 'n';
00577 case GPGME_VALIDITY_MARGINAL: return 'm';
00578 case GPGME_VALIDITY_FULL: return 'f';
00579 case GPGME_VALIDITY_ULTIMATE: return 'u';
00580 }
00581 }
00582
00583 bool UserID::isRevoked() const {
00584 return d->uid && d->uid->revoked;
00585 }
00586
00587 bool UserID::isInvalid() const {
00588 return d->uid && d->uid->invalid;
00589 }
00590
00591
00592
00593
00594
00595
00596
00597 struct UserID::Signature::Private {
00598 Private( gpgme_key_t aKey, gpgme_user_id_t aUid, unsigned int idx )
00599 : key( aKey ), uid( 0 ), sig( 0 )
00600 {
00601 if ( key )
00602 for ( gpgme_user_id_t u = key->uids ; u ; u = u->next )
00603 if ( u == aUid ) {
00604 uid = u;
00605 for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, --idx )
00606 if ( idx == 0 ) {
00607 sig = s;
00608 break;
00609 }
00610 break;
00611 }
00612 if ( !uid || !sig ) {
00613 uid = 0;
00614 sig = 0;
00615 key = 0;
00616 }
00617 }
00618
00619 Private( gpgme_key_t aKey, gpgme_user_id_t aUid, gpgme_key_sig_t aSig )
00620 : key( aKey ), uid( 0 ), sig( 0 )
00621 {
00622 if ( key )
00623 for ( gpgme_user_id_t u = key->uids ; u ; u = u->next )
00624 if ( u == aUid ) {
00625 uid = u;
00626 for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next )
00627 if ( s == aSig ) {
00628 sig = s;
00629 break;
00630 }
00631 break;
00632 }
00633 if ( !uid || !sig ) {
00634 uid = 0;
00635 sig = 0;
00636 key = 0;
00637 }
00638 }
00639
00640 gpgme_key_t key;
00641 gpgme_user_id_t uid;
00642 gpgme_key_sig_t sig;
00643 };
00644
00645 UserID::Signature::Signature( gpgme_key_t key, gpgme_user_id_t uid, unsigned int idx ) {
00646 d = new Private( key, uid, idx );
00647 if ( d->key )
00648 gpgme_key_ref( d->key );
00649 }
00650
00651 UserID::Signature::Signature( gpgme_key_t key, gpgme_user_id_t uid, gpgme_key_sig_t sig ) {
00652 d = new Private( key, uid, sig );
00653 if ( d->key )
00654 gpgme_key_ref( d->key );
00655 }
00656
00657 UserID::Signature::Signature( const Signature & other ) {
00658 d = new Private( other.d->key, other.d->uid, other.d->sig );
00659 if ( d->key )
00660 gpgme_key_ref( d->key );
00661 }
00662
00663 UserID::Signature::~Signature() {
00664 if ( d->key )
00665 gpgme_key_unref( d->key );
00666 delete d; d = 0;
00667 }
00668
00669 const UserID::Signature & UserID::Signature::operator=( const Signature & other ) {
00670 if ( &other == this ) return *this;
00671
00672 if ( other.d->key )
00673 gpgme_key_ref( other.d->key );
00674 if ( d->key )
00675 gpgme_key_unref( d->key );
00676 *d = *other.d;
00677 return *this;
00678 }
00679
00680 bool UserID::Signature::isNull() const {
00681 return !d || !d->key || !d->uid || !d->sig;
00682 }
00683
00684 UserID UserID::Signature::parent() const {
00685 return UserID( d->key, d->uid );
00686 }
00687
00688 const char * UserID::Signature::signerKeyID() const {
00689 return d->sig ? d->sig->keyid : 0 ;
00690 }
00691
00692 const char * UserID::Signature::algorithmAsString() const {
00693 return gpgme_pubkey_algo_name( d->sig ? d->sig->pubkey_algo : (gpgme_pubkey_algo_t)0 );
00694 }
00695
00696 unsigned int UserID::Signature::algorithm() const {
00697 return d->sig ? d->sig->pubkey_algo : 0 ;
00698 }
00699
00700 time_t UserID::Signature::creationTime() const {
00701 return static_cast<time_t>( d->sig ? d->sig->timestamp : 0 );
00702 }
00703
00704 time_t UserID::Signature::expirationTime() const {
00705 return static_cast<time_t>( d->sig ? d->sig->expires : 0 );
00706 }
00707
00708 bool UserID::Signature::neverExpires() const {
00709 return expirationTime() == time_t(0);
00710 }
00711
00712 bool UserID::Signature::isRevokation() const {
00713 return d->sig && d->sig->revoked;
00714 }
00715
00716 bool UserID::Signature::isInvalid() const {
00717 return d->sig && d->sig->invalid;
00718 }
00719
00720 bool UserID::Signature::isExpired() const {
00721 return d->sig && d->sig->expired;
00722 }
00723
00724 bool UserID::Signature::isExportable() const {
00725 return d->sig && d->sig->exportable;
00726 }
00727
00728 const char * UserID::Signature::signerUserID() const {
00729 return d->sig ? d->sig->uid : 0 ;
00730 }
00731
00732 const char * UserID::Signature::signerName() const {
00733 return d->sig ? d->sig->name : 0 ;
00734 }
00735
00736 const char * UserID::Signature::signerEmail() const {
00737 return d->sig ? d->sig->email : 0 ;
00738 }
00739
00740 const char * UserID::Signature::signerComment() const {
00741 return d->sig ? d->sig->comment : 0 ;
00742 }
00743
00744 unsigned int UserID::Signature::certClass() const {
00745 return d->sig ? d->sig->sig_class : 0 ;
00746 }
00747
00748 UserID::Signature::Status UserID::Signature::status() const {
00749 if ( !d->sig )
00750 return GeneralError;
00751 switch ( d->sig->status ) {
00752 case GPG_ERR_NO_ERROR: return NoError;
00753 case GPG_ERR_SIG_EXPIRED: return SigExpired;
00754 case GPG_ERR_KEY_EXPIRED: return KeyExpired;
00755 case GPG_ERR_BAD_SIGNATURE: return BadSignature;
00756 case GPG_ERR_NO_PUBKEY: return NoPublicKey;
00757 default:
00758 case GPG_ERR_GENERAL: return GeneralError;
00759 }
00760 }
00761
00762 const char * UserID::Signature::statusAsString() const {
00763 return d->sig ? gpgme_strerror( d->sig->status ) : 0 ;
00764 }
00765
00766 UserID::Signature::Notation UserID::Signature::notation( unsigned int idx ) const {
00767 return Notation( d->key, d->uid, d->sig, idx );
00768 }
00769
00770 unsigned int UserID::Signature::numNotations() const {
00771 if ( !d->sig )
00772 return 0;
00773 unsigned int count = 0;
00774 #ifdef HAVE_GPGME_KEY_SIG_NOTATIONS
00775 for ( gpgme_sig_notation_t nota = d->sig->notations ; nota ; nota = nota->next )
00776 if ( nota->name ) ++count;
00777 #endif
00778 return count;
00779 }
00780
00781 vector<UserID::Signature::Notation> UserID::Signature::notations() const {
00782 if ( !d->sig )
00783 return vector<Notation>();
00784 vector<Notation> v;
00785 #ifdef HAVE_GPGME_KEY_SIG_NOTATIONS
00786 v.reserve( numNotations() );
00787 for ( gpgme_sig_notation_t nota = d->sig->notations ; nota ; nota = nota->next )
00788 if ( nota->name )
00789 v.push_back( Notation( d->key, d->uid, d->sig, nota ) );
00790 #endif
00791 return v;
00792 }
00793
00794 const char * UserID::Signature::policyURL() const {
00795 #ifdef HAVE_GPGME_KEY_SIG_NOTATIONS
00796 if ( !d->sig )
00797 return 0;
00798 for ( gpgme_sig_notation_t nota = d->sig->notations ; nota ; nota = nota->next )
00799 if ( !nota->name )
00800 return nota->value;
00801 #endif
00802 return 0;
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 struct UserID::Signature::Notation::Private {
00814 Private( gpgme_key_t aKey, gpgme_user_id_t aUid,
00815 gpgme_key_sig_t aSig, unsigned int idx )
00816 : key( aKey ), uid( 0 ), sig( 0 ), nota( 0 )
00817 {
00818 if ( key )
00819 for ( gpgme_user_id_t u = key->uids ; u ; u = u->next )
00820 if ( u == aUid ) {
00821 uid = u;
00822 for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next )
00823 if ( s == aSig ) {
00824 sig = s;
00825 #ifdef HAVE_GPGME_KEY_SIG_NOTATIONS
00826 for ( gpgme_sig_notation_t n = sig->notations ; n ; n = n->next, --idx )
00827 if ( n == aNota ) {
00828 nota = n;
00829 break;
00830 }
00831 #else
00832 (void)idx;
00833 #endif
00834 break;
00835 }
00836 break;
00837 }
00838 if ( !uid || !sig || !nota ) {
00839 uid = 0;
00840 sig = 0;
00841 key = 0;
00842 nota = 0;
00843 }
00844 }
00845
00846 Private( gpgme_key_t aKey, gpgme_user_id_t aUid,
00847 gpgme_key_sig_t aSig, gpgme_sig_notation_t aNota )
00848 : key( aKey ), uid( 0 ), sig( 0 ), nota( 0 )
00849 {
00850 if ( key )
00851 for ( gpgme_user_id_t u = key->uids ; u ; u = u->next )
00852 if ( u == aUid ) {
00853 uid = u;
00854 for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next )
00855 if ( s == aSig ) {
00856 sig = s;
00857 #ifdef HAVE_GPGME_KEY_SIG_NOTATIONS
00858 for ( gpgme_sig_notation_t n = sig->notations ; n ; n = n->next )
00859 if ( n == aNota ) {
00860 nota = n;
00861 break;
00862 }
00863 #else
00864 (void)aNota;
00865 #endif
00866 break;
00867 }
00868 break;
00869 }
00870 if ( !uid || !sig || !nota ) {
00871 uid = 0;
00872 sig = 0;
00873 key = 0;
00874 nota = 0;
00875 }
00876 }
00877
00878 gpgme_key_t key;
00879 gpgme_user_id_t uid;
00880 gpgme_key_sig_t sig;
00881 gpgme_sig_notation_t nota;
00882 };
00883
00884 UserID::Signature::Notation::Notation( gpgme_key_t key, gpgme_user_id_t uid,
00885 gpgme_key_sig_t sig, unsigned int idx ) {
00886 d = new Private( key, uid, sig, idx );
00887 if ( d->key )
00888 gpgme_key_ref( d->key );
00889 }
00890
00891 UserID::Signature::Notation::Notation( gpgme_key_t key, gpgme_user_id_t uid,
00892 gpgme_key_sig_t sig, gpgme_sig_notation_t nota ) {
00893 d = new Private( key, uid, sig, nota );
00894 if ( d->key )
00895 gpgme_key_ref( d->key );
00896 }
00897
00898 UserID::Signature::Notation::Notation( const Notation & other ) {
00899 d = new Private( other.d->key, other.d->uid, other.d->sig, other.d->nota );
00900 if ( d->key )
00901 gpgme_key_ref( d->key );
00902 }
00903
00904 UserID::Signature::Notation::~Notation() {
00905 if ( d->key )
00906 gpgme_key_unref( d->key );
00907 delete d; d = 0;
00908 }
00909
00910 const UserID::Signature::Notation & UserID::Signature::Notation::operator=( const Notation & other ) {
00911 if ( &other == this ) return *this;
00912
00913 if ( other.d->key )
00914 gpgme_key_ref( other.d->key );
00915 if ( d->key )
00916 gpgme_key_unref( d->key );
00917 *d = *other.d;
00918 return *this;
00919 }
00920
00921 bool UserID::Signature::Notation::isNull() const {
00922 return !d || !d->key || !d->uid || !d->sig || !d->nota;
00923 }
00924
00925 UserID::Signature UserID::Signature::Notation::parent() const {
00926 return Signature( d->key, d->uid, d->sig );
00927 }
00928
00929 const char * UserID::Signature::Notation::name() const {
00930 return d->nota ? d->nota->name : 0 ;
00931 }
00932
00933 const char * UserID::Signature::Notation::value() const {
00934 return d->nota ? d->nota->value : 0 ;
00935 }
00936
00937 }