Blame lang/cpp/src/context.cpp

Packit d7e8d0
/*
Packit d7e8d0
  context.cpp - wraps a gpgme key context
Packit d7e8d0
  Copyright (C) 2003, 2007 Klarälvdalens Datakonsult AB
Packit d7e8d0
Packit d7e8d0
  This file is part of GPGME++.
Packit d7e8d0
Packit d7e8d0
  GPGME++ is free software; you can redistribute it and/or
Packit d7e8d0
  modify it under the terms of the GNU Library General Public
Packit d7e8d0
  License as published by the Free Software Foundation; either
Packit d7e8d0
  version 2 of the License, or (at your option) any later version.
Packit d7e8d0
Packit d7e8d0
  GPGME++ is distributed in the hope that it will be useful,
Packit d7e8d0
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d7e8d0
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit d7e8d0
  GNU Library General Public License for more details.
Packit d7e8d0
Packit d7e8d0
  You should have received a copy of the GNU Library General Public License
Packit d7e8d0
  along with GPGME++; see the file COPYING.LIB.  If not, write to the
Packit d7e8d0
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d7e8d0
  Boston, MA 02110-1301, USA.
Packit d7e8d0
*/
Packit d7e8d0
Packit d7e8d0
#ifdef HAVE_CONFIG_H
Packit d7e8d0
 #include "config.h"
