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