/* ############################################################################# * * Description initialize the GPGME library * Author Harry Brueckner * Date 2005-03-30 * Arguments void * Return void */ void initGPG(void) { gpgme_error_t error; gpgme_check_version(NULL); TRACE(99, "initGPG()", NULL); error = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if (error) { gpgError(error); exit(1); } if (!gpgme_check_version(GPG_VERSION_MINIMUM)) { fprintf(stderr, _("GpgMe error: invalid library version (%s).\n"), gpgme_check_version(NULL)); exit(1); } retries = 0; signers = 0; lastrealm = NULL; }
void GPGWrapper::init() { if (initialized) return; initialized = true; gpgme_check_version(NULL); setlocale(LC_ALL, ""); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); #ifdef LC_MESSAGES gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); #endif gpgme_error_t error = gpgme_new(&context); fail_if_err(error, L"Nie uda³o siê zainicjowaæ kontekstu GPG."); gpgme_set_textmode(context, 1); gpgme_set_armor(context, 1); error = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); fail_if_err(error, L"Nie zainstalowano OpenPGP."); error = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP); fail_if_err(error, L"Nie uda³o siê ustawiæ OpenPGP."); privateKey = getPrivateKey(privateKeyId.c_str()); error = gpgme_signers_add(context, privateKey); fail_if_err(error, L"Nie uda³o siê ustawiæ klucza prywatnego."); }
/** * g_mime_pkcs7_context_new: * @request_passwd: a #GMimePasswordRequestFunc * * Creates a new pkcs7 crypto context object. * * Returns: (transfer full): a new pkcs7 crypto context object. **/ GMimeCryptoContext * g_mime_pkcs7_context_new (GMimePasswordRequestFunc request_passwd) { #ifdef ENABLE_SMIME GMimeCryptoContext *crypto; GMimePkcs7Context *pkcs7; gpgme_ctx_t ctx; /* make sure GpgMe supports the CMS protocols */ if (gpgme_engine_check_version (GPGME_PROTOCOL_CMS) != GPG_ERR_NO_ERROR) return NULL; /* create the GpgMe context */ if (gpgme_new (&ctx) != GPG_ERR_NO_ERROR) return NULL; pkcs7 = g_object_newv (GMIME_TYPE_PKCS7_CONTEXT, 0, NULL); gpgme_set_passphrase_cb (ctx, pkcs7_passphrase_cb, pkcs7); gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); pkcs7->priv->ctx = ctx; crypto = (GMimeCryptoContext *) pkcs7; crypto->request_passwd = request_passwd; return crypto; #else return NULL; #endif /* ENABLE_SMIME */ }
/** * Initialize the GPGME library. * This can be safely called multiple times; however it is not thread-safe. * @param handle the context handle * @return 0 on success, -1 on error */ static int init_gpgme(alpm_handle_t *handle) { static int init = 0; const char *version, *sigdir; gpgme_error_t gpg_err; gpgme_engine_info_t enginfo; if(init) { /* we already successfully initialized the library */ return 0; } sigdir = handle->gpgdir; if(_alpm_access(handle, sigdir, "pubring.gpg", R_OK) || _alpm_access(handle, sigdir, "trustdb.gpg", R_OK)) { handle->pm_errno = ALPM_ERR_NOT_A_FILE; _alpm_log(handle, ALPM_LOG_DEBUG, "Signature verification will fail!\n"); _alpm_log(handle, ALPM_LOG_WARNING, _("Public keyring not found; have you run '%s'?\n"), "pacman-key --init"); } /* calling gpgme_check_version() returns the current version and runs * some internal library setup code */ version = gpgme_check_version(NULL); _alpm_log(handle, ALPM_LOG_DEBUG, "GPGME version: %s\n", version); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); #ifdef LC_MESSAGES gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); #endif /* NOTE: * The GPGME library installs a SIGPIPE signal handler automatically if * the default signal hander is in use. The only time we set a handler * for SIGPIPE is in dload.c, and we reset it when we are done. Given that * we do this, we can let GPGME do its automagic. However, if we install * a library-wide SIGPIPE handler, we will have to be careful. */ /* check for OpenPGP support (should be a no-brainer, but be safe) */ gpg_err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); CHECK_ERR(); /* set and check engine information */ gpg_err = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, sigdir); CHECK_ERR(); gpg_err = gpgme_get_engine_info(&enginfo); CHECK_ERR(); _alpm_log(handle, ALPM_LOG_DEBUG, "GPGME engine info: file=%s, home=%s\n", enginfo->file_name, enginfo->home_dir); init = 1; return 0; gpg_error: _alpm_log(handle, ALPM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(gpg_err)); RET_ERR(handle, ALPM_ERR_GPGME, -1); }
int op_gpgme_init (void) { gpgme_error_t err; if (init_done) return 0; err = op_gpgme_basic_init (); if (err) return err; err = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (err) { log_debug ("gpgme can't find a suitable OpenPGP backend: %s\n", gpgme_strerror (err)); return err; } err = gpgme_engine_check_version (GPGME_PROTOCOL_CMS); if (err) { log_debug ("gpgme can't find a suitable CMS backend: %s\n", gpgme_strerror (err)); return err; } { HANDLE th; DWORD tid; waiter_thread_handle = INVALID_HANDLE_VALUE; InitializeCriticalSection (&waiter_thread_lock); th = CreateThread (NULL, 128*1024, waiter_thread, NULL, 0, &tid); if (th == INVALID_HANDLE_VALUE) log_error ("failed to start the gpgme waiter thread\n"); else waiter_thread_handle = th; } init_done = 1; return 0; }
static gpgme_key_t prompt_signer () { gpgme_error_t gerr = 0; CryptUIKeyset *keyset; CryptUIKeyStore *ckstore; gpgme_key_t key = NULL; gpgme_ctx_t ctx = NULL; gchar *signer; gchar *id; guint count; GList *keys; keyset = cryptui_keyset_new ("openpgp", TRUE); ckstore = cryptui_key_store_new (keyset, TRUE, NULL); cryptui_key_store_set_filter (ckstore, signer_filter, NULL); count = cryptui_key_store_get_count (ckstore); if (count == 0) { cryptui_need_to_get_keys (); return NULL; } else if (count == 1) { keys = cryptui_key_store_get_all_keys (ckstore); signer = (gchar*) keys->data; g_list_free (keys); } else { signer = cryptui_prompt_signer (keyset, _("Choose Signer")); } if (signer) { id = cryptui_keyset_key_raw_keyid (keyset, signer); g_free (signer); gpgme_check_version (NULL); gerr = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); g_return_val_if_fail (gerr == 0, NULL); gerr = gpgme_new (&ctx); g_return_val_if_fail (gerr == 0, NULL); /* Load up the GPGME secret key */ gerr = gpgme_get_key (ctx, id, &key, 1); g_free (id); gpgme_release (ctx); if (gerr != 0) seahorse_util_handle_gpgme (gerr, _("Couldn't load keys")); } g_object_unref (ckstore); g_object_unref (keyset); return key; }
static gpgme_error_t geanypg_init_gpgme(void) { /* Initialize the locale environment. */ setlocale(LC_ALL, ""); fprintf(stderr, "GeanyPG: %s %s\n", _("Using libgpgme version:"), gpgme_check_version("1.1.0")); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); #ifdef LC_MESSAGES /* only necessary for portability to W32 systems */ gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); #endif return gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); }
c_gpgme::c_gpgme() { setlocale (LC_ALL, ""); gpgme_set_locale(nullptr, LC_CTYPE, setlocale (LC_CTYPE, nullptr)); gpgme_check_version(nullptr); m_error_code = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); m_error_code = gpgme_new(&m_ctx); assert(m_ctx != nullptr); #ifdef __CYGWIN__ m_error_code = gpgme_ctx_set_engine_info (m_ctx, GPGME_PROTOCOL_OpenPGP, "./gpg.exe", nullptr); #endif }
static int init_gpgme(alpm_handle_t *handle) { static int init = 0; const char *version, *sigdir; gpgme_error_t err; gpgme_engine_info_t enginfo; if(init) { /* we already successfully initialized the library */ return 0; } sigdir = alpm_option_get_gpgdir(handle); /* calling gpgme_check_version() returns the current version and runs * some internal library setup code */ version = gpgme_check_version(NULL); _alpm_log(handle, ALPM_LOG_DEBUG, "GPGME version: %s\n", version); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); #ifdef LC_MESSAGES gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); #endif /* NOTE: * The GPGME library installs a SIGPIPE signal handler automatically if * the default signal hander is in use. The only time we set a handler * for SIGPIPE is in dload.c, and we reset it when we are done. Given that * we do this, we can let GPGME do its automagic. However, if we install * a library-wide SIGPIPE handler, we will have to be careful. */ /* check for OpenPGP support (should be a no-brainer, but be safe) */ err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); CHECK_ERR(); /* set and check engine information */ err = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, sigdir); CHECK_ERR(); err = gpgme_get_engine_info(&enginfo); CHECK_ERR(); _alpm_log(handle, ALPM_LOG_DEBUG, "GPGME engine info: file=%s, home=%s\n", enginfo->file_name, enginfo->home_dir); init = 1; return 0; error: _alpm_log(handle, ALPM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); RET_ERR(handle, ALPM_ERR_GPGME, 1); }
gboolean init_gpgme() { gpgme_error_t err; gpgme_check_version(NULL); setlocale(LC_ALL, ""); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if (err) { return FALSE; } return TRUE; }
void init_gpgme (gpgme_protocol_t proto) { gpgme_error_t err; gpgme_check_version (NULL); setlocale (LC_ALL, ""); gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); #ifndef HAVE_W32_SYSTEM gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); #endif err = gpgme_engine_check_version (proto); fail_if_err (err); }
void KGpgMe::init(gpgme_protocol_t proto) { gpgme_error_t err; gpgme_check_version(NULL); setlocale(LC_ALL, ""); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); err = gpgme_engine_check_version(proto); if(err) { KMessageBox::error(kapp->activeWindow(), QString("%1: %2") .arg(gpgme_strsource(err)).arg(gpgme_strerror(err))); } }
int init_gpgme(fko_ctx_t fko_ctx) { gpgme_error_t err; /* If we already have a context, we are done. */ if(fko_ctx->have_gpgme_context) return(FKO_SUCCESS); /* Because the gpgme manual says you should. */ gpgme_check_version(NULL); /* Check for OpenPGP support */ err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { /* GPG engine is not available. */ fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_NO_OPENPGP); } /* Extract the current gpgme engine information. */ gpgme_set_engine_info( GPGME_PROTOCOL_OpenPGP, (fko_ctx->gpg_exe != NULL) ? fko_ctx->gpg_exe : GPG_EXE, fko_ctx->gpg_home_dir /* If this is NULL, the default is used */ ); /* Create our gpgme context */ err = gpgme_new(&(fko_ctx->gpg_ctx)); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_CONTEXT); } fko_ctx->have_gpgme_context = 1; return(FKO_SUCCESS); }
int setup(gpgme_ctx_t* ctx) { char *p; gpgme_error_t err; gpgme_engine_info_t enginfo; setlocale (LC_ALL, ""); p = (char *) gpgme_check_version(NULL); printf("version=%s\n",p); /* set locale, because tests do also */ gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); /* check for OpenPGP support */ err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if(err != GPG_ERR_NO_ERROR) return 1; p = (char *) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP); printf("Protocol name: %s\n",p); /* get engine information */ err = gpgme_get_engine_info(&enginfo); if(err != GPG_ERR_NO_ERROR) return 2; printf("file=%s, home=%s\n",enginfo->file_name,enginfo->home_dir); /* create our own context */ err = gpgme_new(ctx); if(err != GPG_ERR_NO_ERROR) return 3; /* set protocol to use in our context */ err = gpgme_set_protocol(*ctx,GPGME_PROTOCOL_OpenPGP); if(err != GPG_ERR_NO_ERROR) return 4; /* set engine info in our context; I changed it for ceof like this: err = gpgme_ctx_set_engine_info (*ctx, GPGME_PROTOCOL_OpenPGP, "/usr/bin/gpg","/home/user/nico/.ceof/gpg/"); but I'll use standard values for this example: */ err = gpgme_ctx_set_engine_info (*ctx, GPGME_PROTOCOL_OpenPGP, enginfo->file_name,enginfo->home_dir); if(err != GPG_ERR_NO_ERROR) return 5; return 0; }
void CGPGHelper::Start() { #ifdef HAVE_LIBGPGME char buf[MAX_LINE_LEN]; snprintf(buf, MAX_LINE_LEN, "%s/licq_gpg.conf", BASE_DIR); mKeysIni.LoadFile(buf); mKeysIni.SetSection("gpg"); mKeysIni.ReadStr("passphrase", buf); mGPGPassphrase = strdup(buf); const char *gpgme_ver = gpgme_check_version(0); gLog.Info("%s[GPG] gpgme library found: %s\n", L_INITxSTR, gpgme_ver); if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPG_ERR_NO_ERROR) gLog.Error("%s[GPG] gpgme engine OpenPGP not found!\n", L_ERRORxSTR); gpgme_new(&mCtx); gpgme_set_protocol(mCtx, GPGME_PROTOCOL_OpenPGP); gpgme_set_armor(mCtx, 1); gpgme_set_passphrase_cb(mCtx, PassphraseCallback, 0); #endif }
retvalue signature_init(bool allowpassphrase){ #ifdef HAVE_LIBGPGME gpg_error_t err; if (context != NULL) return RET_NOTHING; gpgme_check_version(NULL); err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if (err != 0) return gpgerror(err); err = gpgme_new(&context); if (err != 0) return gpgerror(err); err = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP); if (err != 0) return gpgerror(err); if (allowpassphrase) gpgme_set_passphrase_cb(context, signature_getpassphrase, NULL); gpgme_set_armor(context, 1); #endif /* HAVE_LIBGPGME */ return RET_OK; }
static gpgme_key_t* prompt_recipients (gpgme_key_t *signkey) { gpgme_error_t gerr = 0; CryptUIKeyset *keyset; gpgme_ctx_t ctx; gpgme_key_t key; GArray *keys; gchar **recips; gchar *signer; *signkey = NULL; keyset = cryptui_keyset_new ("openpgp", TRUE); if (cryptui_keyset_get_count (keyset) == 0) { cryptui_need_to_get_keys (); } else { recips = cryptui_prompt_recipients (keyset, _("Choose Recipients"), &signer); if (recips) { gpgme_check_version (NULL); gerr = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); g_return_val_if_fail (gerr == 0, NULL); gerr = gpgme_new (&ctx); g_return_val_if_fail (gerr == 0, NULL); if (signer) { /* Load up the GPGME secret key */ gchar *id = cryptui_keyset_key_raw_keyid (keyset, signer); gerr = gpgme_get_key (ctx, id, signkey, 1); g_free (id); /* A more descriptive error message */ if (GPG_ERR_EOF == gpgme_err_code (gerr)) gerr = gpgme_error (GPG_ERR_NOT_FOUND); } if (gerr == 0) { gchar **ids; guint num; /* Load up the GPGME keys */ ids = cryptui_keyset_keys_raw_keyids (keyset, (const gchar**)recips); num = g_strv_length (ids); keys = g_array_new (TRUE, TRUE, sizeof (gpgme_key_t)); gerr = gpgme_op_keylist_ext_start (ctx, (const gchar**)ids, 0, 0); g_free (ids); if (gerr == 0) { while ((gerr = gpgme_op_keylist_next (ctx, &key)) == 0) g_array_append_val (keys, key); gpgme_op_keylist_end (ctx); } /* Ignore EOF error */ if (GPG_ERR_EOF == gpgme_err_code (gerr)) gerr = 0; if (gerr == 0 && num != keys->len) g_warning ("couldn't load all the keys (%d/%d) from GPGME", keys->len, num); } gpgme_release (ctx); } g_object_unref (keyset); if (!recips) return NULL; g_strfreev (recips); g_free (signer); if (gerr == 0 && keys->len) return (gpgme_key_t*)g_array_free (keys, FALSE); /* When failure, free all our return values */ seahorse_util_free_keys ((gpgme_key_t*)g_array_free (keys, FALSE)); if (*signkey) gpgme_key_unref (*signkey); seahorse_util_handle_gpgme (gerr, _("Couldn't load keys")); } return NULL; }
void sgpgme_init() { gchar *ctype_locale = NULL, *messages_locale = NULL; gchar *ctype_utf8_locale = NULL, *messages_utf8_locale = NULL; gpgme_engine_info_t engineInfo; if (gpgme_check_version("1.0.0")) { #ifdef LC_CTYPE debug_print("setting gpgme CTYPE locale\n"); #ifdef G_OS_WIN32 ctype_locale = g_win32_getlocale(); #else ctype_locale = g_strdup(setlocale(LC_CTYPE, NULL)); #endif if (ctype_locale) { debug_print("setting gpgme CTYPE locale to: %s\n", ctype_locale); if (strchr(ctype_locale, '.')) *(strchr(ctype_locale, '.')) = '\0'; else if (strchr(ctype_locale, '@')) *(strchr(ctype_locale, '@')) = '\0'; ctype_utf8_locale = g_strconcat(ctype_locale, ".UTF-8", NULL); debug_print("setting gpgme locale to UTF8: %s\n", ctype_utf8_locale ? ctype_utf8_locale : "NULL"); gpgme_set_locale(NULL, LC_CTYPE, ctype_utf8_locale); debug_print("done\n"); g_free(ctype_utf8_locale); g_free(ctype_locale); } else { debug_print("couldn't set gpgme CTYPE locale\n"); } #endif #ifdef LC_MESSAGES debug_print("setting gpgme MESSAGES locale\n"); #ifdef G_OS_WIN32 messages_locale = g_win32_getlocale(); #else messages_locale = g_strdup(setlocale(LC_MESSAGES, NULL)); #endif if (messages_locale) { debug_print("setting gpgme MESSAGES locale to: %s\n", messages_locale); if (strchr(messages_locale, '.')) *(strchr(messages_locale, '.')) = '\0'; else if (strchr(messages_locale, '@')) *(strchr(messages_locale, '@')) = '\0'; messages_utf8_locale = g_strconcat(messages_locale, ".UTF-8", NULL); debug_print("setting gpgme locale to UTF8: %s\n", messages_utf8_locale ? messages_utf8_locale : "NULL"); gpgme_set_locale(NULL, LC_MESSAGES, messages_utf8_locale); debug_print("done\n"); g_free(messages_utf8_locale); g_free(messages_locale); } else { debug_print("couldn't set gpgme MESSAGES locale\n"); } #endif if (!gpgme_get_engine_info(&engineInfo)) { while (engineInfo) { debug_print("GpgME Protocol: %s\n" "Version: %s (req %s)\n" "Executable: %s\n", gpgme_get_protocol_name(engineInfo->protocol) ? gpgme_get_protocol_name(engineInfo->protocol):"???", engineInfo->version ? engineInfo->version:"???", engineInfo->req_version ? engineInfo->req_version:"???", engineInfo->file_name ? engineInfo->file_name:"???"); if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP && gpgme_engine_check_version(engineInfo->protocol) != GPG_ERR_NO_ERROR) { if (engineInfo->file_name && !engineInfo->version) { alertpanel_error(_("Gpgme protocol '%s' is unusable: " "Engine '%s' isn't installed properly."), gpgme_get_protocol_name(engineInfo->protocol), engineInfo->file_name); } else if (engineInfo->file_name && engineInfo->version && engineInfo->req_version) { alertpanel_error(_("Gpgme protocol '%s' is unusable: " "Engine '%s' version %s is installed, " "but version %s is required.\n"), gpgme_get_protocol_name(engineInfo->protocol), engineInfo->file_name, engineInfo->version, engineInfo->req_version); } else { alertpanel_error(_("Gpgme protocol '%s' is unusable " "(unknown problem)"), gpgme_get_protocol_name(engineInfo->protocol)); } } engineInfo = engineInfo->next; } } } else { sgpgme_disable_all(); if (prefs_gpg_get_config()->gpg_warning) { AlertValue val; val = alertpanel_full (_("Warning"), _("GnuPG is not installed properly, or needs " "to be upgraded.\n" "OpenPGP support disabled."), GTK_STOCK_CLOSE, NULL, NULL, TRUE, NULL, ALERT_WARNING, G_ALERTDEFAULT); if (val & G_ALERTDISABLE) prefs_gpg_get_config()->gpg_warning = FALSE; } } }
GPGME_Error GPGME::init(const QString & gpgHomeDir) { if (instancesStore.contains(gpgHomeDir)) { return GPG_ERR_NO_ERROR; } setlocale(LC_ALL, ""); gpgme_check_version(NULL); gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); #ifdef LC_MESSAGES gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); #endif gpgme_error_t err; gpgme_ctx_t context; err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if (err != GPG_ERR_NO_ERROR) { return err; } QString protocolName = gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP); qDebug() << "protocol: " << protocolName; gpgme_engine_info_t engineInfo; err = gpgme_get_engine_info(&engineInfo); if (err != GPG_ERR_NO_ERROR) { return err; } qDebug() << "Backend info"; qDebug() << "filename: " << engineInfo->file_name << ", homedir: " << engineInfo->home_dir; err = gpgme_new(&context); if (err != GPG_ERR_NO_ERROR) { return err; } err = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP); if (err != GPG_ERR_NO_ERROR) { return err; } // we don't need to set gnupg home dir explicitly QString gnupgHome; if (gpgHomeDir.isEmpty()) { // i.e. use default gnupg directory or one from environment QString gnupgHomeEnv = QString::fromLatin1(qgetenv("GNUPGHOME")); if (!gnupgHomeEnv.isEmpty()) { gnupgHome = gnupgHomeEnv; } else { // use default path: "~/.gnupg" QDir gh = QDir::home(); gh.cd(".gnupg"); gnupgHome = gh.canonicalPath(); } } else { QDir gh(gpgHomeDir); gnupgHome = gh.canonicalPath(); } qDebug() << "GNUPGHOME" << gnupgHome; err = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_OpenPGP, engineInfo->file_name, gnupgHome.toLatin1().data() ); if (err != GPG_ERR_NO_ERROR) { return err; } GPGME * inst = new GPGME(context, gnupgHome); instancesStore[gpgHomeDir] = inst; qDebug() << "gpgme initalized for the directory " << gnupgHome << "[store key: " << gpgHomeDir << "]"; return GPG_ERR_NO_ERROR; }
gboolean lr_gpg_check_signature_fd(int signature_fd, int data_fd, const char *home_dir, GError **err) { gpgme_error_t gpgerr; gpgme_ctx_t context; gpgme_data_t signature_data; gpgme_data_t data_data; gpgme_verify_result_t result; gpgme_signature_t sig; assert(!err || *err == NULL); // Initialization gpgme_check_version(NULL); gpgerr = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_engine_check_version: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGNOTSUPPORTED, "gpgme_engine_check_version() error: %s", gpgme_strerror(gpgerr)); return FALSE; } gpgerr = gpgme_new(&context); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_new: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_new() error: %s", gpgme_strerror(gpgerr)); return FALSE; } gpgerr = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_set_protocol: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_set_protocol() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } if (home_dir) { gpgerr = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_OpenPGP, NULL, home_dir); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_ctx_set_engine_info: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_ctx_set_engine_info() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } } gpgme_set_armor(context, 1); gpgerr = gpgme_data_new_from_fd(&signature_data, signature_fd); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_data_new_from_fd: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_data_new_from_fd(_, %d) error: %s", signature_fd, gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } gpgerr = gpgme_data_new_from_fd(&data_data, data_fd); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_data_new_from_fd: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_data_new_from_fd(_, %d) error: %s", data_fd, gpgme_strerror(gpgerr)); gpgme_data_release(signature_data); gpgme_release(context); return FALSE; } // Verify gpgerr = gpgme_op_verify(context, signature_data, data_data, NULL); gpgme_data_release(signature_data); gpgme_data_release(data_data); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_op_verify: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_op_verify() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } result = gpgme_op_verify_result(context); if (!result) { g_debug("%s: gpgme_op_verify_result: error", __func__); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_op_verify_result() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } // Check result of verification sig = result->signatures; if(!sig) { g_debug("%s: signature verify error (no signatures)", __func__); g_set_error(err, LR_GPG_ERROR, LRE_BADGPG, "Signature verify error - no signatures"); gpgme_release(context); return FALSE; } // Example of signature usage could be found in gpgme git repository // in the gpgme/tests/run-verify.c for (; sig; sig = sig->next) { if ((sig->summary & GPGME_SIGSUM_VALID) || // Valid (sig->summary & GPGME_SIGSUM_GREEN) || // Valid (sig->summary == 0 && sig->status == GPG_ERR_NO_ERROR)) // Valid but key is not certified with a trusted signature { gpgme_release(context); return TRUE; } } gpgme_release(context); g_debug("%s: Bad GPG signature", __func__); g_set_error(err, LR_GPG_ERROR, LRE_BADGPG, "Bad GPG signature"); return FALSE; }
gboolean lr_gpg_import_key(const char *key_fn, const char *home_dir, GError **err) { gpgme_error_t gpgerr; int key_fd; gpgme_ctx_t context; gpgme_data_t key_data; assert(!err || *err == NULL); // Initialization gpgme_check_version(NULL); gpgerr = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_engine_check_version: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGNOTSUPPORTED, "gpgme_engine_check_version() error: %s", gpgme_strerror(gpgerr)); return FALSE; } gpgerr = gpgme_new(&context); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_new: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_new() error: %s", gpgme_strerror(gpgerr)); return FALSE; } gpgerr = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_set_protocol: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_set_protocol() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } if (home_dir) { gpgerr = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_OpenPGP, NULL, home_dir); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_ctx_set_engine_info: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_ctx_set_engine_info() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); return FALSE; } } gpgme_set_armor(context, 1); // Key import key_fd = open(key_fn, O_RDONLY); if (key_fd == -1) { g_debug("%s: Opening key: %s", __func__, strerror(errno)); g_set_error(err, LR_GPG_ERROR, LRE_IO, "Error while opening key %s: %s", key_fn, strerror(errno)); gpgme_release(context); return FALSE; } gpgerr = gpgme_data_new_from_fd(&key_data, key_fd); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_data_new_from_fd: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_data_new_from_fd(_, %d) error: %s", key_fd, gpgme_strerror(gpgerr)); gpgme_release(context); close(key_fd); return FALSE; } gpgerr = gpgme_op_import(context, key_data); gpgme_data_release(key_data); if (gpgerr != GPG_ERR_NO_ERROR) { g_debug("%s: gpgme_op_import: %s", __func__, gpgme_strerror(gpgerr)); g_set_error(err, LR_GPG_ERROR, LRE_GPGERROR, "gpgme_op_import() error: %s", gpgme_strerror(gpgerr)); gpgme_release(context); close(key_fd); return FALSE; } close(key_fd); gpgme_release(context); return TRUE; }
int main() { int fd; gpgme_ctx_t g_context; gpgme_engine_info_t enginfo; gpgme_data_t data; gpgme_error_t gerr; gpg_err_code_t gpg_err; gpgme_data_t g_plain; gpgme_data_t g_plain_recv; gpgme_data_t g_encrypt; gpgme_data_t g_encrypt_send; gpgme_key_t g_recipient[MAX_RCP+1]; char *p; char b_encrypt[BIGBUF+1]; char msg[EOF_L_MESSAGE]; char msg_in[EOF_L_MESSAGE]; int i, tmp; for(i=0;i<EOF_L_MESSAGE; i++) msg_in[i] = 0; for(i=0;i<EOF_L_MESSAGE; i++) msg[i] = 0; for(i=0;i<=BIGBUF; i++) b_encrypt[i] = 0; gpgme_check_version(NULL); gerr = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if(gerr != GPG_ERR_NO_ERROR) return 10; p = (char *) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP); printf("Version: %s\n",p); gerr = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, home); if(gerr == GPG_ERR_NO_ERROR) { printf("gpgme_set_engine_info: ok\n"); } else { printf("gpgme_set_engine_info: err\n"); } /* get engine information */ gerr = gpgme_get_engine_info(&enginfo); if(gerr != GPG_ERR_NO_ERROR) return 3; printf("file=%s, home=%s\n",enginfo->file_name,enginfo->home_dir); /* create our own context */ gerr = gpgme_new(&g_context); if(gerr != GPG_ERR_NO_ERROR) return 1; /* FIXME: both needed? */ /* FIXME: why is the path (FILE_NAME) needed? */ /* FIXME: /usr/bin/gpg must be changed to ~/.ceof/gpg/binary or similar */ gerr = gpgme_ctx_set_engine_info (g_context, GPGME_PROTOCOL_OpenPGP, "/usr/bin/gpg",home); if(gerr != GPG_ERR_NO_ERROR) return 4; /* do not ascii armor data; use 1 for testing */ //gpgme_set_armor(g_context, 0); gpgme_set_armor(g_context, 1); /* create buffers */ gerr = gpgme_data_new(&data); if(gerr != GPG_ERR_NO_ERROR) return 12; gerr = gpgme_data_new(&g_plain_recv); if(gerr != GPG_ERR_NO_ERROR) return 20; gerr = gpgme_data_new(&g_encrypt); if(gerr != GPG_ERR_NO_ERROR) return 14; gerr = gpgme_data_new(&g_encrypt_send); if(gerr != GPG_ERR_NO_ERROR) return 24; /* fill buffers */ /* gerr = gpgme_data_new(&g_plain); if(gerr != GPG_ERR_NO_ERROR) return 13; printf("strlen(%s) = %d\n",msg,i); i -= gpgme_data_write(g_plain, msg, i); if(i) { printf("size mismatch\n"); return 12; } */ strncpy(msg, "==> Erste Nachricht\n\n", EOF_L_MESSAGE); i = strlen(msg); gerr = gpgme_data_new_from_mem (&g_plain, msg, i, 0); /* setup recipient */ gerr = gpgme_op_keylist_start(g_context, "nico schottelius", 0); if(gerr != GPG_ERR_NO_ERROR) return 11; i=0; gerr = gpgme_op_keylist_next(g_context, &g_recipient[0]); while((gpg_err = gpg_err_code(gerr)) != GPG_ERR_EOF) { /* for testing: one call of gpgme_op_keylist_next is enough */ break; if(gerr == GPG_ERR_INV_VALUE) { printf("invalid pointer\n"); return 15; } else if(gerr == GPG_ERR_ENOMEM) { printf("no mem\n"); return 16; } printf ("%s: %s <%s> (%d)\n", g_recipient[0]->subkeys->keyid, g_recipient[0]->uids->name, g_recipient[0]->uids->email, i); i++; /* FIXME: this resets the good filled buffer ... */ gerr = gpgme_op_keylist_next(g_context, &g_recipient[0]); } g_recipient[1] = NULL; /* all above seems to be wrong ... */ gerr = gpgme_get_key(g_context,"775506B45998BF57D0D4AFF27C6E747C38616ADC", &g_recipient[0], 0); if(gerr != GPG_ERR_NO_ERROR) return 32; /* en/decrypt message */ //gerr = gpgme_op_encrypt_sign(g_context, g_recipient, 0, g_plain, g_encrypt); gerr = gpgme_op_encrypt(g_context, g_recipient, 0, g_plain, g_encrypt); if(gerr != GPG_ERR_NO_ERROR) { printf("gerr=%d\n",gerr); return 18; } /* transfer the data into our own buffer, * so the data is saved; you cannot * reuse the gpgme buffers directly as in * gerr = gpgme_op_decrypt(g_context, g_encrypt, g_plain_recv); * */ i = gpgme_data_seek(g_encrypt, 0, SEEK_END); if(i > BIGBUF) return 22; printf("buflen: %d\n",i); /* reset to the beginning */ gpgme_data_seek(g_encrypt, 0, SEEK_SET); if(gpgme_data_read(g_encrypt, b_encrypt, i) == -1) { perror("pgme_data_read"); return 23; } printf("crypt:\n%s\n", b_encrypt); fd = open("testcrypt",O_RDWR|O_CREAT); if(fd == -1) return 40; if(write_all(fd, b_encrypt, BIGBUF) <= 0) return 41; close(fd); /* until here it works, testcrypt contains * data and can be decrypted ... * * perhaps the context needs some reset? */ if((tmp = gpgme_data_write(g_encrypt_send, b_encrypt, i)) == -1) { perror("pgme_data_write"); return 23; } printf("crypt-wrote:%d\n", tmp); /* look for contexts */ gerr = gpgme_op_decrypt(g_context, g_encrypt_send, g_plain_recv); if(gerr != GPG_ERR_NO_ERROR) { printf("gerr=%d\n",gerr); return 19; } /* open communication channel: netcat */ /* listen for input from: * stdin * communication channel */ /* de/encode data from comm channel */ return 1; }
int main(int argc, char *argv[]) { char * op=(char *)0; char * search=(char *)0; char * searchdec=(char *)0; char * exact=(char *)0; gpgme_ctx_t gpgctx; gpgme_key_t gpgkey; gpgme_error_t gpgerr; gpgme_engine_info_t enginfo; char * qstring, * pchar; pchar=getenv("QUERY_STRING"); if (! pchar || *pchar == '\0' ) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: there is no query string.</h1></body></html>"); return 1; } qstring=strndup(pchar,QSTRING_MAX); /* copy the QUERY from env to write in */ pchar=qstring; while (pchar && *pchar) { if (!strncmp(pchar,"op=",3)) { pchar+=3; op=pchar; } else if (!strncmp(pchar,"search=",7)) { pchar+=7; search=pchar; } else if (!strncmp(pchar,"options=",8)) { /*this parameter is useless now, as today we only support "mr" option and always enable it (machine readable) */ pchar+=8; //options=pchar; } else if (!strncmp(pchar,"fingerprint=",12)) { /*this parameter is useless now as we only support "mr" options which don't care this */ pchar+=12; //fingerprints=pchar; } else if (!strncmp(pchar,"exact=",6)) { pchar+=6; exact=pchar; } /*else: Other parameter not in hkp draft are quietly ignored */ pchar=strchr(pchar,'&'); if (pchar) { *pchar='\0'; pchar++; } } if (exact) { if (!strcmp(exact,"off")) { exact=(char *) 0; /* off is default */ } else if (!strcmp(exact,"on")) { http_header(501,CTYPE_HTML_STR); printf("<html><head><title>Not implemented</title></head><body><h1>Error handling request: \"exact\" parameter is not implemented.</h1></body></html>"); return 1; } else { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: \"exact\" parameter only take \"on\" or \"off\" as argument.</h1></body></html>"); return 1; } } if ( ! search ) { /* (mandatory parameter) */ http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: Missing \"search\" parameter in \"%s\".</h1></body></html>",getenv("QUERY_STRING")); return 1; } else { if (searchdec=malloc(strlen(search)*sizeof(char)+1)) strdecode(searchdec,search); else { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Internal malloc(%d) for search fail.</h1></body></html>",strlen(search)*sizeof(char)+1); return 1; } } if ( ! op ) op="index"; /* defaut operation */ /* Check gpgme version ( http://www.gnupg.org/documentation/manuals/gpgme/Library-Version-Check.html )*/ setlocale (LC_ALL, ""); gpgme_check_version (NULL); gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); /* check for OpenPGP support */ gpgerr=gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if ( gpgerr != GPG_ERR_NO_ERROR ) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_engine_check_version).</h1></body></html>"); return 1; } /* create context */ gpgerr=gpgme_new(&gpgctx); if ( gpgerr != GPG_ERR_NO_ERROR ) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_new %d).</h1></body></html>",gpgerr); return 1; } /*gpgerr = gpgme_get_engine_info(&enginfo); gpgerr |= gpgme_ctx_set_engine_info(gpgctx, GPGME_PROTOCOL_OpenPGP, enginfo->file_name,"../../new"); if ( gpgerr != GPG_ERR_NO_ERROR ) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_ctx_set_engine_info %d).</h1></body></html>",gpgerr); return 1; }*/ if (!strcmp(op, "get")) { gpgme_data_t gpgdata; char buff[BUFFSIZE]; ssize_t read_bytes; gpgme_set_armor(gpgctx,1); gpgerr = gpgme_data_new(&gpgdata); if (gpgerr == GPG_ERR_NO_ERROR) { gpgerr = gpgme_data_set_encoding(gpgdata,GPGME_DATA_ENCODING_ARMOR); if (gpgerr == GPG_ERR_NO_ERROR) gpgerr = gpgme_op_export(gpgctx,searchdec,0,gpgdata); } if ( gpgerr != GPG_ERR_NO_ERROR) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (%d).</h1></body></html>",gpgerr); return 1; } gpgme_data_seek (gpgdata, 0, SEEK_SET); read_bytes = gpgme_data_read (gpgdata, buff, BUFFSIZE); if ( read_bytes == -1 ) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (%s).</h1></body></html>",gpgme_strerror(errno)); return 1; } else if ( read_bytes <= 0 ) { http_header(404,CTYPE_HTML_STR); printf("<html><head><title>ludd Public Key Server -- Get: %s</title></head><body><h1>Public Key Server -- Get: %s : No key found ! :-( </h1></body></html>",search,search); return 0; } else { http_header(200,CTYPE_HTML_STR); printf("<html><head><title>ludd Public Key Server -- Get: %s</title></head><body><h1>Public Key Server -- Get: %s</h1><pre>",search,search); fwrite(buff, sizeof(char),read_bytes,stdout); /* Now it's too late to test fwrite return value ;-) */ while ( (read_bytes = gpgme_data_read (gpgdata, buff, BUFFSIZE)) > 0 ) fwrite(buff, sizeof(char),read_bytes,stdout); printf("\n</pre></body></html>"); return 0; } } else if (!strcmp(op, "index")) { char uidenc[BUFFSIZE]; char begin=0; gpgme_user_id_t gpguid; /* check for the searched key(s) */ gpgerr = gpgme_op_keylist_start(gpgctx, searchdec, 0); //gpgerr = gpgme_op_keylist_start(gpgctx, NULL, 0); if ( gpgerr != GPG_ERR_NO_ERROR ) { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_op_keylist_start %d).</h1></body></html>",gpgerr); return 1; } gpgerr = gpgme_op_keylist_next (gpgctx, &gpgkey); while (gpgerr == GPG_ERR_NO_ERROR) { if (!begin) { http_header(200,"text/plain; charset=utf-8"); begin=1; /* Luckily: info "header" is optionnal, see draft-shaw-openpgp-hkp-00.txt */ } /* first subkey is the main key */ printf("pub:%s:%d:%d:%d:%d\n",gpgkey->subkeys->fpr,gpgkey->subkeys->pubkey_algo,gpgkey->subkeys->length,gpgkey->subkeys->timestamp,(gpgkey->subkeys->expires?gpgkey->subkeys->expires:-1)); gpguid=gpgkey->uids; while (gpguid) { printf("uid:%s (%s) <%s>:\n",gpguid->name,gpguid->comment,gpguid->email); gpguid=gpguid->next; } gpgme_key_unref(gpgkey); gpgerr = gpgme_op_keylist_next (gpgctx, &gpgkey); } gpgme_key_unref(gpgkey); /* ... because i don't know how "gpgme_op_keylist_next" behave when not returning GPG_ERR_NO_ERROR */ if (!begin) { http_header(404,CTYPE_HTML_STR); printf("<html><head><title>ludd Public Key Server -- index: %s</title></head><body><h1>index Error: No keys found</h1></body></html>",search); return 1; } return 0; } else if ( !strcmp(op, "photo") || !strcmp(op, "x-photo") ) { http_header(501,CTYPE_HTML_STR); printf("<html><head><title>Not implemented</title></head><body><h1>Error handling request: \"%s\" operation is not implemented.</h1></body></html>",op); return 1; } else { http_header(500,CTYPE_HTML_STR); printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: Unrecognized action in \"%s\".</h1></body></html>",getenv("QUERY_STRING")); return 1; } }
/** \brief Initialise GpgME * * \param get_passphrase Callback function to read a passphrase from the * user. Note that this function is used \em only for OpenPGP and * \em only if no GPG Agent is running and can therefore usually be * NULL. The first (HOOK) argument the passed function accepts * shall be the parent GtkWindow. * \param select_key Callback function to let the user select a key from a * list if more than one is available. * \param accept_low_trust Callback function to ask the user whether a low * trust key shall be accepted. * * Initialise the GpgME backend and remember the callback functions. * * \note This function \em must be called before using any other function * from this module. */ void libbalsa_gpgme_init(gpgme_passphrase_cb_t get_passphrase, lbgpgme_select_key_cb select_key, lbgpgme_accept_low_trust_cb accept_low_trust) { gpgme_engine_info_t e; const gchar *agent_info; /* initialise the gpgme library */ g_message("init gpgme version %s", gpgme_check_version(NULL)); #ifdef HAVE_GPG /* configure the GnuPG engine if a specific gpg path has been * detected */ gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, GPG_PATH, NULL); #endif #ifdef ENABLE_NLS gpgme_set_locale(NULL, LC_CTYPE, get_utf8_locale(LC_CTYPE)); gpgme_set_locale(NULL, LC_MESSAGES, get_utf8_locale(LC_MESSAGES)); #endif /* ENABLE_NLS */ /* dump the available engines */ if (gpgme_get_engine_info(&e) == GPG_ERR_NO_ERROR) { while (e) { g_message("protocol %s: engine %s (home %s, version %s)", gpgme_get_protocol_name(e->protocol), e->file_name, e->home_dir, e->version); e = e->next; } } /* check for gpg-agent */ agent_info = g_getenv("GPG_AGENT_INFO"); if (agent_info) { g_message("gpg-agent found: %s", agent_info); gpgme_passphrase_cb = NULL; } else { gpgme_passphrase_cb = get_passphrase; } /* verify that the engines we need are there */ if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) == GPG_ERR_NO_ERROR) { g_message("OpenPGP protocol supported"); has_proto_openpgp = TRUE; } else { g_warning ("OpenPGP protocol not supported, basic crypto will not work!"); has_proto_openpgp = FALSE; } #ifdef HAVE_SMIME if (gpgme_engine_check_version(GPGME_PROTOCOL_CMS) == GPG_ERR_NO_ERROR) { g_message("CMS (aka S/MIME) protocol supported"); has_proto_cms = TRUE; } else { g_warning("CMS protocol not supported, S/MIME will not work!"); has_proto_cms = FALSE; } #else g_message("built without CMS (aka S/MIME) protocol support"); has_proto_cms = FALSE; #endif /* remember callbacks */ select_key = select_key_cb; accept_low_trust = accept_low_trust_cb; }
gpointer sign_file (const gchar *input_file_path, const gchar *fpr) { gpgme_error_t error; gpgme_ctx_t context; gpgme_key_t signing_key; gpgme_data_t clear_text, signed_text; gpgme_sign_result_t result; gchar *buffer; gssize nbytes; error = gpgme_new (&context); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); return GPGME_ERROR; } gpgme_set_armor (context, 0); error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } const char *keyring_dir = gpgme_get_dirinfo ("homedir"); error = gpgme_ctx_set_engine_info (context, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_get_key (context, fpr, &signing_key, 1); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_signers_add (context, signing_key); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } FILE *infp = g_fopen (input_file_path, "r"); if (infp == NULL) { g_printerr ("Couldn't open input file\n"); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return FILE_OPEN_ERROR; } error = gpgme_data_new_from_stream (&clear_text, infp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_new (&signed_text); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_op_sign (context, clear_text, signed_text, GPGME_SIG_MODE_DETACH); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } result = gpgme_op_sign_result (context); if (result->invalid_signers) { g_printerr ("Invalid signer found: %s\n", result->invalid_signers->fpr); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } if (!result->signatures || result->signatures->next) { g_printerr ("Unexpected number of signatures created\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_seek (signed_text, 0, SEEK_SET); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } buffer = g_try_malloc0 (SIG_MAXLEN); if (buffer == NULL) { g_printerr ("Couldn't allocate memory\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return MEMORY_ALLOCATION_ERROR; } nbytes = gpgme_data_read (signed_text, buffer, SIG_MAXLEN); if (nbytes == -1) { g_printerr ("Error while reading data\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } GError *gerr = NULL; gchar *output_file_path = g_strconcat (input_file_path, ".sig", NULL); GFile *fpout = g_file_new_for_path (output_file_path); GFileOutputStream *ostream = g_file_append_to (fpout, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &gerr); if (gerr != NULL) { g_printerr ("Couldn't open output file for writing\n"); cleanup (infp, fpout, NULL, output_file_path, &signing_key, &context); return FILE_OPEN_ERROR; } gssize wbytes = g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer, nbytes, NULL, &gerr); if (wbytes == -1) { g_printerr ("Couldn't write the request number of bytes (%s)\n", gerr->message); cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return FILE_WRITE_ERROR; } cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return SIGN_OK; }
gpointer verify_signature (const gchar *detached_signature_path, const gchar *signed_file_path) { init_gpgme (); gpgme_ctx_t ctx; gpgme_signature_t sig; gpgme_data_t signature_data, signed_data; gpgme_error_t error = gpgme_new (&ctx); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); return GPGME_ERROR; } gpgme_set_armor (ctx, 1); error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } const char *keyring_dir = gpgme_get_dirinfo ("homedir"); error = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } FILE *sig_fp = g_fopen (detached_signature_path, "r"); FILE *sig_data_fp = g_fopen (signed_file_path, "r"); if (sig_fp == NULL || sig_data_fp == NULL) { g_printerr ("Couldn't open input file\n"); gpgme_release (ctx); return FILE_OPEN_ERROR; } error = gpgme_data_new_from_stream (&signature_data, sig_fp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); fclose (sig_fp); fclose (sig_data_fp); gpgme_release (ctx); return GPGME_ERROR; } error = gpgme_data_new_from_stream (&signed_data, sig_data_fp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); fclose (sig_fp); fclose (sig_data_fp); gpgme_release (ctx); gpgme_data_release (signature_data); return GPGME_ERROR; } error = gpgme_op_verify (ctx, signature_data, signed_data, NULL); gpgme_data_release (signature_data); gpgme_data_release (signed_data); fclose (sig_fp); fclose (sig_data_fp); if (error != GPG_ERR_NO_ERROR) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } gpgme_verify_result_t result = gpgme_op_verify_result (ctx); if (!result) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } sig = result->signatures; if (!sig) { gpgme_release (ctx); return NO_GPG_KEYS_AVAILABLE; } for (; sig; sig = sig->next) { if ((sig->summary & GPGME_SIGSUM_VALID) || (sig->summary & GPGME_SIGSUM_GREEN)) { gpgme_release (ctx); return SIGNATURE_OK; } else if (sig->summary == 0 && sig->status == GPG_ERR_NO_ERROR) { // Valid but key is not certified with a trusted signature gpgme_release (ctx); return SIGNATURE_OK_KEY_NOT_TRUSTED; } } gpgme_release (ctx); return BAD_SIGNATURE; }