Packit d7e8d0
#endif
Packit d7e8d0
Packit d7e8d0
#include <context.h>
Packit d7e8d0
#include <eventloopinteractor.h>
Packit d7e8d0
#include <trustitem.h>
Packit d7e8d0
#include <keylistresult.h>
Packit d7e8d0
#include <keygenerationresult.h>
Packit d7e8d0
#include <importresult.h>
Packit d7e8d0
#include <decryptionresult.h>
Packit d7e8d0
#include <verificationresult.h>
Packit d7e8d0
#include <signingresult.h>
Packit d7e8d0
#include <encryptionresult.h>
Packit d7e8d0
#include <engineinfo.h>
Packit d7e8d0
#include <editinteractor.h>
Packit d7e8d0
#include <vfsmountresult.h>
Packit d7e8d0
Packit d7e8d0
#include <interfaces/assuantransaction.h>
Packit d7e8d0
#include <defaultassuantransaction.h>
Packit d7e8d0
Packit d7e8d0
#include "callbacks.h"
Packit d7e8d0
#include "data_p.h"
Packit d7e8d0
#include "context_p.h"
Packit d7e8d0
#include "util.h"
Packit d7e8d0
#include "tofuinfo.h"
Packit d7e8d0
Packit d7e8d0
#include <gpgme.h>
Packit d7e8d0
Packit d7e8d0
#include <istream>
Packit d7e8d0
#ifndef NDEBUG
Packit d7e8d0
#include <iostream>
Packit d7e8d0
using std::cerr;
Packit d7e8d0
using std::endl;
Packit d7e8d0
#endif
Packit d7e8d0
Packit d7e8d0
#include <cassert>
Packit d7e8d0
Packit d7e8d0
namespace GpgME
Packit d7e8d0
{
Packit d7e8d0
Packit d7e8d0
static inline unsigned int xtoi_1(const char *str)
Packit d7e8d0
{
Packit d7e8d0
    const unsigned int ch = *str;
Packit d7e8d0
    const unsigned int result =
Packit d7e8d0
        ch <= '9' ? ch - '0' :
Packit d7e8d0
        ch <= 'F' ? ch - 'A' + 10 :
Packit d7e8d0
        /* else */  ch - 'a' + 10 ;
Packit d7e8d0
    return result < 16 ? result : 0 ;
Packit d7e8d0
}
Packit d7e8d0
static inline int xtoi_2(const char *str)
Packit d7e8d0
{
Packit d7e8d0
    return xtoi_1(str) * 16U + xtoi_1(str + 1);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static void percent_unescape(std::string &s, bool plus2space)
Packit d7e8d0
{
Packit d7e8d0
    std::string::iterator src = s.begin(), dest = s.begin(), end = s.end();
Packit d7e8d0
    while (src != end) {
Packit d7e8d0
        if (*src == '%' && end - src > 2) {
Packit d7e8d0
            *dest++ = xtoi_2(&*++src);
Packit d7e8d0
            src += 2;
Packit d7e8d0
        } else if (*src == '+' && plus2space) {
Packit d7e8d0
            *dest++ = ' ';
Packit d7e8d0
            ++src;
Packit d7e8d0
        } else {
Packit d7e8d0
            *dest++ = *src++;
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    s.erase(dest, end);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void initializeLibrary()
Packit d7e8d0
{
Packit d7e8d0
    gpgme_check_version(0);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error initializeLibrary(int)
Packit d7e8d0
{
Packit d7e8d0
    if (gpgme_check_version(GPGME_VERSION)) {
Packit d7e8d0
        return Error();
Packit d7e8d0
    } else {
Packit d7e8d0
        return Error::fromCode(GPG_ERR_USER_1);
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static void format_error(gpgme_error_t err, std::string &str)
Packit d7e8d0
{
Packit d7e8d0
    char buffer[ 1024 ];
Packit d7e8d0
    gpgme_strerror_r(err, buffer, sizeof buffer);
Packit d7e8d0
    buffer[ sizeof buffer - 1 ] = '\0';
Packit d7e8d0
    str = buffer;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *Error::source() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_strsource((gpgme_error_t)mErr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *Error::asString() const
Packit d7e8d0
{
Packit d7e8d0
    if (mMessage.empty()) {
Packit d7e8d0
        format_error(static_cast<gpgme_error_t>(mErr), mMessage);
Packit d7e8d0
    }
Packit d7e8d0
    return mMessage.c_str();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
int Error::code() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_err_code(mErr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
int Error::sourceID() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_err_source(mErr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
bool Error::isCanceled() const
Packit d7e8d0
{
Packit d7e8d0
    return code() == GPG_ERR_CANCELED;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
int Error::toErrno() const
Packit d7e8d0
{
Packit d7e8d0
//#ifdef HAVE_GPGME_GPG_ERROR_WRAPPERS
Packit d7e8d0
    return gpgme_err_code_to_errno(static_cast<gpgme_err_code_t>(code()));
Packit d7e8d0
//#else
Packit d7e8d0
//    return gpg_err_code_to_errno( static_cast<gpg_err_code_t>( code() ) );
Packit d7e8d0
//#endif
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// static
Packit d7e8d0
bool Error::hasSystemError()
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_err_code_from_syserror() == GPG_ERR_MISSING_ERRNO ;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// static
Packit d7e8d0
void Error::setSystemError(gpg_err_code_t err)
Packit d7e8d0
{
Packit d7e8d0
    setErrno(gpgme_err_code_to_errno(err));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// static
Packit d7e8d0
void Error::setErrno(int err)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_err_set_errno(err);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// static
Packit d7e8d0
Error Error::fromSystemError(unsigned int src)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_err_make(static_cast<gpgme_err_source_t>(src), gpgme_err_code_from_syserror()));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// static
Packit d7e8d0
Error Error::fromErrno(int err, unsigned int src)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_err_make(static_cast<gpgme_err_source_t>(src), gpgme_err_code_from_errno(err)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// static
Packit d7e8d0
Error Error::fromCode(unsigned int err, unsigned int src)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_err_make(static_cast<gpgme_err_source_t>(src), static_cast<gpgme_err_code_t>(err)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, const Error &err)
Packit d7e8d0
{
Packit d7e8d0
    return os << "GpgME::Error(" << err.encodedError() << " (" << err.asString() << "))";
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Context::Context(gpgme_ctx_t ctx) : d(new Private(ctx))
Packit d7e8d0
{
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Context::~Context()
Packit d7e8d0
{
Packit d7e8d0
    delete d;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Context *Context::createForProtocol(Protocol proto)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_ctx_t ctx = 0;
Packit d7e8d0
    if (gpgme_new(&ctx) != 0) {
Packit d7e8d0
        return 0;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    switch (proto) {
Packit d7e8d0
    case OpenPGP:
Packit d7e8d0
        if (gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP) != 0) {
Packit d7e8d0
            gpgme_release(ctx);
Packit d7e8d0
            return 0;
Packit d7e8d0
        }
Packit d7e8d0
        break;
Packit d7e8d0
    case CMS:
Packit d7e8d0
        if (gpgme_set_protocol(ctx, GPGME_PROTOCOL_CMS) != 0) {
Packit d7e8d0
            gpgme_release(ctx);
Packit d7e8d0
            return 0;
Packit d7e8d0
        }
Packit d7e8d0
        break;
Packit d7e8d0
    default:
Packit ecbf52
        gpgme_release(ctx);
Packit d7e8d0
        return 0;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    return new Context(ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::unique_ptr<Context> Context::createForEngine(Engine eng, Error *error)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_ctx_t ctx = 0;
Packit d7e8d0
    if (const gpgme_error_t err = gpgme_new(&ctx)) {
Packit d7e8d0
        if (error) {
Packit d7e8d0
            *error = Error(err);
Packit d7e8d0
        }
Packit d7e8d0
        return std::unique_ptr<Context>();
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    switch (eng) {
Packit d7e8d0
    case AssuanEngine:
Packit d7e8d0
        if (const gpgme_error_t err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_ASSUAN)) {
Packit d7e8d0
            gpgme_release(ctx);
Packit d7e8d0
            if (error) {
Packit d7e8d0
                *error = Error(err);
Packit d7e8d0
            }
Packit d7e8d0
            return std::unique_ptr<Context>();
Packit d7e8d0
        }
Packit d7e8d0
        break;
Packit d7e8d0
    case G13Engine:
Packit d7e8d0
        if (const gpgme_error_t err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_G13)) {
Packit d7e8d0
            gpgme_release(ctx);
Packit d7e8d0
            if (error) {
Packit d7e8d0
                *error = Error(err);
Packit d7e8d0
            }
Packit d7e8d0
            return std::unique_ptr<Context>();
Packit d7e8d0
        }
Packit d7e8d0
        break;
Packit d7e8d0
    case SpawnEngine:
Packit d7e8d0
        if (const gpgme_error_t err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_SPAWN)) {
Packit d7e8d0
            gpgme_release(ctx);
Packit d7e8d0
            if (error) {
Packit d7e8d0
                *error = Error(err);
Packit d7e8d0
            }
Packit d7e8d0
            return std::unique_ptr<Context>();
Packit d7e8d0
        }
Packit d7e8d0
        break;
Packit d7e8d0
    default:
Packit ecbf52
        gpgme_release(ctx);
Packit d7e8d0
        if (error) {
Packit d7e8d0
            *error = Error::fromCode(GPG_ERR_INV_ARG);
Packit d7e8d0
        }
Packit d7e8d0
        return std::unique_ptr<Context>();
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    if (error) {
Packit d7e8d0
        *error = Error();
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    return std::unique_ptr<Context>(new Context(ctx));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setDecryptionFlags(DecryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->decryptFlags = flags;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
//
Packit d7e8d0
//
Packit d7e8d0
// Context::Private
Packit d7e8d0
//
Packit d7e8d0
//
Packit d7e8d0
Packit d7e8d0
Context::Private::Private(gpgme_ctx_t c)
Packit d7e8d0
    : ctx(c),
Packit d7e8d0
      iocbs(0),
Packit d7e8d0
      lastop(None),
Packit d7e8d0
      lasterr(GPG_ERR_NO_ERROR),
Packit d7e8d0
      lastAssuanInquireData(Data::null),
Packit d7e8d0
      lastAssuanTransaction(),
Packit d7e8d0
      lastEditInteractor(),
Packit d7e8d0
      lastCardEditInteractor(),
Packit d7e8d0
      decryptFlags(DecryptNone)
Packit d7e8d0
{
Packit d7e8d0
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Context::Private::~Private()
Packit d7e8d0
{
Packit d7e8d0
    if (ctx) {
Packit d7e8d0
        gpgme_release(ctx);
Packit d7e8d0
    }
Packit d7e8d0
    ctx = 0;
Packit d7e8d0
    delete iocbs;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
//
Packit d7e8d0
//
Packit d7e8d0
// Context attributes:
Packit d7e8d0
//
Packit d7e8d0
//
Packit d7e8d0
Packit d7e8d0
Protocol Context::protocol() const
Packit d7e8d0
{
Packit d7e8d0
    gpgme_protocol_t p = gpgme_get_protocol(d->ctx);
Packit d7e8d0
    switch (p) {
Packit d7e8d0
    case GPGME_PROTOCOL_OpenPGP: return OpenPGP;
Packit d7e8d0
    case GPGME_PROTOCOL_CMS:     return CMS;
Packit d7e8d0
    default:                     return UnknownProtocol;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setArmor(bool useArmor)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_set_armor(d->ctx, int(useArmor));
Packit d7e8d0
}
Packit d7e8d0
bool Context::armor() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_get_armor(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setTextMode(bool useTextMode)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_set_textmode(d->ctx, int(useTextMode));
Packit d7e8d0
}
Packit d7e8d0
bool Context::textMode() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_get_textmode(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setOffline(bool useOfflineMode)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_set_offline(d->ctx, int(useOfflineMode));
Packit d7e8d0
}
Packit d7e8d0
bool Context::offline() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_get_offline(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setIncludeCertificates(int which)
Packit d7e8d0
{
Packit d7e8d0
    if (which == DefaultCertificates) {
Packit d7e8d0
        which = GPGME_INCLUDE_CERTS_DEFAULT;
Packit d7e8d0
    }
Packit d7e8d0
    gpgme_set_include_certs(d->ctx, which);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
int Context::includeCertificates() const
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_get_include_certs(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setKeyListMode(unsigned int mode)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_set_keylist_mode(d->ctx, add_to_gpgme_keylist_mode_t(0, mode));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::addKeyListMode(unsigned int mode)
Packit d7e8d0
{
Packit d7e8d0
    const unsigned int cur = gpgme_get_keylist_mode(d->ctx);
Packit d7e8d0
    gpgme_set_keylist_mode(d->ctx, add_to_gpgme_keylist_mode_t(cur, mode));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
unsigned int Context::keyListMode() const
Packit d7e8d0
{
Packit d7e8d0
    return convert_from_gpgme_keylist_mode_t(gpgme_get_keylist_mode(d->ctx));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setProgressProvider(ProgressProvider *provider)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_set_progress_cb(d->ctx, provider ? &progress_callback : 0, provider);
Packit d7e8d0
}
Packit d7e8d0
ProgressProvider *Context::progressProvider() const
Packit d7e8d0
{
Packit d7e8d0
    void *pp = 0;
Packit d7e8d0
    gpgme_progress_cb_t pcb = &progress_callback;
Packit d7e8d0
    gpgme_get_progress_cb(d->ctx, &pcb, &pp;;
Packit d7e8d0
    return static_cast<ProgressProvider *>(pp);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setPassphraseProvider(PassphraseProvider *provider)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_set_passphrase_cb(d->ctx, provider ? &passphrase_callback : 0, provider);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
PassphraseProvider *Context::passphraseProvider() const
Packit d7e8d0
{
Packit d7e8d0
    void *pp = 0;
Packit d7e8d0
    gpgme_passphrase_cb_t pcb = &passphrase_callback;
Packit d7e8d0
    gpgme_get_passphrase_cb(d->ctx, &pcb, &pp;;
Packit d7e8d0
    return static_cast<PassphraseProvider *>(pp);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::setManagedByEventLoopInteractor(bool manage)
Packit d7e8d0
{
Packit d7e8d0
    if (!EventLoopInteractor::instance()) {
Packit d7e8d0
#ifndef NDEBUG
Packit d7e8d0
        cerr << "Context::setManagedByEventLoopInteractor(): "
Packit d7e8d0
             "You must create an instance of EventLoopInteractor "
Packit d7e8d0
             "before using anything that needs one." << endl;
Packit d7e8d0
#endif
Packit d7e8d0
        return;
Packit d7e8d0
    }
Packit d7e8d0
    if (manage) {
Packit d7e8d0
        EventLoopInteractor::instance()->manage(this);
Packit d7e8d0
    } else {
Packit d7e8d0
        EventLoopInteractor::instance()->unmanage(this);
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
bool Context::managedByEventLoopInteractor() const
Packit d7e8d0
{
Packit d7e8d0
    return d->iocbs != 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::installIOCallbacks(gpgme_io_cbs *iocbs)
Packit d7e8d0
{
Packit d7e8d0
    if (!iocbs) {
Packit d7e8d0
        uninstallIOCallbacks();
Packit d7e8d0
        return;
Packit d7e8d0
    }
Packit d7e8d0
    gpgme_set_io_cbs(d->ctx, iocbs);
Packit d7e8d0
    delete d->iocbs; d->iocbs = iocbs;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::uninstallIOCallbacks()
Packit d7e8d0
{
Packit d7e8d0
    static gpgme_io_cbs noiocbs = { 0, 0, 0, 0, 0 };
Packit d7e8d0
    // io.add == 0 means disable io callbacks:
Packit d7e8d0
    gpgme_set_io_cbs(d->ctx, &noiocbs);
Packit d7e8d0
    delete d->iocbs; d->iocbs = 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setLocale(int cat, const char *val)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_set_locale(d->ctx, cat, val));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
EngineInfo Context::engineInfo() const
Packit d7e8d0
{
Packit d7e8d0
    return EngineInfo(gpgme_ctx_get_engine_info(d->ctx));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setEngineFileName(const char *filename)
Packit d7e8d0
{
Packit d7e8d0
    const char *const home_dir = engineInfo().homeDirectory();
Packit d7e8d0
    return Error(gpgme_ctx_set_engine_info(d->ctx, gpgme_get_protocol(d->ctx), filename, home_dir));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setEngineHomeDirectory(const char *home_dir)
Packit d7e8d0
{
Packit d7e8d0
    const char *const filename = engineInfo().fileName();
Packit d7e8d0
    return Error(gpgme_ctx_set_engine_info(d->ctx, gpgme_get_protocol(d->ctx), filename, home_dir));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setSender (const char *sender)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_set_sender(d->ctx, sender));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *Context::getSender ()
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_get_sender(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
//
Packit d7e8d0
//
Packit d7e8d0
// Key Management
Packit d7e8d0
//
Packit d7e8d0
//
Packit d7e8d0
Packit d7e8d0
Error Context::startKeyListing(const char *pattern, bool secretOnly)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::KeyList;
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_keylist_start(d->ctx, pattern, int(secretOnly)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startKeyListing(const char *patterns[], bool secretOnly)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::KeyList;
Packit d7e8d0
#ifndef HAVE_GPGME_EXT_KEYLIST_MODE_EXTERNAL_NONBROKEN
Packit d7e8d0
    if (!patterns || !patterns[0] || !patterns[1]) {
Packit d7e8d0
        // max. one pattern -> use the non-ext version
Packit d7e8d0
        return startKeyListing(patterns ? patterns[0] : 0, secretOnly);
Packit d7e8d0
    }
Packit d7e8d0
#endif
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_keylist_ext_start(d->ctx, patterns, int(secretOnly), 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Key Context::nextKey(GpgME::Error &e)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::KeyList;
Packit d7e8d0
    gpgme_key_t key;
Packit d7e8d0
    e = Error(d->lasterr = gpgme_op_keylist_next(d->ctx, &key));
Packit d7e8d0
    return Key(key, false);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
KeyListResult Context::endKeyListing()
Packit d7e8d0
{
Packit d7e8d0
    d->lasterr = gpgme_op_keylist_end(d->ctx);
Packit d7e8d0
    return keyListResult();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
KeyListResult Context::keyListResult() const
Packit d7e8d0
{
Packit d7e8d0
    return KeyListResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Key Context::key(const char *fingerprint, GpgME::Error &e , bool secret /*, bool forceUpdate*/)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::KeyList;
Packit d7e8d0
    gpgme_key_t key;
Packit d7e8d0
    e = Error(d->lasterr = gpgme_get_key(d->ctx, fingerprint, &key, int(secret)/*, int( forceUpdate )*/));
Packit d7e8d0
    return Key(key, false);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
KeyGenerationResult Context::generateKey(const char *parameters, Data &pubKey)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::KeyGen;
Packit d7e8d0
    Data::Private *const dp = pubKey.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_genkey(d->ctx, parameters, dp ? dp->data : 0, 0);
Packit d7e8d0
    return KeyGenerationResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startKeyGeneration(const char *parameters, Data &pubKey)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::KeyGen;
Packit d7e8d0
    Data::Private *const dp = pubKey.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_genkey_start(d->ctx, parameters, dp ? dp->data : 0, 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
KeyGenerationResult Context::keyGenerationResult() const
Packit d7e8d0
{
Packit d7e8d0
    if (d->lastop & Private::KeyGen) {
Packit d7e8d0
        return KeyGenerationResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return KeyGenerationResult();
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::exportPublicKeys(const char *pattern, Data &keyData)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Export;
Packit d7e8d0
    Data::Private *const dp = keyData.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_export(d->ctx, pattern, 0, dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::exportPublicKeys(const char *patterns[], Data &keyData)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Export;
Packit d7e8d0
#ifndef HAVE_GPGME_EXT_KEYLIST_MODE_EXTERNAL_NONBROKEN
Packit d7e8d0
    if (!patterns || !patterns[0] || !patterns[1]) {
Packit d7e8d0
        // max. one pattern -> use the non-ext version
Packit d7e8d0
        return exportPublicKeys(patterns ? patterns[0] : 0, keyData);
Packit d7e8d0
    }
Packit d7e8d0
#endif
Packit d7e8d0
    Data::Private *const dp = keyData.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_export_ext(d->ctx, patterns, 0, dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startPublicKeyExport(const char *pattern, Data &keyData)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Export;
Packit d7e8d0
    Data::Private *const dp = keyData.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_export_start(d->ctx, pattern, 0, dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startPublicKeyExport(const char *patterns[], Data &keyData)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Export;
Packit d7e8d0
#ifndef HAVE_GPGME_EXT_KEYLIST_MODE_EXTERNAL_NONBROKEN
Packit d7e8d0
    if (!patterns || !patterns[0] || !patterns[1]) {
Packit d7e8d0
        // max. one pattern -> use the non-ext version
Packit d7e8d0
        return startPublicKeyExport(patterns ? patterns[0] : 0, keyData);
Packit d7e8d0
    }
Packit d7e8d0
#endif
Packit d7e8d0
    Data::Private *const dp = keyData.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_export_ext_start(d->ctx, patterns, 0, dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
ImportResult Context::importKeys(const Data &data)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Import;
Packit d7e8d0
    const Data::Private *const dp = data.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_import(d->ctx, dp ? dp->data : 0);
Packit d7e8d0
    return ImportResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
ImportResult Context::importKeys(const std::vector<Key> &kk)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Import;
Packit d7e8d0
    d->lasterr = make_error(GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
    bool shouldHaveResult = false;
Packit d7e8d0
    gpgme_key_t * const keys = new gpgme_key_t[ kk.size() + 1 ];
Packit d7e8d0
    gpgme_key_t *keys_it = &keys[0];
Packit d7e8d0
    for (std::vector<Key>::const_iterator it = kk.begin(), end = kk.end() ; it != end ; ++it) {
Packit d7e8d0
        if (it->impl()) {
Packit d7e8d0
            *keys_it++ = it->impl();
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    *keys_it++ = 0;
Packit d7e8d0
    d->lasterr = gpgme_op_import_keys(d->ctx, keys);
Packit d7e8d0
    shouldHaveResult = true;
Packit d7e8d0
    if ((gpgme_err_code(d->lasterr) == GPG_ERR_NOT_IMPLEMENTED ||
Packit d7e8d0
            gpgme_err_code(d->lasterr) == GPG_ERR_NOT_SUPPORTED) &&
Packit d7e8d0
            protocol() == CMS) {
Packit d7e8d0
        // ok, try the workaround (export+import):
Packit d7e8d0
        std::vector<const char *> fprs;
Packit d7e8d0
        for (std::vector<Key>::const_iterator it = kk.begin(), end = kk.end() ; it != end ; ++it) {
Packit d7e8d0
            if (const char *fpr = it->primaryFingerprint()) {
Packit d7e8d0
                if (*fpr) {
Packit d7e8d0
                    fprs.push_back(fpr);
Packit d7e8d0
                }
Packit d7e8d0
            } else if (const char *keyid = it->keyID()) {
Packit d7e8d0
                if (*keyid) {
Packit d7e8d0
                    fprs.push_back(keyid);
Packit d7e8d0
                }
Packit d7e8d0
            }
Packit d7e8d0
        }
Packit d7e8d0
        fprs.push_back(0);
Packit d7e8d0
        Data data;
Packit d7e8d0
        Data::Private *const dp = data.impl();
Packit d7e8d0
        const gpgme_keylist_mode_t oldMode = gpgme_get_keylist_mode(d->ctx);
Packit d7e8d0
        gpgme_set_keylist_mode(d->ctx, GPGME_KEYLIST_MODE_EXTERN);
Packit d7e8d0
        d->lasterr = gpgme_op_export_ext(d->ctx, &fprs[0], 0, dp ? dp->data : 0);
Packit d7e8d0
        gpgme_set_keylist_mode(d->ctx, oldMode);
Packit d7e8d0
        if (!d->lasterr) {
Packit d7e8d0
            data.seek(0, SEEK_SET);
Packit d7e8d0
            d->lasterr = gpgme_op_import(d->ctx, dp ? dp->data : 0);
Packit d7e8d0
            shouldHaveResult = true;
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    delete[] keys;
Packit d7e8d0
    if (shouldHaveResult) {
Packit d7e8d0
        return ImportResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return ImportResult(Error(d->lasterr));
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startKeyImport(const Data &data)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Import;
Packit d7e8d0
    const Data::Private *const dp = data.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_import_start(d->ctx, dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startKeyImport(const std::vector<Key> &kk)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Import;
Packit d7e8d0
    gpgme_key_t * const keys = new gpgme_key_t[ kk.size() + 1 ];
Packit d7e8d0
    gpgme_key_t *keys_it = &keys[0];
Packit d7e8d0
    for (std::vector<Key>::const_iterator it = kk.begin(), end = kk.end() ; it != end ; ++it) {
Packit d7e8d0
        if (it->impl()) {
Packit d7e8d0
            *keys_it++ = it->impl();
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    *keys_it++ = 0;
Packit d7e8d0
    Error err = Error(d->lasterr = gpgme_op_import_keys_start(d->ctx, keys));
Packit d7e8d0
    delete[] keys;
Packit d7e8d0
    return err;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
ImportResult Context::importResult() const
Packit d7e8d0
{
Packit d7e8d0
    if (d->lastop & Private::Import) {
Packit d7e8d0
        return ImportResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return ImportResult();
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::deleteKey(const Key &key, bool allowSecretKeyDeletion)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Delete;
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_delete(d->ctx, key.impl(), int(allowSecretKeyDeletion)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startKeyDeletion(const Key &key, bool allowSecretKeyDeletion)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Delete;
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_delete_start(d->ctx, key.impl(), int(allowSecretKeyDeletion)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::passwd(const Key &key)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Passwd;
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_passwd(d->ctx, key.impl(), 0U));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startPasswd(const Key &key)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Passwd;
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_passwd_start(d->ctx, key.impl(), 0U));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
#pragma GCC diagnostic push
Packit d7e8d0
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Packit d7e8d0
Packit d7e8d0
Error Context::edit(const Key &key, std::unique_ptr<EditInteractor> func, Data &data)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Edit;
Packit d7e8d0
    d->lastEditInteractor = std::move(func);
Packit d7e8d0
    Data::Private *const dp = data.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_edit(d->ctx, key.impl(),
Packit d7e8d0
                                            d->lastEditInteractor.get() ? edit_interactor_callback : 0,
Packit d7e8d0
                                            d->lastEditInteractor.get() ? d->lastEditInteractor->d : 0,
Packit d7e8d0
                                            dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
Error Context::startEditing(const Key &key, std::unique_ptr<EditInteractor> func, Data &data)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Edit;
Packit d7e8d0
    d->lastEditInteractor = std::move(func);
Packit d7e8d0
    Data::Private *const dp = data.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_edit_start(d->ctx, key.impl(),
Packit d7e8d0
                              d->lastEditInteractor.get() ? edit_interactor_callback : 0,
Packit d7e8d0
                              d->lastEditInteractor.get() ? d->lastEditInteractor->d : 0,
Packit d7e8d0
                              dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
EditInteractor *Context::lastEditInteractor() const
Packit d7e8d0
{
Packit d7e8d0
    return d->lastEditInteractor.get();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::unique_ptr<EditInteractor> Context::takeLastEditInteractor()
Packit d7e8d0
{
Packit d7e8d0
    return std::move(d->lastEditInteractor);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
Error Context::cardEdit(const Key &key, std::unique_ptr<EditInteractor> func, Data &data)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::CardEdit;
Packit d7e8d0
    d->lastCardEditInteractor = std::move(func);
Packit d7e8d0
    Data::Private *const dp = data.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_card_edit(d->ctx, key.impl(),
Packit d7e8d0
                              d->lastCardEditInteractor.get() ? edit_interactor_callback : 0,
Packit d7e8d0
                              d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->d : 0,
Packit d7e8d0
                              dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startCardEditing(const Key &key, std::unique_ptr<EditInteractor> func, Data &data)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::CardEdit;
Packit d7e8d0
    d->lastCardEditInteractor = std::move(func);
Packit d7e8d0
    Data::Private *const dp = data.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_card_edit_start(d->ctx, key.impl(),
Packit d7e8d0
                              d->lastCardEditInteractor.get() ? edit_interactor_callback : 0,
Packit d7e8d0
                              d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->d : 0,
Packit d7e8d0
                              dp ? dp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
#pragma GCC diagnostic pop
Packit d7e8d0
Packit d7e8d0
EditInteractor *Context::lastCardEditInteractor() const
Packit d7e8d0
{
Packit d7e8d0
    return d->lastCardEditInteractor.get();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::unique_ptr<EditInteractor> Context::takeLastCardEditInteractor()
Packit d7e8d0
{
Packit d7e8d0
    return std::move(d->lastCardEditInteractor);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startTrustItemListing(const char *pattern, int maxLevel)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::TrustList;
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_trustlist_start(d->ctx, pattern, maxLevel));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
TrustItem Context::nextTrustItem(Error &e)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_trust_item_t ti = 0;
Packit d7e8d0
    e = Error(d->lasterr = gpgme_op_trustlist_next(d->ctx, &ti);;
Packit d7e8d0
    return TrustItem(ti);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::endTrustItemListing()
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_trustlist_end(d->ctx));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static gpgme_error_t assuan_transaction_data_callback(void *opaque, const void *data, size_t datalen)
Packit d7e8d0
{
Packit d7e8d0
    assert(opaque);
Packit d7e8d0
    AssuanTransaction *t = static_cast<AssuanTransaction *>(opaque);
Packit d7e8d0
    return t->data(static_cast<const char *>(data), datalen).encodedError();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static gpgme_error_t assuan_transaction_inquire_callback(void *opaque, const char *name, const char *args, gpgme_data_t *r_data)
Packit d7e8d0
{
Packit d7e8d0
    assert(opaque);
Packit d7e8d0
    Context::Private *p = static_cast<Context::Private *>(opaque);
Packit d7e8d0
    AssuanTransaction *t = p->lastAssuanTransaction.get();
Packit d7e8d0
    assert(t);
Packit d7e8d0
    Error err;
Packit d7e8d0
    if (name) {
Packit d7e8d0
        p->lastAssuanInquireData = t->inquire(name, args, err);
Packit d7e8d0
    } else {
Packit d7e8d0
        p->lastAssuanInquireData = Data::null;
Packit d7e8d0
    }
Packit d7e8d0
    if (!p->lastAssuanInquireData.isNull()) {
Packit d7e8d0
        *r_data = p->lastAssuanInquireData.impl()->data;
Packit d7e8d0
    }
Packit d7e8d0
    return err.encodedError();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static gpgme_error_t assuan_transaction_status_callback(void *opaque, const char *status, const char *args)
Packit d7e8d0
{
Packit d7e8d0
    assert(opaque);
Packit d7e8d0
    AssuanTransaction *t = static_cast<AssuanTransaction *>(opaque);
Packit d7e8d0
    std::string a = args;
Packit d7e8d0
    percent_unescape(a, true);   // ### why doesn't gpgme do this??
Packit d7e8d0
    return t->status(status, a.c_str()).encodedError();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::assuanTransact(const char *command)
Packit d7e8d0
{
Packit d7e8d0
    return assuanTransact(command, std::unique_ptr<AssuanTransaction>(new DefaultAssuanTransaction));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::assuanTransact(const char *command, std::unique_ptr<AssuanTransaction> transaction)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_error_t err, operr;
Packit d7e8d0
Packit d7e8d0
    d->lastop = Private::AssuanTransact;
Packit d7e8d0
    d->lastAssuanTransaction = std::move(transaction);
Packit d7e8d0
    if (!d->lastAssuanTransaction.get()) {
Packit d7e8d0
        return Error(d->lasterr = make_error(GPG_ERR_INV_ARG));
Packit d7e8d0
    }
Packit d7e8d0
    err = gpgme_op_assuan_transact_ext
Packit d7e8d0
      (d->ctx,
Packit d7e8d0
       command,
Packit d7e8d0
       assuan_transaction_data_callback,
Packit d7e8d0
       d->lastAssuanTransaction.get(),
Packit d7e8d0
       assuan_transaction_inquire_callback,
Packit d7e8d0
       d,
Packit d7e8d0
       assuan_transaction_status_callback,
Packit d7e8d0
       d->lastAssuanTransaction.get(),
Packit d7e8d0
       &operr;;
Packit d7e8d0
Packit d7e8d0
    if (!err)
Packit d7e8d0
      err = operr;
Packit d7e8d0
    d->lasterr = err;
Packit d7e8d0
Packit d7e8d0
    return Error(d->lasterr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startAssuanTransaction(const char *command)
Packit d7e8d0
{
Packit d7e8d0
    return startAssuanTransaction(command, std::unique_ptr<AssuanTransaction>(new DefaultAssuanTransaction));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startAssuanTransaction(const char *command, std::unique_ptr<AssuanTransaction> transaction)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_error_t err;
Packit d7e8d0
Packit d7e8d0
    d->lastop = Private::AssuanTransact;
Packit d7e8d0
    d->lastAssuanTransaction = std::move(transaction);
Packit d7e8d0
    if (!d->lastAssuanTransaction.get()) {
Packit d7e8d0
        return Error(d->lasterr = make_error(GPG_ERR_INV_ARG));
Packit d7e8d0
    }
Packit d7e8d0
    err = gpgme_op_assuan_transact_start
Packit d7e8d0
      (d->ctx,
Packit d7e8d0
       command,
Packit d7e8d0
       assuan_transaction_data_callback,
Packit d7e8d0
       d->lastAssuanTransaction.get(),
Packit d7e8d0
       assuan_transaction_inquire_callback,
Packit d7e8d0
       d,
Packit d7e8d0
       assuan_transaction_status_callback,
Packit d7e8d0
       d->lastAssuanTransaction.get());
Packit d7e8d0
Packit d7e8d0
    d->lasterr = err;
Packit d7e8d0
Packit d7e8d0
    return Error(d->lasterr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
AssuanTransaction *Context::lastAssuanTransaction() const
Packit d7e8d0
{
Packit d7e8d0
    return d->lastAssuanTransaction.get();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::unique_ptr<AssuanTransaction> Context::takeLastAssuanTransaction()
Packit d7e8d0
{
Packit d7e8d0
    return std::move(d->lastAssuanTransaction);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText, const DecryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Decrypt;
Packit d7e8d0
    const Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_decrypt_ext(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags), cdp ? cdp->data : 0, pdp ? pdp->data : 0);
Packit d7e8d0
    return DecryptionResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText)
Packit d7e8d0
{
Packit d7e8d0
    return decrypt(cipherText, plainText, DecryptNone);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startDecryption(const Data &cipherText, Data &plainText, const DecryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Decrypt;
Packit d7e8d0
    const Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_decrypt_ext_start(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags),
Packit d7e8d0
                 cdp ? cdp->data : 0, pdp ? pdp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startDecryption(const Data &cipherText, Data &plainText)
Packit d7e8d0
{
Packit d7e8d0
    return startDecryption(cipherText, plainText, DecryptNone);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
DecryptionResult Context::decryptionResult() const
Packit d7e8d0
{
Packit d7e8d0
    if (d->lastop & Private::Decrypt) {
Packit d7e8d0
        return DecryptionResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return DecryptionResult();
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
VerificationResult Context::verifyDetachedSignature(const Data &signature, const Data &signedText)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Verify;
Packit d7e8d0
    const Data::Private *const sdp = signature.impl();
Packit d7e8d0
    const Data::Private *const tdp = signedText.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_verify(d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0);
Packit d7e8d0
    return VerificationResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
VerificationResult Context::verifyOpaqueSignature(const Data &signedData, Data &plainText)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Verify;
Packit d7e8d0
    const Data::Private *const sdp = signedData.impl();
Packit d7e8d0
    Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_verify(d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0);
Packit d7e8d0
    return VerificationResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startDetachedSignatureVerification(const Data &signature, const Data &signedText)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Verify;
Packit d7e8d0
    const Data::Private *const sdp = signature.impl();
Packit d7e8d0
    const Data::Private *const tdp = signedText.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_verify_start(d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startOpaqueSignatureVerification(const Data &signedData, Data &plainText)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Verify;
Packit d7e8d0
    const Data::Private *const sdp = signedData.impl();
Packit d7e8d0
    Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_verify_start(d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
VerificationResult Context::verificationResult() const
Packit d7e8d0
{
Packit d7e8d0
    if (d->lastop & Private::Verify) {
Packit d7e8d0
        return VerificationResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return VerificationResult();
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::pair<DecryptionResult, VerificationResult> Context::decryptAndVerify(const Data &cipherText, Data &plainText, DecryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::DecryptAndVerify;
Packit d7e8d0
    const Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_decrypt_ext(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags | DecryptVerify),
Packit d7e8d0
                                      cdp ? cdp->data : 0, pdp ? pdp->data : 0);
Packit d7e8d0
    return std::make_pair(DecryptionResult(d->ctx, Error(d->lasterr)),
Packit d7e8d0
                          VerificationResult(d->ctx, Error(d->lasterr)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::pair<DecryptionResult, VerificationResult> Context::decryptAndVerify(const Data &cipherText, Data &plainText)
Packit d7e8d0
{
Packit d7e8d0
    return decryptAndVerify(cipherText, plainText, DecryptNone);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText, DecryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::DecryptAndVerify;
Packit d7e8d0
    const Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_decrypt_ext_start(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags | DecryptVerify), cdp ? cdp->data : 0, pdp ? pdp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText)
Packit d7e8d0
{
Packit d7e8d0
    return startCombinedDecryptionAndVerification(cipherText, plainText, DecryptNone);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
unsigned int to_auditlog_flags(unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    unsigned int result = 0;
Packit d7e8d0
    if (flags & Context::HtmlAuditLog) {
Packit d7e8d0
        result |= GPGME_AUDITLOG_HTML;
Packit d7e8d0
    }
Packit d7e8d0
    if (flags & Context::AuditLogWithHelp) {
Packit d7e8d0
        result |= GPGME_AUDITLOG_WITH_HELP;
Packit d7e8d0
    }
Packit d7e8d0
    return result;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startGetAuditLog(Data &output, unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::GetAuditLog;
Packit d7e8d0
    Data::Private *const odp = output.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_getauditlog_start(d->ctx, odp ? odp->data : 0, to_auditlog_flags(flags)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::getAuditLog(Data &output, unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::GetAuditLog;
Packit d7e8d0
    Data::Private *const odp = output.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_getauditlog(d->ctx, odp ? odp->data : 0, to_auditlog_flags(flags)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::clearSigningKeys()
Packit d7e8d0
{
Packit d7e8d0
    gpgme_signers_clear(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::addSigningKey(const Key &key)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_signers_add(d->ctx, key.impl()));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Key Context::signingKey(unsigned int idx) const
Packit d7e8d0
{
Packit d7e8d0
    gpgme_key_t key = gpgme_signers_enum(d->ctx, idx);
Packit d7e8d0
    return Key(key, false);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::vector<Key> Context::signingKeys() const
Packit d7e8d0
{
Packit d7e8d0
    std::vector<Key> result;
Packit d7e8d0
    gpgme_key_t key;
Packit d7e8d0
    for (unsigned int i = 0 ; (key = gpgme_signers_enum(d->ctx, i)) ; ++i) {
Packit d7e8d0
        result.push_back(Key(key, false));
Packit d7e8d0
    }
Packit d7e8d0
    return result;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void Context::clearSignatureNotations()
Packit d7e8d0
{
Packit d7e8d0
    gpgme_sig_notation_clear(d->ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::Error Context::addSignatureNotation(const char *name, const char *value, unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_sig_notation_add(d->ctx, name, value, add_to_gpgme_sig_notation_flags_t(0, flags)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::Error Context::addSignaturePolicyURL(const char *url, bool critical)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_sig_notation_add(d->ctx, 0, url, critical ? GPGME_SIG_NOTATION_CRITICAL : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *Context::signaturePolicyURL() const
Packit d7e8d0
{
Packit d7e8d0
    for (gpgme_sig_notation_t n = gpgme_sig_notation_get(d->ctx) ; n ; n = n->next) {
Packit d7e8d0
        if (!n->name) {
Packit d7e8d0
            return n->value;
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    return nullptr;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Notation Context::signatureNotation(unsigned int idx) const
Packit d7e8d0
{
Packit d7e8d0
    for (gpgme_sig_notation_t n = gpgme_sig_notation_get(d->ctx) ; n ; n = n->next) {
Packit d7e8d0
        if (n->name) {
Packit d7e8d0
            if (idx-- == 0) {
Packit d7e8d0
                return Notation(n);
Packit d7e8d0
            }
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    return Notation();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::vector<Notation> Context::signatureNotations() const
Packit d7e8d0
{
Packit d7e8d0
    std::vector<Notation> result;
Packit d7e8d0
    for (gpgme_sig_notation_t n = gpgme_sig_notation_get(d->ctx) ; n ; n = n->next) {
Packit d7e8d0
        if (n->name) {
Packit d7e8d0
            result.push_back(Notation(n));
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    return result;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static gpgme_sig_mode_t sigmode2sigmode(SignatureMode mode)
Packit d7e8d0
{
Packit d7e8d0
    switch (mode) {
Packit d7e8d0
    default:
Packit d7e8d0
    case NormalSignatureMode: return GPGME_SIG_MODE_NORMAL;
Packit d7e8d0
    case Detached:            return GPGME_SIG_MODE_DETACH;
Packit d7e8d0
    case Clearsigned:         return GPGME_SIG_MODE_CLEAR;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
SigningResult Context::sign(const Data &plainText, Data &signature, SignatureMode mode)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Sign;
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const sdp = signature.impl();
Packit d7e8d0
    d->lasterr = gpgme_op_sign(d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode(mode));
Packit d7e8d0
    return SigningResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startSigning(const Data &plainText, Data &signature, SignatureMode mode)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Sign;
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const sdp = signature.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_sign_start(d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode(mode)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
SigningResult Context::signingResult() const
Packit d7e8d0
{
Packit d7e8d0
    if (d->lastop & Private::Sign) {
Packit d7e8d0
        return SigningResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return SigningResult();
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static gpgme_encrypt_flags_t encryptflags2encryptflags(Context::EncryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    unsigned int result = 0;
Packit d7e8d0
    if (flags & Context::AlwaysTrust) {
Packit d7e8d0
        result |= GPGME_ENCRYPT_ALWAYS_TRUST;
Packit d7e8d0
    }
Packit d7e8d0
    if (flags & Context::NoEncryptTo) {
Packit d7e8d0
        result |= GPGME_ENCRYPT_NO_ENCRYPT_TO;
Packit d7e8d0
    }
Packit d7e8d0
    if (flags & Context::Prepare) {
Packit d7e8d0
        result |= GPGME_ENCRYPT_PREPARE;
Packit d7e8d0
    }
Packit d7e8d0
    if (flags & Context::ExpectSign) {
Packit d7e8d0
        result |= GPGME_ENCRYPT_EXPECT_SIGN;
Packit d7e8d0
    }
Packit d7e8d0
    if (flags & Context::NoCompress) {
Packit d7e8d0
        result |= GPGME_ENCRYPT_NO_COMPRESS;
Packit d7e8d0
    }
Packit d7e8d0
    if (flags & Context::Symmetric) {
Packit d7e8d0
        result |= GPGME_ENCRYPT_SYMMETRIC;
Packit d7e8d0
    }
Packit d7e8d0
    return static_cast<gpgme_encrypt_flags_t>(result);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
gpgme_key_t *Context::getKeysFromRecipients(const std::vector<Key> &recipients)
Packit d7e8d0
{
Packit d7e8d0
    if (recipients.empty()) {
Packit d7e8d0
        return nullptr;
Packit d7e8d0
    }
Packit d7e8d0
    gpgme_key_t *ret = new gpgme_key_t[ recipients.size() + 1 ];
Packit d7e8d0
    gpgme_key_t *keys_it = ret;
Packit d7e8d0
    for (std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it) {
Packit d7e8d0
        if (it->impl()) {
Packit d7e8d0
            *keys_it++ = it->impl();
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    *keys_it++ = 0;
Packit d7e8d0
    return ret;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
EncryptionResult Context::encrypt(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Encrypt;
Packit d7e8d0
    if (flags & NoEncryptTo) {
Packit d7e8d0
        return EncryptionResult(Error(d->lasterr = make_error(GPG_ERR_NOT_IMPLEMENTED)));
Packit d7e8d0
    }
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    gpgme_key_t *const keys = getKeysFromRecipients(recipients);
Packit d7e8d0
    d->lasterr = gpgme_op_encrypt(d->ctx, keys, encryptflags2encryptflags(flags),
Packit d7e8d0
                                  pdp ? pdp->data : 0, cdp ? cdp->data : 0);
Packit d7e8d0
    if (keys) {
Packit d7e8d0
        delete[] keys;
Packit d7e8d0
    }
Packit d7e8d0
    return EncryptionResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::encryptSymmetrically(const Data &plainText, Data &cipherText)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Encrypt;
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_encrypt(d->ctx, 0, (gpgme_encrypt_flags_t)0,
Packit d7e8d0
                              pdp ? pdp->data : 0, cdp ? cdp->data : 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startEncryption(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::Encrypt;
Packit d7e8d0
    if (flags & NoEncryptTo) {
Packit d7e8d0
        return Error(d->lasterr = make_error(GPG_ERR_NOT_IMPLEMENTED));
Packit d7e8d0
    }
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    gpgme_key_t *const keys = getKeysFromRecipients(recipients);
Packit d7e8d0
    d->lasterr = gpgme_op_encrypt_start(d->ctx, keys, encryptflags2encryptflags(flags),
Packit d7e8d0
                                        pdp ? pdp->data : 0, cdp ? cdp->data : 0);
Packit d7e8d0
    if (keys) {
Packit d7e8d0
        delete[] keys;
Packit d7e8d0
    }
Packit d7e8d0
    return Error(d->lasterr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
EncryptionResult Context::encryptionResult() const
Packit d7e8d0
{
Packit d7e8d0
    if (d->lastop & Private::Encrypt) {
Packit d7e8d0
        return EncryptionResult(d->ctx, Error(d->lasterr));
Packit d7e8d0
    } else {
Packit d7e8d0
        return EncryptionResult();
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::pair<SigningResult, EncryptionResult> Context::signAndEncrypt(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::SignAndEncrypt;
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    gpgme_key_t *const keys = getKeysFromRecipients(recipients);
Packit d7e8d0
    d->lasterr = gpgme_op_encrypt_sign(d->ctx, keys, encryptflags2encryptflags(flags),
Packit d7e8d0
                                       pdp ? pdp->data : 0, cdp ? cdp->data : 0);
Packit d7e8d0
    if (keys) {
Packit d7e8d0
        delete[] keys;
Packit d7e8d0
    }
Packit d7e8d0
    return std::make_pair(SigningResult(d->ctx, Error(d->lasterr)),
Packit d7e8d0
                          EncryptionResult(d->ctx, Error(d->lasterr)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startCombinedSigningAndEncryption(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::SignAndEncrypt;
Packit d7e8d0
    const Data::Private *const pdp = plainText.impl();
Packit d7e8d0
    Data::Private *const cdp = cipherText.impl();
Packit d7e8d0
    gpgme_key_t *const keys = getKeysFromRecipients(recipients);
Packit d7e8d0
    d->lasterr = gpgme_op_encrypt_sign_start(d->ctx, keys, encryptflags2encryptflags(flags),
Packit d7e8d0
                 pdp ? pdp->data : 0, cdp ? cdp->data : 0);
Packit d7e8d0
    if (keys) {
Packit d7e8d0
        delete[] keys;
Packit d7e8d0
    }
Packit d7e8d0
    return Error(d->lasterr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::createVFS(const char *containerFile, const std::vector< Key > &recipients)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::CreateVFS;
Packit d7e8d0
    gpgme_key_t *const keys = new gpgme_key_t[ recipients.size() + 1 ];
Packit d7e8d0
    gpgme_key_t *keys_it = keys;
Packit d7e8d0
    for (std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it) {
Packit d7e8d0
        if (it->impl()) {
Packit d7e8d0
            *keys_it++ = it->impl();
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
    *keys_it++ = 0;
Packit d7e8d0
Packit d7e8d0
    gpgme_error_t op_err;
Packit d7e8d0
    d->lasterr = gpgme_op_vfs_create(d->ctx, keys, containerFile, 0, &op_err);
Packit d7e8d0
    delete[] keys;
Packit d7e8d0
    Error error(d->lasterr);
Packit d7e8d0
    if (error) {
Packit d7e8d0
        return error;
Packit d7e8d0
    }
Packit d7e8d0
    return Error(d->lasterr = op_err);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
VfsMountResult Context::mountVFS(const char *containerFile, const char *mountDir)
Packit d7e8d0
{
Packit d7e8d0
    d->lastop = Private::MountVFS;
Packit d7e8d0
    gpgme_error_t op_err;
Packit d7e8d0
    d->lasterr = gpgme_op_vfs_mount(d->ctx, containerFile, mountDir, 0, &op_err);
Packit d7e8d0
    return VfsMountResult(d->ctx, Error(d->lasterr), Error(op_err));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::cancelPendingOperation()
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_cancel_async(d->ctx));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
bool Context::poll()
Packit d7e8d0
{
Packit d7e8d0
    gpgme_error_t e = GPG_ERR_NO_ERROR;
Packit d7e8d0
    const bool finished = gpgme_wait(d->ctx, &e, 0);
Packit d7e8d0
    if (finished) {
Packit d7e8d0
        d->lasterr = e;
Packit d7e8d0
    }
Packit d7e8d0
    return finished;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::wait()
Packit d7e8d0
{
Packit d7e8d0
    gpgme_error_t e = GPG_ERR_NO_ERROR;
Packit d7e8d0
    gpgme_wait(d->ctx, &e, 1);
Packit d7e8d0
    return Error(d->lasterr = e);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::lastError() const
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Context::PinentryMode Context::pinentryMode() const
Packit d7e8d0
{
Packit d7e8d0
    switch (gpgme_get_pinentry_mode (d->ctx)) {
Packit d7e8d0
        case GPGME_PINENTRY_MODE_ASK:
Packit d7e8d0
            return PinentryAsk;
Packit d7e8d0
        case GPGME_PINENTRY_MODE_CANCEL:
Packit d7e8d0
            return PinentryCancel;
Packit d7e8d0
        case GPGME_PINENTRY_MODE_ERROR:
Packit d7e8d0
            return PinentryError;
Packit d7e8d0
        case GPGME_PINENTRY_MODE_LOOPBACK:
Packit d7e8d0
            return PinentryLoopback;
Packit d7e8d0
        case GPGME_PINENTRY_MODE_DEFAULT:
Packit d7e8d0
        default:
Packit d7e8d0
            return PinentryDefault;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setPinentryMode(PinentryMode which)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_pinentry_mode_t mode;
Packit d7e8d0
    switch (which) {
Packit d7e8d0
        case PinentryAsk:
Packit d7e8d0
            mode = GPGME_PINENTRY_MODE_ASK;
Packit d7e8d0
            break;
Packit d7e8d0
        case PinentryCancel:
Packit d7e8d0
            mode = GPGME_PINENTRY_MODE_CANCEL;
Packit d7e8d0
            break;
Packit d7e8d0
        case PinentryError:
Packit d7e8d0
            mode = GPGME_PINENTRY_MODE_ERROR;
Packit d7e8d0
            break;
Packit d7e8d0
        case PinentryLoopback:
Packit d7e8d0
            mode = GPGME_PINENTRY_MODE_LOOPBACK;
Packit d7e8d0
            break;
Packit d7e8d0
        case PinentryDefault:
Packit d7e8d0
        default:
Packit d7e8d0
            mode = GPGME_PINENTRY_MODE_DEFAULT;
Packit d7e8d0
    }
Packit d7e8d0
    return Error(d->lasterr = gpgme_set_pinentry_mode(d->ctx, mode));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static gpgme_tofu_policy_t to_tofu_policy_t(unsigned int policy)
Packit d7e8d0
{
Packit d7e8d0
    switch (policy) {
Packit d7e8d0
        case TofuInfo::PolicyNone:
Packit d7e8d0
            return GPGME_TOFU_POLICY_NONE;
Packit d7e8d0
        case TofuInfo::PolicyAuto:
Packit d7e8d0
            return GPGME_TOFU_POLICY_AUTO;
Packit d7e8d0
        case TofuInfo::PolicyGood:
Packit d7e8d0
            return GPGME_TOFU_POLICY_GOOD;
Packit d7e8d0
        case TofuInfo::PolicyBad:
Packit d7e8d0
            return GPGME_TOFU_POLICY_BAD;
Packit d7e8d0
        case TofuInfo::PolicyAsk:
Packit d7e8d0
            return GPGME_TOFU_POLICY_ASK;
Packit d7e8d0
        case TofuInfo::PolicyUnknown:
Packit d7e8d0
        default:
Packit d7e8d0
            return GPGME_TOFU_POLICY_UNKNOWN;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setTofuPolicy(const Key &k, unsigned int policy)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_tofu_policy(d->ctx,
Packit d7e8d0
                 k.impl(), to_tofu_policy_t(policy)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::setTofuPolicyStart(const Key &k, unsigned int policy)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_tofu_policy_start(d->ctx,
Packit d7e8d0
                 k.impl(), to_tofu_policy_t(policy)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startCreateKey (const char *userid,
Packit d7e8d0
                               const char *algo,
Packit d7e8d0
                               unsigned long reserved,
Packit d7e8d0
                               unsigned long expires,
Packit d7e8d0
                               const Key &certkey,
Packit d7e8d0
                               unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_createkey_start(d->ctx,
Packit d7e8d0
                 userid,
Packit d7e8d0
                 algo,
Packit d7e8d0
                 reserved,
Packit d7e8d0
                 expires,
Packit d7e8d0
                 certkey.impl(),
Packit d7e8d0
                 flags));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::createKey (const char *userid,
Packit d7e8d0
                          const char *algo,
Packit d7e8d0
                          unsigned long reserved,
Packit d7e8d0
                          unsigned long expires,
Packit d7e8d0
                          const Key &certkey,
Packit d7e8d0
                          unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_createkey(d->ctx,
Packit d7e8d0
                 userid,
Packit d7e8d0
                 algo,
Packit d7e8d0
                 reserved,
Packit d7e8d0
                 expires,
Packit d7e8d0
                 certkey.impl(),
Packit d7e8d0
                 flags));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::addUid(const Key &k, const char *userid)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_adduid(d->ctx,
Packit d7e8d0
                 k.impl(), userid, 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startAddUid(const Key &k, const char *userid)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_adduid_start(d->ctx,
Packit d7e8d0
                 k.impl(), userid, 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::revUid(const Key &k, const char *userid)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_revuid(d->ctx,
Packit d7e8d0
                 k.impl(), userid, 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startRevUid(const Key &k, const char *userid)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_revuid_start(d->ctx,
Packit d7e8d0
                 k.impl(), userid, 0));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::createSubkey(const Key &k, const char *algo,
Packit d7e8d0
                            unsigned long reserved,
Packit d7e8d0
                            unsigned long expires,
Packit d7e8d0
                            unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_createsubkey(d->ctx,
Packit d7e8d0
                 k.impl(), algo, reserved, expires, flags));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::startCreateSubkey(const Key &k, const char *algo,
Packit d7e8d0
                                 unsigned long reserved,
Packit d7e8d0
                                 unsigned long expires,
Packit d7e8d0
                                 unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_createsubkey_start(d->ctx,
Packit d7e8d0
                 k.impl(), algo, reserved, expires, flags));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
// Engine Spawn stuff
Packit d7e8d0
Error Context::spawn(const char *file, const char *argv[],
Packit d7e8d0
                     Data &input, Data &output, Data &err,
Packit d7e8d0
                     SpawnFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_spawn (d->ctx, file, argv,
Packit d7e8d0
        input.impl() ? input.impl()->data : nullptr,
Packit d7e8d0
        output.impl() ? output.impl()->data : nullptr,
Packit d7e8d0
        err.impl() ? err.impl()->data : nullptr,
Packit d7e8d0
        static_cast<int>(flags)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Error Context::spawnAsync(const char *file, const char *argv[],
Packit d7e8d0
                          Data &input, Data &output, Data &err,
Packit d7e8d0
                          SpawnFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    return Error(d->lasterr = gpgme_op_spawn_start (d->ctx, file, argv,
Packit d7e8d0
        input.impl() ? input.impl()->data : nullptr,
Packit d7e8d0
        output.impl() ? output.impl()->data : nullptr,
Packit d7e8d0
        err.impl() ? err.impl()->data : nullptr,
Packit d7e8d0
        static_cast<int>(flags)));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, Protocol proto)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::Protocol(";
Packit d7e8d0
    switch (proto) {
Packit d7e8d0
    case OpenPGP:
Packit d7e8d0
        os << "OpenPGP";
Packit d7e8d0
        break;
Packit d7e8d0
    case CMS:
Packit d7e8d0
        os << "CMS";
Packit d7e8d0
        break;
Packit d7e8d0
    default:
Packit d7e8d0
    case UnknownProtocol:
Packit d7e8d0
        os << "UnknownProtocol";
Packit d7e8d0
        break;
Packit d7e8d0
    }
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, Engine eng)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::Engine(";
Packit d7e8d0
    switch (eng) {
Packit d7e8d0
    case GpgEngine:
Packit d7e8d0
        os << "GpgEngine";
Packit d7e8d0
        break;
Packit d7e8d0
    case GpgSMEngine:
Packit d7e8d0
        os << "GpgSMEngine";
Packit d7e8d0
        break;
Packit d7e8d0
    case GpgConfEngine:
Packit d7e8d0
        os << "GpgConfEngine";
Packit d7e8d0
        break;
Packit d7e8d0
    case AssuanEngine:
Packit d7e8d0
        os << "AssuanEngine";
Packit d7e8d0
        break;
Packit d7e8d0
    case SpawnEngine:
Packit d7e8d0
        os << "SpawnEngine";
Packit d7e8d0
        break;
Packit d7e8d0
    default:
Packit d7e8d0
    case UnknownEngine:
Packit d7e8d0
        os << "UnknownEngine";
Packit d7e8d0
        break;
Packit d7e8d0
    }
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, Context::CertificateInclusion incl)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::Context::CertificateInclusion(" << static_cast<int>(incl);
Packit d7e8d0
    switch (incl) {
Packit d7e8d0
    case Context::DefaultCertificates:
Packit d7e8d0
        os << "(DefaultCertificates)";
Packit d7e8d0
        break;
Packit d7e8d0
    case Context::AllCertificatesExceptRoot:
Packit d7e8d0
        os << "(AllCertificatesExceptRoot)";
Packit d7e8d0
        break;
Packit d7e8d0
    case Context::AllCertificates:
Packit d7e8d0
        os << "(AllCertificates)";
Packit d7e8d0
        break;
Packit d7e8d0
    case Context::NoCertificates:
Packit d7e8d0
        os << "(NoCertificates)";
Packit d7e8d0
        break;
Packit d7e8d0
    case Context::OnlySenderCertificate:
Packit d7e8d0
        os << "(OnlySenderCertificate)";
Packit d7e8d0
        break;
Packit d7e8d0
    }
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, KeyListMode mode)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::KeyListMode(";
Packit d7e8d0
#define CHECK( x ) if ( !(mode & (x)) ) {} else do { os << #x " "; } while (0)
Packit d7e8d0
    CHECK(Local);
Packit d7e8d0
    CHECK(Extern);
Packit d7e8d0
    CHECK(Signatures);
Packit d7e8d0
    CHECK(Validate);
Packit d7e8d0
    CHECK(Ephemeral);
Packit d7e8d0
    CHECK(WithTofu);
Packit d7e8d0
#undef CHECK
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, SignatureMode mode)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::SignatureMode(";
Packit d7e8d0
    switch (mode) {
Packit d7e8d0
#define CHECK( x ) case x: os << #x; break
Packit d7e8d0
        CHECK(NormalSignatureMode);
Packit d7e8d0
        CHECK(Detached);
Packit d7e8d0
        CHECK(Clearsigned);
Packit d7e8d0
#undef CHECK
Packit d7e8d0
    default:
Packit d7e8d0
        os << "???" "(" << static_cast<int>(mode) << ')';
Packit d7e8d0
        break;
Packit d7e8d0
    }
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, Context::EncryptionFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::Context::EncryptionFlags(";
Packit d7e8d0
#define CHECK( x ) if ( !(flags & (Context::x)) ) {} else do { os << #x " "; } while (0)
Packit d7e8d0
    CHECK(AlwaysTrust);
Packit d7e8d0
    CHECK(NoEncryptTo);
Packit d7e8d0
    CHECK(Prepare);
Packit d7e8d0
    CHECK(ExpectSign);
Packit d7e8d0
    CHECK(NoCompress);
Packit d7e8d0
    CHECK(Symmetric);
Packit d7e8d0
#undef CHECK
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &operator<<(std::ostream &os, Context::AuditLogFlags flags)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::Context::AuditLogFlags(";
Packit d7e8d0
#define CHECK( x ) if ( !(flags & (Context::x)) ) {} else do { os << #x " "; } while (0)
Packit d7e8d0
    CHECK(HtmlAuditLog);
Packit d7e8d0
    CHECK(AuditLogWithHelp);
Packit d7e8d0
#undef CHECK
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
} // namespace GpgME
Packit d7e8d0
Packit d7e8d0
GpgME::Error GpgME::setDefaultLocale(int cat, const char *val)
Packit d7e8d0
{
Packit d7e8d0
    return Error(gpgme_set_locale(0, cat, val));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::EngineInfo GpgME::engineInfo(GpgME::Protocol proto)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_engine_info_t ei = 0;
Packit d7e8d0
    if (gpgme_get_engine_info(&ei)) {
Packit d7e8d0
        return EngineInfo();
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    const gpgme_protocol_t p = proto == CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ;
Packit d7e8d0
Packit d7e8d0
    for (gpgme_engine_info_t i = ei ; i ; i = i->next) {
Packit d7e8d0
        if (i->protocol == p) {
Packit d7e8d0
            return EngineInfo(i);
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    return EngineInfo();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *GpgME::dirInfo(const char *what)
Packit d7e8d0
{
Packit d7e8d0
    return gpgme_get_dirinfo(what);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::Error GpgME::checkEngine(GpgME::Protocol proto)
Packit d7e8d0
{
Packit d7e8d0
    const gpgme_protocol_t p = proto == CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ;
Packit d7e8d0
Packit d7e8d0
    return Error(gpgme_engine_check_version(p));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static const gpgme_protocol_t UNKNOWN_PROTOCOL = static_cast<gpgme_protocol_t>(255);
Packit d7e8d0
Packit d7e8d0
static gpgme_protocol_t engine2protocol(const GpgME::Engine engine)
Packit d7e8d0
{
Packit d7e8d0
    switch (engine) {
Packit d7e8d0
    case GpgME::GpgEngine:   return GPGME_PROTOCOL_OpenPGP;
Packit d7e8d0
    case GpgME::GpgSMEngine: return GPGME_PROTOCOL_CMS;
Packit d7e8d0
    case GpgME::GpgConfEngine:
Packit d7e8d0
        return GPGME_PROTOCOL_GPGCONF;
Packit d7e8d0
    case GpgME::AssuanEngine:
Packit d7e8d0
        return GPGME_PROTOCOL_ASSUAN;
Packit d7e8d0
    case GpgME::G13Engine:
Packit d7e8d0
        return GPGME_PROTOCOL_G13;
Packit d7e8d0
    case GpgME::SpawnEngine:
Packit d7e8d0
        return GPGME_PROTOCOL_SPAWN;
Packit d7e8d0
    case GpgME::UnknownEngine:
Packit d7e8d0
        ;
Packit d7e8d0
    }
Packit d7e8d0
    return UNKNOWN_PROTOCOL;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::EngineInfo GpgME::engineInfo(GpgME::Engine engine)
Packit d7e8d0
{
Packit d7e8d0
    gpgme_engine_info_t ei = 0;
Packit d7e8d0
    if (gpgme_get_engine_info(&ei)) {
Packit d7e8d0
        return EngineInfo();
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    const gpgme_protocol_t p = engine2protocol(engine);
Packit d7e8d0
Packit d7e8d0
    for (gpgme_engine_info_t i = ei ; i ; i = i->next) {
Packit d7e8d0
        if (i->protocol == p) {
Packit d7e8d0
            return EngineInfo(i);
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    return EngineInfo();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::Error GpgME::checkEngine(GpgME::Engine engine)
Packit d7e8d0
{
Packit d7e8d0
    const gpgme_protocol_t p = engine2protocol(engine);
Packit d7e8d0
Packit d7e8d0
    return Error(gpgme_engine_check_version(p));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
static const unsigned long supported_features = 0
Packit d7e8d0
        | GpgME::ValidatingKeylistModeFeature
Packit d7e8d0
        | GpgME::CancelOperationFeature
Packit d7e8d0
        | GpgME::WrongKeyUsageFeature
Packit d7e8d0
        | GpgME::DefaultCertificateInclusionFeature
Packit d7e8d0
        | GpgME::GetSetEngineInfoFeature
Packit d7e8d0
        | GpgME::ClearAddGetSignatureNotationsFeature
Packit d7e8d0
        | GpgME::SetDataFileNameFeeature
Packit d7e8d0
        | GpgME::SignatureNotationsKeylistModeFeature
Packit d7e8d0
        | GpgME::KeySignatureNotationsFeature
Packit d7e8d0
        | GpgME::KeyIsQualifiedFeature
Packit d7e8d0
        | GpgME::SignatureNotationsCriticalFlagFeature
Packit d7e8d0
        | GpgME::SignatureNotationsFlagsFeature
Packit d7e8d0
        | GpgME::SignatureNotationsHumanReadableFlagFeature
Packit d7e8d0
        | GpgME::SubkeyIsQualifiedFeature
Packit d7e8d0
        | GpgME::EngineInfoHomeDirFeature
Packit d7e8d0
        | GpgME::DecryptionResultFileNameFeature
Packit d7e8d0
        | GpgME::DecryptionResultRecipientsFeature
Packit d7e8d0
        | GpgME::VerificationResultFileNameFeature
Packit d7e8d0
        | GpgME::SignaturePkaFieldsFeature
Packit d7e8d0
        | GpgME::SignatureAlgorithmFieldsFeature
Packit d7e8d0
        | GpgME::FdPointerFeature
Packit d7e8d0
        | GpgME::AuditLogFeature
Packit d7e8d0
        | GpgME::GpgConfEngineFeature
Packit d7e8d0
        | GpgME::CancelOperationAsyncFeature
Packit d7e8d0
        | GpgME::NoEncryptToEncryptionFlagFeature
Packit d7e8d0
        | GpgME::CardKeyFeature
Packit d7e8d0
        | GpgME::AssuanEngineFeature
Packit d7e8d0
        | GpgME::EphemeralKeylistModeFeature
Packit d7e8d0
        | GpgME::ImportFromKeyserverFeature
Packit d7e8d0
        | GpgME::G13VFSFeature
Packit d7e8d0
        | GpgME::PasswdFeature
Packit d7e8d0
        ;
Packit d7e8d0
Packit d7e8d0
static const unsigned long supported_features2 = 0
Packit d7e8d0
        | GpgME::BinaryAndFineGrainedIdentify
Packit d7e8d0
        ;
Packit d7e8d0
Packit d7e8d0
bool GpgME::hasFeature(unsigned long features)
Packit d7e8d0
{
Packit d7e8d0
    return features == (features & supported_features);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
bool GpgME::hasFeature(unsigned long features, unsigned long features2)
Packit d7e8d0
{
Packit d7e8d0
    return features  == (features  & supported_features)
Packit d7e8d0
           && features2 == (features2 & supported_features2)
Packit d7e8d0
           ;
Packit d7e8d0
}