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/context.h>
00025 #include <gpgmepp/eventloopinteractor.h>
00026 #include <gpgmepp/trustitem.h>
00027 #include <gpgmepp/keylistresult.h>
00028 #include <gpgmepp/keygenerationresult.h>
00029 #include <gpgmepp/importresult.h>
00030 #include <gpgmepp/decryptionresult.h>
00031 #include <gpgmepp/verificationresult.h>
00032 #include <gpgmepp/signingresult.h>
00033 #include <gpgmepp/encryptionresult.h>
00034 #include <gpgmepp/engineinfo.h>
00035
00036 #include "callbacks.h"
00037 #include "data_p.h"
00038 #include "context_p.h"
00039 #include "util.h"
00040
00041 #include <gpgme.h>
00042
00043
00044
00045 #ifndef NDEBUG
00046 #include <iostream>
00047 using std::cerr;
00048 using std::endl;
00049 #endif
00050
00051 #include <cassert>
00052
00053 namespace GpgME {
00054
00055 const char * Error::source() const {
00056 return gpgme_strsource( (gpgme_error_t)mErr );
00057 }
00058
00059 const char * Error::asString() const {
00060 return gpgme_strerror( (gpgme_error_t)mErr );
00061 }
00062
00063 int Error::code() const {
00064 return gpgme_err_code( mErr );
00065 }
00066
00067 int Error::sourceID() const {
00068 return gpgme_err_source( mErr );
00069 }
00070
00071 bool Error::isCanceled() const {
00072 return code() == GPG_ERR_CANCELED;
00073 }
00074
00075 Context::Context( gpgme_ctx_t ctx ) {
00076 d = new Private( ctx );
00077 }
00078
00079 Context::~Context() {
00080 delete d; d = 0;
00081 }
00082
00083 Context * Context::createForProtocol( Protocol proto ) {
00084 gpgme_ctx_t ctx = 0;
00085 if ( gpgme_new ( &ctx ) != 0 )
00086 return 0;
00087
00088 switch ( proto ) {
00089 case OpenPGP:
00090 if ( gpgme_set_protocol( ctx, GPGME_PROTOCOL_OpenPGP ) != 0 ) {
00091 gpgme_release( ctx );
00092 return 0;
00093 }
00094 break;
00095 case CMS:
00096 if ( gpgme_set_protocol( ctx, GPGME_PROTOCOL_CMS ) != 0 ) {
00097 gpgme_release( ctx );
00098 return 0;
00099 }
00100 break;
00101 default:
00102 return 0;
00103 }
00104
00105 return new Context( ctx );
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 Context::Protocol Context::protocol() const {
00115 gpgme_protocol_t p = gpgme_get_protocol( d->ctx );
00116 switch ( p ) {
00117 case GPGME_PROTOCOL_OpenPGP: return OpenPGP;
00118 case GPGME_PROTOCOL_CMS: return CMS;
00119 default: return Unknown;
00120 }
00121 }
00122
00123
00124 void Context::setArmor( bool useArmor ) {
00125 gpgme_set_armor( d->ctx, int( useArmor ) );
00126 }
00127 bool Context::armor() const {
00128 return gpgme_get_armor( d->ctx );
00129 }
00130
00131 void Context::setTextMode( bool useTextMode ) {
00132 gpgme_set_textmode( d->ctx, int( useTextMode ) );
00133 }
00134 bool Context::textMode() const {
00135 return gpgme_get_textmode( d->ctx );
00136 }
00137
00138 void Context::setIncludeCertificates( int which ) {
00139 if ( which == DefaultCertificates ) {
00140 #ifdef HAVE_GPGME_INCLUDE_CERTS_DEFAULT
00141 which = GPGME_INCLUDE_CERTS_DEFAULT;
00142 #else
00143 which = 1;
00144 #endif
00145 }
00146 gpgme_set_include_certs( d->ctx, which );
00147 }
00148
00149 int Context::includeCertificates() const {
00150 return gpgme_get_include_certs( d->ctx );
00151 }
00152
00153 void Context::setKeyListMode( unsigned int mode ) {
00154 gpgme_set_keylist_mode( d->ctx, add_to_gpgme_keylist_mode_t( 0, mode ) );
00155 }
00156
00157 void Context::addKeyListMode( unsigned int mode ) {
00158 const unsigned int cur = gpgme_get_keylist_mode( d->ctx );
00159 gpgme_set_keylist_mode( d->ctx, add_to_gpgme_keylist_mode_t( cur, mode ) );
00160 }
00161
00162
00163 unsigned int Context::keyListMode() const {
00164 return convert_from_gpgme_keylist_mode_t( gpgme_get_keylist_mode( d->ctx ) );
00165 }
00166
00167 void Context::setProgressProvider( ProgressProvider * provider ) {
00168 gpgme_set_progress_cb( d->ctx, provider ? &progress_callback : 0, provider );
00169 }
00170 ProgressProvider * Context::progressProvider() const {
00171 void * pp = 0;
00172 gpgme_progress_cb_t pcb = &progress_callback;
00173 gpgme_get_progress_cb( d->ctx, &pcb, &pp );
00174 return static_cast<ProgressProvider*>( pp );
00175 }
00176
00177 void Context::setPassphraseProvider( PassphraseProvider * provider ) {
00178 gpgme_set_passphrase_cb( d->ctx, provider ? &passphrase_callback : 0, provider );
00179 }
00180
00181 PassphraseProvider * Context::passphraseProvider() const {
00182 void * pp = 0;
00183 gpgme_passphrase_cb_t pcb = &passphrase_callback;
00184 gpgme_get_passphrase_cb( d->ctx, &pcb, &pp );
00185 return static_cast<PassphraseProvider*>( pp );
00186 }
00187
00188 void Context::setManagedByEventLoopInteractor( bool manage ) {
00189 if ( !EventLoopInteractor::instance() ) {
00190 #ifndef NDEBUG
00191 cerr << "Context::setManagedByEventLoopInteractor(): "
00192 "You must create an instance of EventLoopInteractor "
00193 "before using anything that needs one." << endl;
00194 #endif
00195 return;
00196 }
00197 if ( manage )
00198 EventLoopInteractor::instance()->manage( this );
00199 else
00200 EventLoopInteractor::instance()->unmanage( this );
00201 }
00202 bool Context::managedByEventLoopInteractor() const {
00203 return d->iocbs != 0;
00204 }
00205
00206
00207 void Context::installIOCallbacks( gpgme_io_cbs * iocbs ) {
00208 if ( !iocbs ) {
00209 uninstallIOCallbacks();
00210 return;
00211 }
00212 gpgme_set_io_cbs( d->ctx, iocbs );
00213 delete d->iocbs; d->iocbs = iocbs;
00214 }
00215
00216 void Context::uninstallIOCallbacks() {
00217 static gpgme_io_cbs noiocbs = { 0, 0, 0, 0, 0 };
00218
00219 gpgme_set_io_cbs( d->ctx, &noiocbs );
00220 delete d->iocbs; d->iocbs = 0;
00221 }
00222
00223 Error Context::setLocale( int cat, const char * val ) {
00224 return d->lasterr = gpgme_set_locale( d->ctx, cat, val );
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 Error Context::startKeyListing( const char * pattern, bool secretOnly ) {
00234 d->lastop = Private::KeyList;
00235 return d->lasterr = gpgme_op_keylist_start( d->ctx, pattern, int( secretOnly ) );
00236 }
00237
00238 Error Context::startKeyListing( const char * patterns[], bool secretOnly ) {
00239 d->lastop = Private::KeyList;
00240 return d->lasterr = gpgme_op_keylist_ext_start( d->ctx, patterns, int( secretOnly ), 0 );
00241 }
00242
00243 Key Context::nextKey( GpgME::Error & e ) {
00244 d->lastop = Private::KeyList;
00245 gpgme_key_t key;
00246 e = d->lasterr = gpgme_op_keylist_next( d->ctx, &key );
00247 return Key( key, false, keyListMode() );
00248 }
00249
00250 KeyListResult Context::endKeyListing() {
00251 d->lasterr = gpgme_op_keylist_end( d->ctx );
00252 return keyListResult();
00253 }
00254
00255 KeyListResult Context::keyListResult() const {
00256 return KeyListResult( d->ctx, d->lasterr );
00257 }
00258
00259 Key Context::key( const char * fingerprint, GpgME::Error & e , bool secret ) {
00260 d->lastop = Private::KeyList;
00261 gpgme_key_t key;
00262 e = d->lasterr = gpgme_get_key( d->ctx, fingerprint, &key, int( secret ) );
00263 return Key( key, false, keyListMode() );
00264 }
00265
00266 KeyGenerationResult Context::generateKey( const char * parameters, Data & pubKey ) {
00267 d->lastop = Private::KeyGen;
00268 Data::Private * dp = pubKey.impl();
00269 d->lasterr = gpgme_op_genkey( d->ctx, parameters, dp ? dp->data : 0, 0 );
00270 return KeyGenerationResult( d->ctx, d->lasterr );
00271 }
00272
00273 Error Context::startKeyGeneration( const char * parameters, Data & pubKey ) {
00274 d->lastop = Private::KeyGen;
00275 Data::Private * dp = pubKey.impl();
00276 return d->lasterr = gpgme_op_genkey_start( d->ctx, parameters, dp ? dp->data : 0, 0 );
00277 }
00278
00279 KeyGenerationResult Context::keyGenerationResult() const {
00280 if ( d->lastop & Private::KeyGen )
00281 return KeyGenerationResult( d->ctx, d->lasterr );
00282 else
00283 return KeyGenerationResult();
00284 }
00285
00286 Error Context::exportPublicKeys( const char * pattern, Data & keyData ) {
00287 d->lastop = Private::Export;
00288 Data::Private * dp = keyData.impl();
00289 return d->lasterr = gpgme_op_export( d->ctx, pattern, 0, dp ? dp->data : 0 );
00290 }
00291
00292 Error Context::exportPublicKeys( const char * patterns[], Data & keyData ) {
00293 d->lastop = Private::Export;
00294 Data::Private * dp = keyData.impl();
00295 return d->lasterr = gpgme_op_export_ext( d->ctx, patterns, 0, dp ? dp->data : 0 );
00296 }
00297
00298 Error Context::startPublicKeyExport( const char * pattern, Data & keyData ) {
00299 d->lastop = Private::Export;
00300 Data::Private * dp = keyData.impl();
00301 return d->lasterr = gpgme_op_export_start( d->ctx, pattern, 0, dp ? dp->data : 0 );
00302 }
00303
00304 Error Context::startPublicKeyExport( const char * patterns[], Data & keyData ) {
00305 d->lastop = Private::Export;
00306 Data::Private * dp = keyData.impl();
00307 return d->lasterr = gpgme_op_export_ext_start( d->ctx, patterns, 0, dp ? dp->data : 0 );
00308 }
00309
00310
00311 ImportResult Context::importKeys( const Data & data ) {
00312 d->lastop = Private::Import;
00313 Data::Private * dp = data.impl();
00314 d->lasterr = gpgme_op_import( d->ctx, dp ? dp->data : 0 );
00315 return ImportResult( d->ctx, d->lasterr );
00316 }
00317
00318 Error Context::startKeyImport( const Data & data ) {
00319 d->lastop = Private::Import;
00320 Data::Private * dp = data.impl();
00321 return d->lasterr = gpgme_op_import_start( d->ctx, dp ? dp->data : 0 );
00322 }
00323
00324 ImportResult Context::importResult() const {
00325 if ( d->lastop & Private::Import )
00326 return ImportResult( d->ctx, d->lasterr );
00327 else
00328 return ImportResult();
00329 }
00330
00331 Error Context::deleteKey( const Key & key, bool allowSecretKeyDeletion ) {
00332 d->lastop = Private::Delete;
00333 return d->lasterr = gpgme_op_delete( d->ctx, key.impl(), int( allowSecretKeyDeletion ) );
00334 }
00335
00336 Error Context::startKeyDeletion( const Key & key, bool allowSecretKeyDeletion ) {
00337 d->lastop = Private::Delete;
00338 return d->lasterr = gpgme_op_delete_start( d->ctx, key.impl(), int( allowSecretKeyDeletion ) );
00339 }
00340
00341 Error Context::startTrustItemListing( const char * pattern, int maxLevel ) {
00342 d->lastop = Private::TrustList;
00343 return d->lasterr = gpgme_op_trustlist_start( d->ctx, pattern, maxLevel );
00344 }
00345
00346 TrustItem Context::nextTrustItem( Error & e ) {
00347 gpgme_trust_item_t ti = 0;
00348 e = d->lasterr = gpgme_op_trustlist_next( d->ctx, &ti );
00349 return ti;
00350 }
00351
00352 Error Context::endTrustItemListing() {
00353 return d->lasterr = gpgme_op_trustlist_end( d->ctx );
00354 }
00355
00356 DecryptionResult Context::decrypt( const Data & cipherText, Data & plainText ) {
00357 d->lastop = Private::Decrypt;
00358 Data::Private * cdp = cipherText.impl();
00359 Data::Private * pdp = plainText.impl();
00360 d->lasterr = gpgme_op_decrypt( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 );
00361 return DecryptionResult( d->ctx, d->lasterr );
00362 }
00363
00364 Error Context::startDecryption( const Data & cipherText, Data & plainText ) {
00365 d->lastop = Private::Decrypt;
00366 Data::Private * cdp = cipherText.impl();
00367 Data::Private * pdp = plainText.impl();
00368 return d->lasterr = gpgme_op_decrypt_start( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 );
00369 }
00370
00371 DecryptionResult Context::decryptionResult() const {
00372 if ( d->lastop & Private::Decrypt )
00373 return DecryptionResult( d->ctx, d->lasterr );
00374 else
00375 return DecryptionResult();
00376 }
00377
00378
00379
00380 VerificationResult Context::verifyDetachedSignature( const Data & signature, const Data & signedText ) {
00381 d->lastop = Private::Verify;
00382 Data::Private * sdp = signature.impl();
00383 Data::Private * tdp = signedText.impl();
00384 d->lasterr = gpgme_op_verify( d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0 );
00385 return VerificationResult( d->ctx, d->lasterr );
00386 }
00387
00388 VerificationResult Context::verifyOpaqueSignature( const Data & signedData, Data & plainText ) {
00389 d->lastop = Private::Verify;
00390 Data::Private * sdp = signedData.impl();
00391 Data::Private * pdp = plainText.impl();
00392 d->lasterr = gpgme_op_verify( d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0 );
00393 return VerificationResult( d->ctx, d->lasterr );
00394 }
00395
00396 Error Context::startDetachedSignatureVerification( const Data & signature, const Data & signedText ) {
00397 d->lastop = Private::Verify;
00398 Data::Private * sdp = signature.impl();
00399 Data::Private * tdp = signedText.impl();
00400 return d->lasterr = gpgme_op_verify_start( d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0 );
00401 }
00402
00403 Error Context::startOpaqueSignatureVerification( const Data & signedData, Data & plainText ) {
00404 d->lastop = Private::Verify;
00405 Data::Private * sdp = signedData.impl();
00406 Data::Private * pdp = plainText.impl();
00407 return d->lasterr = gpgme_op_verify_start( d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0 );
00408 }
00409
00410 VerificationResult Context::verificationResult() const {
00411 if ( d->lastop & Private::Verify )
00412 return VerificationResult( d->ctx, d->lasterr );
00413 else
00414 return VerificationResult();
00415 }
00416
00417
00418 std::pair<DecryptionResult,VerificationResult> Context::decryptAndVerify( const Data & cipherText, Data & plainText ) {
00419 d->lastop = Private::DecryptAndVerify;
00420 Data::Private * cdp = cipherText.impl();
00421 Data::Private * pdp = plainText.impl();
00422 d->lasterr = gpgme_op_decrypt_verify( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 );
00423 return std::make_pair( DecryptionResult( d->ctx, d->lasterr ),
00424 VerificationResult( d->ctx, d->lasterr ) );
00425 }
00426
00427 Error Context::startCombinedDecryptionAndVerification( const Data & cipherText, Data & plainText ) {
00428 d->lastop = Private::DecryptAndVerify;
00429 Data::Private * cdp = cipherText.impl();
00430 Data::Private * pdp = plainText.impl();
00431 return d->lasterr = gpgme_op_decrypt_verify_start( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 );
00432 }
00433
00434
00435
00436
00437 void Context::clearSigningKeys() {
00438 gpgme_signers_clear( d->ctx );
00439 }
00440
00441 Error Context::addSigningKey( const Key & key ) {
00442 return d->lasterr = gpgme_signers_add( d->ctx, key.impl() );
00443 }
00444
00445 Key Context::signingKey( unsigned int idx ) const {
00446 gpgme_key_t key = gpgme_signers_enum( d->ctx, idx );
00447 return Key( key, false, keyListMode() );
00448 }
00449
00450
00451 static gpgme_sig_mode_t sigmode2sigmode( Context::SignatureMode mode ) {
00452 switch ( mode ) {
00453 default:
00454 case Context::Normal: return GPGME_SIG_MODE_NORMAL;
00455 case Context::Detached: return GPGME_SIG_MODE_DETACH;
00456 case Context::Clearsigned: return GPGME_SIG_MODE_CLEAR;
00457 }
00458 }
00459
00460 SigningResult Context::sign( const Data & plainText, Data & signature, SignatureMode mode ) {
00461 d->lastop = Private::Sign;
00462 Data::Private * pdp = plainText.impl();
00463 Data::Private * sdp = signature.impl();
00464 d->lasterr = gpgme_op_sign( d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode( mode ) );
00465 return SigningResult( d->ctx, d->lasterr );
00466 }
00467
00468
00469 Error Context::startSigning( const Data & plainText, Data & signature, SignatureMode mode ) {
00470 d->lastop = Private::Sign;
00471 Data::Private * pdp = plainText.impl();
00472 Data::Private * sdp = signature.impl();
00473 return d->lasterr = gpgme_op_sign_start( d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode( mode ) );
00474 }
00475
00476 SigningResult Context::signingResult() const {
00477 if ( d->lastop & Private::Sign )
00478 return SigningResult( d->ctx, d->lasterr );
00479 else
00480 return SigningResult();
00481 }
00482
00483
00484 EncryptionResult Context::encrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
00485 d->lastop = Private::Encrypt;
00486 Data::Private * pdp = plainText.impl();
00487 Data::Private * cdp = cipherText.impl();
00488 gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ];
00489 gpgme_key_t * keys_it = keys;
00490 for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
00491 if ( it->impl() )
00492 *keys_it++ = it->impl();
00493 *keys_it++ = 0;
00494 d->lasterr = gpgme_op_encrypt( d->ctx, keys,
00495 flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
00496 pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
00497 delete[] keys;
00498 return EncryptionResult( d->ctx, d->lasterr );
00499 }
00500
00501 Error Context::encryptSymmetrically( const Data & plainText, Data & cipherText ) {
00502 d->lastop = Private::Encrypt;
00503 Data::Private * pdp = plainText.impl();
00504 Data::Private * cdp = cipherText.impl();
00505 return d->lasterr = gpgme_op_encrypt( d->ctx, 0, (gpgme_encrypt_flags_t)0,
00506 pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
00507 }
00508
00509 Error Context::startEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
00510 d->lastop = Private::Encrypt;
00511 Data::Private * pdp = plainText.impl();
00512 Data::Private * cdp = cipherText.impl();
00513 gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ];
00514 gpgme_key_t * keys_it = keys;
00515 for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
00516 if ( it->impl() )
00517 *keys_it++ = it->impl();
00518 *keys_it++ = 0;
00519 d->lasterr = gpgme_op_encrypt_start( d->ctx, keys,
00520 flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
00521 pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
00522 delete[] keys;
00523 return d->lasterr;
00524 }
00525
00526 EncryptionResult Context::encryptionResult() const {
00527 if ( d->lastop & Private::Encrypt )
00528 return EncryptionResult( d->ctx, d->lasterr );
00529 else
00530 return EncryptionResult();
00531 }
00532
00533 std::pair<SigningResult,EncryptionResult> Context::signAndEncrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
00534 d->lastop = Private::SignAndEncrypt;
00535 Data::Private * pdp = plainText.impl();
00536 Data::Private * cdp = cipherText.impl();
00537 gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ];
00538 gpgme_key_t * keys_it = keys;
00539 for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
00540 if ( it->impl() )
00541 *keys_it++ = it->impl();
00542 *keys_it++ = 0;
00543 d->lasterr = gpgme_op_encrypt_sign( d->ctx, keys,
00544 flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
00545 pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
00546 delete[] keys;
00547 return std::make_pair( SigningResult( d->ctx, d->lasterr ),
00548 EncryptionResult( d->ctx, d->lasterr ) );
00549 }
00550
00551 Error Context::startCombinedSigningAndEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
00552 d->lastop = Private::SignAndEncrypt;
00553 Data::Private * pdp = plainText.impl();
00554 Data::Private * cdp = cipherText.impl();
00555 gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ];
00556 gpgme_key_t * keys_it = keys;
00557 for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
00558 if ( it->impl() )
00559 *keys_it++ = it->impl();
00560 *keys_it++ = 0;
00561 d->lasterr = gpgme_op_encrypt_sign_start( d->ctx, keys,
00562 flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
00563 pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
00564 delete[] keys;
00565 return d->lasterr;
00566 }
00567
00568
00569 Error Context::cancelPendingOperation() {
00570 #ifdef HAVE_GPGME_CANCEL
00571 return gpgme_cancel( d->ctx );
00572 #else
00573 return 0;
00574 #endif
00575 }
00576
00577 bool Context::poll() {
00578 gpgme_error_t e = GPG_ERR_NO_ERROR;
00579 const bool finished = gpgme_wait( d->ctx, &e, 0 );
00580 if ( finished )
00581 d->lasterr = e;
00582 return finished;
00583 }
00584
00585 Error Context::wait() {
00586 gpgme_error_t e = GPG_ERR_NO_ERROR;
00587 gpgme_wait( d->ctx, &e, 1 );
00588 return d->lasterr = e;
00589 }
00590
00591 Error Context::lastError() const {
00592 return d->lasterr;
00593 }
00594
00595
00596 }
00597
00598 GpgME::Error GpgME::setDefaultLocale( int cat, const char * val ) {
00599 return gpgme_set_locale( 0, cat, val );
00600 }
00601
00602 GpgME::EngineInfo GpgME::engineInfo( Context::Protocol proto ) {
00603 gpgme_engine_info_t ei = 0;
00604 if ( gpgme_get_engine_info( &ei ) )
00605 return EngineInfo();
00606
00607 gpgme_protocol_t p = proto == Context::CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ;
00608
00609 for ( gpgme_engine_info_t i = ei ; i ; i = i->next )
00610 if ( i->protocol == p )
00611 return EngineInfo( i );
00612
00613 return EngineInfo();
00614 }
00615
00616 GpgME::Error GpgME::checkEngine( Context::Protocol proto ) {
00617 gpgme_protocol_t p = proto == Context::CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ;
00618
00619 return gpgme_engine_check_version( p );
00620 }
00621