/** * Determine if we have a key is known in our local keyring. * @param handle the context handle * @param fpr the fingerprint key ID to look up * @return 1 if key is known, 0 if key is unknown, -1 on error */ static int key_in_keychain(alpm_handle_t *handle, const char *fpr) { gpgme_error_t err; gpgme_ctx_t ctx; gpgme_key_t key; int ret = -1; memset(&ctx, 0, sizeof(ctx)); err = gpgme_new(&ctx); CHECK_ERR(); _alpm_log(handle, ALPM_LOG_DEBUG, "looking up key %s locally\n", fpr); err = gpgme_get_key(ctx, fpr, &key, 0); if(gpg_err_code(err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); ret = 0; } else if(gpg_err_code(err) == GPG_ERR_NO_ERROR) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup success, key exists\n"); ret = 1; } else { _alpm_log(handle, ALPM_LOG_DEBUG, "gpg error: %s\n", gpgme_strerror(err)); } gpgme_key_unref(key); error: gpgme_release(ctx); return ret; }
gboolean p_gpg_valid_key(const char *const keyid, char **err_str) { gpgme_ctx_t ctx; gpgme_error_t error = gpgme_new(&ctx); if (error) { log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); *err_str = strdup(gpgme_strerror(error)); return FALSE; } gpgme_key_t key = NULL; error = gpgme_get_key(ctx, keyid, &key, 1); if (error || key == NULL) { log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); *err_str = strdup(gpgme_strerror(error)); gpgme_release(ctx); return FALSE; } if (key == NULL) { *err_str = strdup("Unknown error"); gpgme_release(ctx); return FALSE; } gpgme_release(ctx); gpgme_key_unref(key); return TRUE; }
gboolean p_gpg_addkey(const char *const jid, const char *const keyid) { gpgme_ctx_t ctx; gpgme_error_t error = gpgme_new(&ctx); if (error) { log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); return FALSE; } gpgme_key_t key = NULL; error = gpgme_get_key(ctx, keyid, &key, 0); gpgme_release(ctx); if (error || key == NULL) { log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); return FALSE; } // save to public key file g_key_file_set_string(pubkeyfile, jid, "keyid", keyid); _save_pubkeys(); // update in memory pubkeys list ProfPGPPubKeyId *pubkeyid = malloc(sizeof(ProfPGPPubKeyId)); pubkeyid->id = strdup(keyid); pubkeyid->received = FALSE; g_hash_table_replace(pubkeys, strdup(jid), pubkeyid); gpgme_key_unref(key); return TRUE; }
int main (int argc, char *argv[]) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t in, out; gpgme_key_t key[3] = { NULL, NULL, NULL }; gpgme_encrypt_result_t result; init_gpgme (GPGME_PROTOCOL_OpenPGP); err = gpgme_new (&ctx); fail_if_err (err); gpgme_set_armor (ctx, 1); err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0); fail_if_err (err); err = gpgme_data_new (&out); fail_if_err (err); err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734", &key[0], 0); fail_if_err (err); err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", &key[1], 0); fail_if_err (err); err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); fail_if_err (err); result = gpgme_op_encrypt_result (ctx); if (result->invalid_recipients) { fprintf (stderr, "Invalid recipient encountered: %s\n", result->invalid_recipients->fpr); exit (1); } print_data (out); gpgme_key_unref (key[0]); gpgme_key_unref (key[1]); gpgme_data_release (in); gpgme_data_release (out); gpgme_release (ctx); return 0; }
/* ------------------ * check if a key is locally available * ------------------ */ int is_key_available(const char* fpr,int secret, int servermode, char** userid) { gpgme_error_t error; gpgme_ctx_t ctx; gpgme_key_t key; gpgme_key_t key_arr[2]; gpgme_keylist_mode_t current_keylist_mode; key_arr[0] = NULL; key_arr[1] = NULL; // connect to gpgme gpgme_check_version (NULL); error = gpgme_new(&ctx); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); return FALSE; } // set to server search mode if servermode == TRUE if (servermode == TRUE) { purple_debug_info(PLUGIN_ID,"set keylist mode to server\n"); current_keylist_mode = gpgme_get_keylist_mode(ctx); gpgme_set_keylist_mode(ctx,(current_keylist_mode | GPGME_KEYLIST_MODE_EXTERN) &(~GPGME_KEYLIST_MODE_LOCAL)); } // get key by fingerprint error = gpgme_get_key(ctx,fpr,&key,secret); if (error || !key) { purple_debug_error(PLUGIN_ID,"gpgme_get_key failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return FALSE; } // if we have parameter, tell caller about userid if (userid != NULL) { *userid = g_strdup(key->uids->uid); } // import key key_arr[0] = key; error = gpgme_op_import_keys (ctx, key_arr); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_op_import_keys failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return FALSE; } // close gpgme connection gpgme_release (ctx); // we got the key, YEAH :) return TRUE; }
/* ------------------ * get ascii armored public key * FREE MEMORY AFTER USAGE OF RETURN VALUE! * ------------------ */ char* get_key_armored(const char* fpr) { gpgme_error_t error; gpgme_ctx_t ctx; gpgme_data_t key_data; gpgme_key_t key; gpgme_key_t key_arr[2]; key_arr[0] = key_arr[1] = NULL; size_t len = 0; char* key_str = NULL; char* key_str_dup = NULL; // connect to gpgme gpgme_check_version (NULL); error = gpgme_new(&ctx); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); return NULL; } // get key by fingerprint error = gpgme_get_key(ctx,fpr,&key,0); if (error || !key) { purple_debug_error(PLUGIN_ID,"gpgme_get_key failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } key_arr[0] = key; // create data containers gpgme_data_new(&key_data); // export key gpgme_set_armor(ctx,1); error = gpgme_op_export_keys (ctx, key_arr, 0, key_data); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_op_export_keys failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } // release memory for data containers key_str = gpgme_data_release_and_get_mem(key_data,&len); if (key_str != NULL) { key_str[len] = 0; key_str_dup = g_strdup(key_str); } gpgme_free(key_str); // close gpgme connection gpgme_release (ctx); // we got the key, YEAH :) return key_str_dup; }
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 retvalue check_primary_keys(struct signatures *signatures) { /* Get the primary keys belonging to each signing key. This might also invalidate a signature previously believed valid if the primary key is expired */ int i; for (i = 0 ; i < signatures->count ; i++) { gpg_error_t err; gpgme_key_t gpgme_key = NULL; gpgme_subkey_t subkey; struct signature *sig = &signatures->signatures[i]; if (sig->state == sist_error || sig->state == sist_missing) { sig->primary_keyid = strdup(sig->keyid); if (FAILEDTOALLOC(sig->primary_keyid)) return RET_ERROR_OOM; continue; } err = gpgme_get_key(context, sig->keyid, &gpgme_key, 0); if (err != 0) { fprintf(stderr, "gpgme error %s:%d retrieving key '%s': %s\n", gpg_strsource(err), (int)gpg_err_code(err), sig->keyid, gpg_strerror(err)); if (gpg_err_code(err) == GPG_ERR_ENOMEM) return RET_ERROR_OOM; else return RET_ERROR_GPGME; } assert (gpgme_key != NULL); /* the first "sub"key is the primary key */ subkey = gpgme_key->subkeys; if (subkey->revoked) { sig->revoced_key = true; if (sig->state == sist_valid) { sig->state = sist_mostly; signatures->validcount--; } } if (subkey->expired) { sig->expired_key = true; if (sig->state == sist_valid) { sig->state = sist_mostly; signatures->validcount--; } } sig->primary_keyid = strdup(subkey->keyid); gpgme_key_unref(gpgme_key); if (FAILEDTOALLOC(sig->primary_keyid)) return RET_ERROR_OOM; } return RET_OK; }
bool KGpgMe::encrypt(const QByteArray& inBuffer, Q_ULONG length, QByteArray* outBuffer, QString keyid /* = QString::null */) { gpgme_error_t err = 0; gpgme_data_t in = 0, out = 0; gpgme_key_t keys[2] = { NULL, NULL }; gpgme_key_t* key = NULL; gpgme_encrypt_result_t result = 0; outBuffer->resize(0); if(m_ctx) { err = gpgme_data_new_from_mem(&in, inBuffer.data(), length, 1); if(!err) { err = gpgme_data_new(&out); if(!err) { if(keyid.isNull()) { key = NULL; } else { err = gpgme_get_key(m_ctx, keyid.ascii(), &keys[0], 0); key = keys; } if(!err) { err = gpgme_op_encrypt(m_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); if(!err) { result = gpgme_op_encrypt_result(m_ctx); if (result->invalid_recipients) { KMessageBox::error(kapp->activeWindow(), QString("%1: %2") .arg(i18n("That public key is not meant for encryption")) .arg(result->invalid_recipients->fpr)); } else { err = readToBuffer(out, outBuffer); } } } } } } if(err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { KMessageBox::error(kapp->activeWindow(), QString("%1: %2") .arg(gpgme_strsource(err)).arg(gpgme_strerror(err))); } if(err != GPG_ERR_NO_ERROR) clearCache(); if(keys[0]) gpgme_key_unref(keys[0]); if(in) gpgme_data_release(in); if(out) gpgme_data_release(out); return (err == GPG_ERR_NO_ERROR); }
char *gpg_encrypt_msg(const char *msg, const char *fpr) { gpgme_ctx_t ctx; gpgme_data_t plain, cipher; gpgme_error_t err; char *temp, *str; char *ret = 0; gpgme_key_t key_arr[2] = {0, 0}; size_t n = 0; err = gpgme_new(&ctx); if (err) { return 0; } gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); gpgme_set_armor(ctx, 1); err = gpgme_get_key(ctx, fpr, &key_arr[0], 0); if (err) { gpgme_release(ctx); return 0; } err = gpgme_data_new_from_mem(&plain, msg, strlen(msg), 0); if (err) { goto end; } gpgme_data_new(&cipher); err = gpgme_op_encrypt(ctx, key_arr, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); gpgme_data_release(plain); if (err) { gpgme_data_release(cipher); goto end; } temp = gpgme_data_release_and_get_mem(cipher, &n); if (!temp) { goto end; } str = strndup(temp, n); gpgme_free(temp); if (!str) { goto end; } ret = drop_gpg_headers(str); free(str); end: gpgme_key_unref(key_arr[0]); gpgme_release(ctx); return ret; }
void p_gpg_verify(const char *const barejid, const char *const sign) { if (!sign) { return; } gpgme_ctx_t ctx; gpgme_error_t error = gpgme_new(&ctx); if (error) { log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); return; } char *sign_with_header_footer = _add_header_footer(sign, PGP_SIGNATURE_HEADER, PGP_SIGNATURE_FOOTER); gpgme_data_t sign_data; gpgme_data_new_from_mem(&sign_data, sign_with_header_footer, strlen(sign_with_header_footer), 1); free(sign_with_header_footer); gpgme_data_t plain_data; gpgme_data_new(&plain_data); error = gpgme_op_verify(ctx, sign_data, NULL, plain_data); gpgme_data_release(sign_data); gpgme_data_release(plain_data); if (error) { log_error("GPG: Failed to verify. %s %s", gpgme_strsource(error), gpgme_strerror(error)); gpgme_release(ctx); return; } gpgme_verify_result_t result = gpgme_op_verify_result(ctx); if (result) { if (result->signatures) { gpgme_key_t key = NULL; error = gpgme_get_key(ctx, result->signatures->fpr, &key, 0); if (error) { log_debug("Could not find PGP key with ID %s for %s", result->signatures->fpr, barejid); } else { log_debug("Fingerprint found for %s: %s ", barejid, key->subkeys->fpr); ProfPGPPubKeyId *pubkeyid = malloc(sizeof(ProfPGPPubKeyId)); pubkeyid->id = strdup(key->subkeys->keyid); pubkeyid->received = TRUE; g_hash_table_replace(pubkeys, strdup(barejid), pubkeyid); } gpgme_key_unref(key); } } gpgme_release(ctx); }
SEXP R_gpg_delete(SEXP id, SEXP secret){ gpgme_key_t key; const char * idstr = CHAR(STRING_ELT(id, 0)); bail(gpgme_get_key(ctx, idstr, &key, 0), "find key"); gpgme_error_t err = gpgme_op_delete(ctx, key, asLogical(secret)); if(gpg_err_code (err) == GPG_ERR_CONFLICT){ Rf_warningcall(R_NilValue, "Did not delete %s. Set secret = TRUE to delete private keys", idstr); return mkString(""); } bail(err, "delete key"); return mkString(key->subkeys->keyid); }
//note: passphrase callback seems broken for keygen SEXP R_gpg_keygen(SEXP params){ void * cb = NULL; gpgme_get_passphrase_cb(ctx, NULL, &cb); gpgme_set_passphrase_cb(ctx, NULL, NULL); const char * par = Rf_length(params) ? CHAR(STRING_ELT(params, 0)) : NULL; bail(gpgme_op_genkey(ctx, par, NULL, NULL), "generate key"); gpgme_genkey_result_t res = gpgme_op_genkey_result(ctx); gpgme_key_t key; bail(gpgme_get_key(ctx, res->fpr, &key, 0), "get new key"); gpgme_set_passphrase_cb(ctx, pwprompt, cb); return mkString(key->subkeys->keyid); }
// NEW method, requires GPGME 1.7 and GnuPG 2.1 SEXP R_gpg_keygen_new(SEXP userid){ #if GPGME_VERSION_NUMBER >= 0x010700 unsigned int flags = GPGME_CREATE_SIGN | GPGME_CREATE_ENCR | GPGME_CREATE_NOPASSWD | GPGME_CREATE_FORCE; bail(gpgme_op_createkey(ctx, CHAR(STRING_ELT(userid, 0)), "default", 0, 0, NULL, flags), "create key"); gpgme_genkey_result_t res = gpgme_op_genkey_result(ctx); gpgme_key_t key; bail(gpgme_get_key(ctx, res->fpr, &key, 0), "get new key"); return mkString(key->subkeys->keyid); #else Rf_error("GPGME too old for gpgme_op_createkey"); #endif }
void c_gpgme::remove_key_from_keyring ( const std::string &fingerprint ) { gpgme_key_t key; m_error_code = gpgme_get_key(m_ctx, fingerprint.c_str(), &key, 0); if (m_error_code != GPG_ERR_NO_ERROR) { throw std::runtime_error(gpgme_strsource(m_error_code)); } m_error_code = gpgme_op_delete(m_ctx, key, 0); if (m_error_code != GPG_ERR_NO_ERROR) { throw std::runtime_error(gpgme_strsource(m_error_code)); } }
void encrypt(const char *message, char *dest, const char *fingerprint) { gpgme_data_t in; gpgme_key_t key[2] = { NULL, NULL }; gpgme_encrypt_result_t result; init_cryptofox(); gpgme_set_armor (_cf_ctx, 1); _cf_err = gpgme_data_new_from_mem (&in, message, strlen(message), 0); fail_if_err (_cf_err); _cf_err = gpgme_data_new (&_cf_out); fail_if_err (_cf_err); // my key ([email protected]) _cf_err = gpgme_get_key (_cf_ctx, fingerprint, &key[0], 0); fail_if_err (_cf_err); // err = gpgme_get_key(ctx,"C0C13F91F6F111E8C66CA6E518A66F16FBFD6A72", // &key[1], 0); // fail_if_err (err); _cf_err = gpgme_op_encrypt (_cf_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, _cf_out); fail_if_err (_cf_err); result = gpgme_op_encrypt_result (_cf_ctx); if (result->invalid_recipients) { fprintf (stderr, "Invalid recipient encountered: %s\n", result->invalid_recipients->fpr); exit (1); } int ret; ret = gpgme_data_seek(_cf_out, 0, SEEK_SET); if(ret) fail_if_err(gpgme_err_code_from_errno(errno)); gpgme_key_unref (key[0]); gpgme_data_release (in); gpgme_release (_cf_ctx); }
/* Get the key used to create signature IDX in CTX and return it in R_KEY. */ gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key) { gpgme_verify_result_t result; gpgme_signature_t sig; result = gpgme_op_verify_result (ctx); sig = result->signatures; while (sig && idx) { sig = sig->next; idx--; } if (!sig || idx) return gpg_error (GPG_ERR_EOF); return gpgme_get_key (ctx, sig->fpr, r_key, 0); }
static PyObject * pygpgme_context_get_key(PyGpgmeContext *self, PyObject *args) { const char *fpr; int secret = 0; gpgme_error_t err; gpgme_key_t key; PyObject *ret; if (!PyArg_ParseTuple(args, "s|i", &fpr, &secret)) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_get_key(self->ctx, fpr, &key, secret); Py_END_ALLOW_THREADS; if (pygpgme_check_error(err)) return NULL; ret = pygpgme_key_new(key); gpgme_key_unref(key); return ret; }
gchar *sgpgme_sigstat_info_full(gpgme_ctx_t ctx, gpgme_verify_result_t status) { gint i = 0; gchar *ret; GString *siginfo; gpgme_signature_t sig = NULL; siginfo = g_string_sized_new(64); if (status == NULL) { g_string_append_printf(siginfo, _("Error checking signature: no status\n")); goto bail; } sig = status->signatures; while (sig) { char buf[100]; struct tm lt; gpgme_user_id_t user = NULL; gpgme_key_t key; gpgme_error_t err; const gchar *keytype, *keyid, *uid; err = gpgme_get_key(ctx, sig->fpr, &key, 0); if (err != GPG_ERR_NO_ERROR) { key = NULL; g_string_append_printf(siginfo, _("Error checking signature: %s\n"), gpgme_strerror(err)); goto bail; } if (key) { user = key->uids; keytype = gpgme_pubkey_algo_name( key->subkeys->pubkey_algo); keyid = key->subkeys->keyid; uid = user->uid; } else { keytype = "?"; keyid = "?"; uid = "?"; } memset(buf, 0, sizeof(buf)); fast_strftime(buf, sizeof(buf)-1, prefs_common_get_prefs()->date_format, localtime_r(&sig->timestamp, <)); g_string_append_printf(siginfo, _("Signature made on %s using %s key ID %s\n"), buf, keytype, keyid); switch (gpg_err_code(sig->status)) { case GPG_ERR_NO_ERROR: g_string_append_printf(siginfo, _("Good signature from uid \"%s\" (Validity: %s)\n"), uid, get_validity_str(user?user->validity:GPGME_VALIDITY_UNKNOWN)); break; case GPG_ERR_KEY_EXPIRED: g_string_append_printf(siginfo, _("Expired key uid \"%s\"\n"), uid); break; case GPG_ERR_SIG_EXPIRED: g_string_append_printf(siginfo, _("Expired signature from uid \"%s\" (Validity: %s)\n"), uid, get_validity_str(user?user->validity:GPGME_VALIDITY_UNKNOWN)); break; case GPG_ERR_CERT_REVOKED: g_string_append_printf(siginfo, _("Revoked key uid \"%s\"\n"), uid); break; case GPG_ERR_BAD_SIGNATURE: g_string_append_printf(siginfo, _("BAD signature from \"%s\"\n"), uid); break; default: break; } if (sig->status != GPG_ERR_BAD_SIGNATURE) { gint j = 1; user = user ? user->next : NULL; while (user != NULL) { g_string_append_printf(siginfo, _(" uid \"%s\" (Validity: %s)\n"), user->uid, user->revoked==TRUE?_("Revoked"):get_validity_str(user->validity)); j++; user = user->next; } g_string_append_printf(siginfo,_("Owner Trust: %s\n"), get_owner_trust_str(key->owner_trust)); g_string_append(siginfo, _("Primary key fingerprint:")); const char* primary_fpr = NULL; if (key && key->subkeys && key->subkeys->fpr) primary_fpr = key->subkeys->fpr; else g_string_append(siginfo, " ?"); int idx; /* now pretty-print the fingerprint */ for (idx=0; primary_fpr && *primary_fpr!='\0'; idx++, primary_fpr++) { if (idx%4==0) g_string_append_c(siginfo, ' '); if (idx%20==0) g_string_append_c(siginfo, ' '); g_string_append_c(siginfo, (gchar)*primary_fpr); } g_string_append_c(siginfo, '\n'); #ifdef HAVE_GPGME_PKA_TRUST if (sig->pka_trust == 1 && sig->pka_address) { g_string_append_printf(siginfo, _("WARNING: Signer's address \"%s\" " "does not match DNS entry\n"), sig->pka_address); } else if (sig->pka_trust == 2 && sig->pka_address) { g_string_append_printf(siginfo, _("Verified signer's address is \"%s\"\n"), sig->pka_address); /* FIXME: Compare the address to the * From: address. */ } #endif /*HAVE_GPGME_PKA_TRUST*/ } g_string_append(siginfo, "\n"); i++; sig = sig->next; } bail: ret = siginfo->str; g_string_free(siginfo, FALSE); return ret; }
/** * Check the PGP signature for the given file path. * If base64_sig is provided, it will be used as the signature data after * decoding. If base64_sig is NULL, expect a signature file next to path * (e.g. "%s.sig"). * * The return value will be 0 if nothing abnormal happened during the signature * check, and -1 if an error occurred while checking signatures or if a * signature could not be found; pm_errno will be set. Note that "abnormal" * does not include a failed signature; the value in siglist should be checked * to determine if the signature(s) are good. * @param handle the context handle * @param path the full path to a file * @param base64_sig optional PGP signature data in base64 encoding * @param siglist a pointer to storage for signature results * @return 0 in normal cases, -1 if the something failed in the check process */ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, const char *base64_sig, alpm_siglist_t *siglist) { int ret = -1, sigcount; gpgme_error_t gpg_err = 0; gpgme_ctx_t ctx; gpgme_data_t filedata, sigdata; gpgme_verify_result_t verify_result; gpgme_signature_t gpgsig; char *sigpath = NULL; unsigned char *decoded_sigdata = NULL; FILE *file = NULL, *sigfile = NULL; if(!path || _alpm_access(handle, NULL, path, R_OK) != 0) { RET_ERR(handle, ALPM_ERR_NOT_A_FILE, -1); } if(!siglist) { RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1); } siglist->count = 0; if(!base64_sig) { sigpath = _alpm_sigpath(handle, path); if(_alpm_access(handle, NULL, sigpath, R_OK) != 0 || (sigfile = fopen(sigpath, "rb")) == NULL) { _alpm_log(handle, ALPM_LOG_DEBUG, "sig path %s could not be opened\n", sigpath); handle->pm_errno = ALPM_ERR_SIG_MISSING; goto error; } } /* does the file we are verifying exist? */ file = fopen(path, "rb"); if(file == NULL) { handle->pm_errno = ALPM_ERR_NOT_A_FILE; goto error; } if(init_gpgme(handle)) { /* pm_errno was set in gpgme_init() */ goto error; } _alpm_log(handle, ALPM_LOG_DEBUG, "checking signature for %s\n", path); memset(&ctx, 0, sizeof(ctx)); memset(&sigdata, 0, sizeof(sigdata)); memset(&filedata, 0, sizeof(filedata)); gpg_err = gpgme_new(&ctx); CHECK_ERR(); /* create our necessary data objects to verify the signature */ gpg_err = gpgme_data_new_from_stream(&filedata, file); CHECK_ERR(); /* next create data object for the signature */ if(base64_sig) { /* memory-based, we loaded it from a sync DB */ size_t data_len; int decode_ret = alpm_decode_signature(base64_sig, &decoded_sigdata, &data_len); if(decode_ret) { handle->pm_errno = ALPM_ERR_SIG_INVALID; goto gpg_error; } gpg_err = gpgme_data_new_from_mem(&sigdata, (char *)decoded_sigdata, data_len, 0); } else { /* file-based, it is on disk */ gpg_err = gpgme_data_new_from_stream(&sigdata, sigfile); } CHECK_ERR(); /* here's where the magic happens */ gpg_err = gpgme_op_verify(ctx, sigdata, filedata, NULL); CHECK_ERR(); verify_result = gpgme_op_verify_result(ctx); CHECK_ERR(); if(!verify_result || !verify_result->signatures) { _alpm_log(handle, ALPM_LOG_DEBUG, "no signatures returned\n"); handle->pm_errno = ALPM_ERR_SIG_MISSING; goto gpg_error; } for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig; gpgsig = gpgsig->next, sigcount++); _alpm_log(handle, ALPM_LOG_DEBUG, "%d signatures returned\n", sigcount); CALLOC(siglist->results, sigcount, sizeof(alpm_sigresult_t), handle->pm_errno = ALPM_ERR_MEMORY; goto gpg_error); siglist->count = sigcount; for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig; gpgsig = gpgsig->next, sigcount++) { alpm_list_t *summary_list, *summary; alpm_sigstatus_t status; alpm_sigvalidity_t validity; gpgme_key_t key; alpm_sigresult_t *result; _alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); summary_list = list_sigsum(gpgsig->summary); for(summary = summary_list; summary; summary = summary->next) { _alpm_log(handle, ALPM_LOG_DEBUG, "summary: %s\n", (const char *)summary->data); } alpm_list_free(summary_list); _alpm_log(handle, ALPM_LOG_DEBUG, "status: %s\n", gpgme_strerror(gpgsig->status)); _alpm_log(handle, ALPM_LOG_DEBUG, "timestamp: %lu\n", gpgsig->timestamp); if((time_t)gpgsig->timestamp > time(NULL)) { _alpm_log(handle, ALPM_LOG_DEBUG, "signature timestamp is greater than system time.\n"); } _alpm_log(handle, ALPM_LOG_DEBUG, "exp_timestamp: %lu\n", gpgsig->exp_timestamp); _alpm_log(handle, ALPM_LOG_DEBUG, "validity: %s; reason: %s\n", string_validity(gpgsig->validity), gpgme_strerror(gpgsig->validity_reason)); result = siglist->results + sigcount; gpg_err = gpgme_get_key(ctx, gpgsig->fpr, &key, 0); if(gpg_err_code(gpg_err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); gpg_err = GPG_ERR_NO_ERROR; /* we dupe the fpr in this case since we have no key to point at */ STRDUP(result->key.fingerprint, gpgsig->fpr, handle->pm_errno = ALPM_ERR_MEMORY; goto gpg_error); } else {
gchar *sgpgme_sigstat_info_short(gpgme_ctx_t ctx, gpgme_verify_result_t status) { gpgme_signature_t sig = NULL; gchar *uname = NULL; gpgme_key_t key; gchar *result = NULL; gpgme_error_t err = 0; static gboolean warned = FALSE; if (GPOINTER_TO_INT(status) == -GPG_ERR_SYSTEM_ERROR) { return g_strdup_printf(_("The signature can't be checked - %s"), privacy_get_error()); } if (status == NULL) { return g_strdup(_("The signature has not been checked.")); } sig = status->signatures; if (sig == NULL) { return g_strdup(_("The signature has not been checked.")); } err = gpgme_get_key(ctx, sig->fpr, &key, 0); if (gpg_err_code(err) == GPG_ERR_NO_AGENT) { if (!warned) alertpanel_error(_("PGP Core: Can't get key - no gpg-agent running.")); else g_warning(_("PGP Core: Can't get key - no gpg-agent running.")); warned = TRUE; } else if (gpg_err_code(err) != GPG_ERR_NO_ERROR && gpg_err_code(err) != GPG_ERR_EOF) { return g_strdup_printf(_("The signature can't be checked - %s"), gpgme_strerror(err)); } if (key) uname = extract_name(key->uids->uid); else uname = g_strdup("<?>"); switch (gpg_err_code(sig->status)) { case GPG_ERR_NO_ERROR: result = g_strdup_printf(_("Good signature from %s."), uname); break; case GPG_ERR_SIG_EXPIRED: result = g_strdup_printf(_("Expired signature from %s."), uname); break; case GPG_ERR_KEY_EXPIRED: result = g_strdup_printf(_("Good signature from %s, but the key has expired."), uname); break; case GPG_ERR_CERT_REVOKED: result = g_strdup_printf(_("Good signature from %s, but the key has been revoked."), uname); break; case GPG_ERR_BAD_SIGNATURE: result = g_strdup_printf(_("Bad signature from %s."), uname); break; case GPG_ERR_NO_PUBKEY: { gchar *id = g_strdup(sig->fpr + strlen(sig->fpr)-8); result = g_strdup_printf(_("Key 0x%s not available to verify this signature."), id); g_free(id); break; } default: result = g_strdup(_("The signature has not been checked.")); break; } if (result == NULL) result = g_strdup(_("Error")); g_free(uname); return result; }
/* ------------------ * sign a plain string with the key found with fingerprint fpr * FREE MEMORY AFTER USAGE OF RETURN VALUE! * ------------------ */ static char* sign(const char* plain_str,const char* fpr) { gpgme_error_t error; gpgme_ctx_t ctx; gpgme_key_t key; gpgme_data_t plain,sig; const int MAX_LEN = 10000; char *sig_str = NULL; char *sig_str_dup = NULL; size_t len = 0; // connect to gpgme gpgme_check_version (NULL); error = gpgme_new(&ctx); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); return NULL; } // get key by fingerprint error = gpgme_get_key(ctx,fpr,&key,1); if (error || !key) { purple_debug_error(PLUGIN_ID,"gpgme_get_key failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } // select signers gpgme_signers_clear(ctx); error = gpgme_signers_add (ctx,key); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_signers_add failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } // create data containers gpgme_data_new_from_mem (&plain, plain_str,strlen(plain_str),1); gpgme_data_new(&sig); // sign message, ascii armored gpgme_set_armor(ctx,1); error = gpgme_op_sign(ctx,plain,sig,GPGME_SIG_MODE_DETACH); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_op_sign failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } // release memory for data containers gpgme_data_release(plain); sig_str = gpgme_data_release_and_get_mem(sig,&len); if (sig_str != NULL) { sig_str[len] = 0; sig_str_dup = str_unarmor(sig_str); } gpgme_free(sig_str); // close gpgme connection gpgme_release (ctx); return sig_str_dup; }
/** * Search for a GPG key in a remote location. * This requires GPGME to call the gpg binary and have a keyserver previously * defined in a gpg.conf configuration file. * @param handle the context handle * @param fpr the fingerprint key ID to look up * @param pgpkey storage location for the given key if found * @return 1 on success, 0 on key not found, -1 on error */ static int key_search(alpm_handle_t *handle, const char *fpr, alpm_pgpkey_t *pgpkey) { gpgme_error_t gpg_err; gpgme_ctx_t ctx; gpgme_keylist_mode_t mode; gpgme_key_t key; int ret = -1; size_t fpr_len; char *full_fpr; /* gpg2 goes full retard here. For key searches ONLY, we need to prefix the * key fingerprint with 0x, or the lookup will fail. */ fpr_len = strlen(fpr); MALLOC(full_fpr, fpr_len + 3, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); sprintf(full_fpr, "0x%s", fpr); memset(&ctx, 0, sizeof(ctx)); gpg_err = gpgme_new(&ctx); CHECK_ERR(); mode = gpgme_get_keylist_mode(ctx); /* using LOCAL and EXTERN together doesn't work for GPG 1.X. Ugh. */ mode &= ~GPGME_KEYLIST_MODE_LOCAL; mode |= GPGME_KEYLIST_MODE_EXTERN; gpg_err = gpgme_set_keylist_mode(ctx, mode); CHECK_ERR(); _alpm_log(handle, ALPM_LOG_DEBUG, "looking up key %s remotely\n", fpr); gpg_err = gpgme_get_key(ctx, full_fpr, &key, 0); if(gpg_err_code(gpg_err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); /* Try an alternate lookup using the 8 character fingerprint value, since * busted-ass keyservers can't support lookups using subkeys with the full * value as of now. This is why 2012 is not the year of PGP encryption. */ if(fpr_len > 8) { const char *short_fpr = memcpy(&full_fpr[fpr_len - 8], "0x", 2); _alpm_log(handle, ALPM_LOG_DEBUG, "looking up key %s remotely\n", short_fpr); gpg_err = gpgme_get_key(ctx, short_fpr, &key, 0); if(gpg_err_code(gpg_err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); ret = 0; } } else { ret = 0; } } CHECK_ERR(); /* should only get here if key actually exists */ pgpkey->data = key; if(key->subkeys->fpr) { pgpkey->fingerprint = key->subkeys->fpr; } else if(key->subkeys->keyid) { pgpkey->fingerprint = key->subkeys->keyid; } pgpkey->uid = key->uids->uid; pgpkey->name = key->uids->name; pgpkey->email = key->uids->email; pgpkey->created = key->subkeys->timestamp; pgpkey->expires = key->subkeys->expires; pgpkey->length = key->subkeys->length; pgpkey->revoked = key->subkeys->revoked; switch(key->subkeys->pubkey_algo) { case GPGME_PK_RSA: case GPGME_PK_RSA_E: case GPGME_PK_RSA_S: pgpkey->pubkey_algo = 'R'; break; case GPGME_PK_DSA: pgpkey->pubkey_algo = 'D'; break; case GPGME_PK_ELG_E: case GPGME_PK_ELG: case GPGME_PK_ECDSA: case GPGME_PK_ECDH: pgpkey->pubkey_algo = 'E'; break; } ret = 1; gpg_error: if(ret != 1) { _alpm_log(handle, ALPM_LOG_DEBUG, "gpg error: %s\n", gpgme_strerror(gpg_err)); } free(full_fpr); gpgme_release(ctx); return ret; }
static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data) { MimeInfo *msgcontent; FILE *fp; gchar *enccontent; size_t len; gchar *textstr, *tmp; gpgme_data_t gpgtext, gpgenc; gpgme_ctx_t ctx; gpgme_key_t *kset = NULL; gchar **fprs = g_strsplit(encrypt_data, " ", -1); gpgme_error_t err; gint i = 0; while (fprs[i] && strlen(fprs[i])) { i++; } kset = g_malloc(sizeof(gpgme_key_t)*(i+1)); memset(kset, 0, sizeof(gpgme_key_t)*(i+1)); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); g_free(kset); return FALSE; } i = 0; while (fprs[i] && strlen(fprs[i])) { gpgme_key_t key; err = gpgme_get_key(ctx, fprs[i], &key, 0); if (err) { debug_print("can't add key '%s'[%d] (%s)\n", fprs[i],i, gpgme_strerror(err)); privacy_set_error(_("Couldn't add GPG key %s, %s"), fprs[i], gpgme_strerror(err)); g_free(kset); return FALSE; } debug_print("found %s at %d\n", fprs[i], i); kset[i] = key; i++; } debug_print("Encrypting message content\n"); /* get content node from message */ msgcontent = (MimeInfo *) mimeinfo->node->children->data; if (msgcontent->type == MIMETYPE_MULTIPART) { if (!msgcontent->node->children) { debug_print("msgcontent->node->children NULL, bailing\n"); privacy_set_error(_("Malformed message")); g_free(kset); return FALSE; } msgcontent = (MimeInfo *) msgcontent->node->children->data; } /* get rid of quoted-printable or anything */ procmime_decode_content(msgcontent); fp = my_tmpfile(); if (fp == NULL) { privacy_set_error(_("Couldn't create temporary file, %s"), g_strerror(errno)); perror("my_tmpfile"); g_free(kset); return FALSE; } procmime_write_mimeinfo(msgcontent, fp); rewind(fp); /* read temporary file into memory */ textstr = fp_read_noconv(fp); fclose(fp); /* encrypt data */ gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgenc); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); g_free(kset); return FALSE; } gpgme_set_armor(ctx, 1); err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc); enccontent = sgpgme_data_release_and_get_mem(gpgenc, &len); g_free(kset); if (enccontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Encryption failed, %s"), gpgme_strerror(err)); gpgme_data_release(gpgtext); g_free(textstr); gpgme_release(ctx); g_free(enccontent); return FALSE; } tmp = g_malloc(len+1); g_memmove(tmp, enccontent, len+1); tmp[len] = '\0'; g_free(enccontent); gpgme_data_release(gpgtext); g_free(textstr); if (msgcontent->content == MIMECONTENT_FILE && msgcontent->data.filename != NULL) { if (msgcontent->tmp == TRUE) claws_unlink(msgcontent->data.filename); g_free(msgcontent->data.filename); } msgcontent->data.mem = g_strdup(tmp); msgcontent->content = MIMECONTENT_MEM; g_free(tmp); gpgme_release(ctx); return TRUE; }
/* ############################################################################# * * Description encrypt the given buffer and return the encrypted data with * an updated size information * Author Harry Brueckner * Date 2005-03-31 * Arguments char* buffer - buffer to encrypt * int size - size of the buffer * char** newbuffer - pointer to the new buffer which holds the * encrypted data * int* newsize - size of the returned buffer * PASSPHRASE_FN password_cb - callback function pointer used * to get the current passphrase * SHOWERROR_FN showerror_cb - callback function pointer used * to display errors * Return 0 if ok, otherwise 1 */ int gpgEncrypt(char* buffer, int size, char** newbuffer, int* newsize, PASSPHRASE_FN password_cb, SHOWERROR_FN showerror_cb) { gpgme_ctx_t context; gpgme_data_t input, output; gpgme_encrypt_result_t result; gpgme_error_t error; gpgme_key_t* key = NULL; gpgme_key_t tkey = NULL; gpgme_sign_result_t sign_result; int i, keys = 0, showerror = 1; char* agent; char* fpr; char* tmpbuffer = NULL; TRACE(99, "gpgEncrypt()", NULL); /* we set our passphrase callback function */ passphrase_callback = password_cb; /* we initialize the external size data */ newsize[0] = 0; error = gpgme_new(&context); if (!error) { gpgme_set_textmode(context, 1); gpgme_set_armor(context, 1); /* Flawfinder: ignore */ agent = getenv("GPG_AGENT_INFO"); if (!(agent && strchr(agent, ':'))) { retries = 0; gpgme_set_passphrase_cb(context, gpgRequestPassphrase, NULL); } } if (!error) { error = gpgme_data_new_from_mem(&input, buffer, size, 0); } if (!error) { error = gpgme_data_new(&output); } if (!error) { gpgme_signers_clear(context); } if (!error) { /* allocate the keys */ keys = keyCount(); key = memAlloc(__FILE__, __LINE__, sizeof(gpgme_key_t) * (keys + 1)); key[keys] = NULL; signers = 0; for (i = 0; i < keys && !error; i++) { /* add all keys */ fpr = gpgGetFingerprint(keyGet(i), LIST_SECRET); if (fpr) { error = gpgme_get_key(context, fpr, &tkey, LIST_SECRET); if (tkey -> secret); { error = gpgme_signers_add(context, tkey); signers++; } memFreeString(__FILE__, __LINE__, fpr); } fpr = gpgGetFingerprint(keyGet(i), LIST_ALL); if (fpr) { error = gpgme_get_key(context, fpr, &key[i], LIST_ALL); memFreeString(__FILE__, __LINE__, fpr); } } } if (signers > 1) { /* as soon as we get two signers, we must no longer cache anything */ config -> keeppassphrase = 0; clearPassphrase(1); } /* encrypt and sign the data */ if (!error) { error = gpgme_op_encrypt_sign(context, key, GPGME_ENCRYPT_ALWAYS_TRUST, input, output); } /* we don't need the passphrase any longer */ clearPassphrase(0); if (!error) { result = gpgme_op_encrypt_result(context); } if (!error && result -> invalid_recipients) { tmpbuffer = memAlloc(__FILE__, __LINE__, STDBUFFERLENGTH); snprintf(tmpbuffer, STDBUFFERLENGTH, _("Invalid recipient encountered: %s"), result -> invalid_recipients -> fpr); (showerror_cb)(_("GpgMe error"), tmpbuffer); memFree(__FILE__, __LINE__, tmpbuffer, STDBUFFERLENGTH); showerror = 0; error = 1; } if (!error) { sign_result = gpgme_op_sign_result(context); error = gpgCheckSignResult(showerror_cb, sign_result, GPGME_SIG_MODE_NORMAL); showerror = !error; } if (!error) { tmpbuffer = gpgData2Char(output, newsize); } /* free the keys again */ i = 0; while (key && keys && key[i]) { gpgme_key_unref(key[i++]); } memFree(__FILE__, __LINE__, key, sizeof(gpgme_key_t) * (keys + 1)); gpgme_data_release(input); gpgme_data_release(output); gpgme_release(context); *newbuffer = tmpbuffer; if (error) { if (showerror) { (showerror_cb)(_("GpgMe encrypt error"), gpgme_strerror(error)); } return 1; } else return 0; }
/* name must already be upper-case */ static retvalue load_key(const char *name, bool allow_subkeys, bool allow_bad, const char *full_condition, const struct known_key **key_found, int *index_found) { gpg_error_t err; gpgme_key_t gpgme_key = NULL; gpgme_subkey_t subkey; int found = -1; struct known_key *k; int i; size_t l = strlen(name); /* first look if this key was already retrieved: */ for (k = known_keys ; k != NULL ; k = k->next) { for(i = 0 ; i < k->count ; i++) { struct known_subkey *s = &k->subkeys[i]; if (s->name_len < l) continue; if (memcmp(name, s->name + (s->name_len - l), l) != 0) continue; return found_key(k, i, allow_subkeys, allow_bad, full_condition, key_found, index_found); } } /* If not yet found, request it: */ err = gpgme_get_key(context, name, &gpgme_key, 0); if ((gpg_err_code(err) == GPG_ERR_EOF) && gpgme_key == NULL) { fprintf(stderr, "Error: unknown key '%s'!\n", name); return RET_ERROR_MISSING; } if (err != 0) { fprintf(stderr, "gpgme error %s:%d retrieving key '%s': %s\n", gpg_strsource(err), (int)gpg_err_code(err), name, gpg_strerror(err)); if (gpg_err_code(err) == GPG_ERR_ENOMEM) return RET_ERROR_OOM; else return RET_ERROR_GPGME; } i = 0; subkey = gpgme_key->subkeys; while (subkey != NULL) { subkey = subkey->next; i++; } k = calloc(1, sizeof(struct known_key) + i * sizeof(struct known_subkey)); if (FAILEDTOALLOC(k)) { gpgme_key_unref(gpgme_key); return RET_ERROR_OOM; } k->count = i; k->next = known_keys; known_keys = k; subkey = gpgme_key->subkeys; for (i = 0 ; i < k->count ; i++ , subkey = subkey->next) { struct known_subkey *s = &k->subkeys[i]; assert (subkey != NULL); s->revoked = subkey->revoked; s->expired = subkey->expired; s->cansign = subkey->can_sign && !subkey->invalid; s->name = strdup(subkey->keyid); if (FAILEDTOALLOC(s->name)) { gpgme_key_unref(gpgme_key); return RET_ERROR_OOM; } for (char *p = s->name ; *p != '\0' ; p++) { if (*p >= 'a' && *p <= 'z') *p -= 'a'-'A'; } s->name_len = strlen(s->name); if (memcmp(name, s->name + (s->name_len - l), l) == 0) found = i; } assert (subkey == NULL); gpgme_key_unref(gpgme_key); if (found < 0) { fprintf(stderr, "Error: not a valid key id '%s'!\n" "Use hex-igits from the end of the key as identifier\n", name); return RET_ERROR; } return found_key(k, found, allow_subkeys, allow_bad, full_condition, key_found, index_found); }
QString QalfCrypto::sign(QString &message, QString &key) { gpgme_key_t gpgkey ; gpgme_data_t signature ; gpgme_data_t msg ; gpgme_verify_result_t verification ; gpgme_signature_t signatures ; gpgme_error_t result ; char * buffer ; gpgme_set_passphrase_cb(context,&passphrase_callback,NULL) ; result = gpgme_set_protocol(context,GPGME_PROTOCOL_OpenPGP) ; Q_ASSERT(gpgme_err_code(result) == GPG_ERR_NO_ERROR) ; gpgme_set_armor(context,1) ; gpgme_set_textmode(context,1) ; gpgme_signers_clear(context) ; result = gpgme_set_keylist_mode(context,GPGME_KEYLIST_MODE_LOCAL) ; // retrieving key result = gpgme_get_key(context, key.toAscii().data(),&gpgkey,1) ; Q_ASSERT(result == GPG_ERR_NO_ERROR) ; Q_ASSERT(gpgkey != 0) ; // signing result = gpgme_signers_add(context,gpgkey) ; Q_ASSERT(result == GPG_ERR_NO_ERROR) ; result = gpgme_data_new(&signature); Q_ASSERT(result == GPG_ERR_NO_ERROR) ; int message_length = message.toAscii().size() ; char * message_char = (char *) calloc(message_length+1,sizeof(char)) ; memcpy(message_char,message.toAscii().data(),message_length) ; // printf("memcmp : %d\n",memcmp(message_char,"1fc36e1d41a93c1d79f6872198f426129320d287",message_length+1)) ; result = gpgme_data_new_from_mem(&msg,message_char,message_length,0) ; gpgme_data_seek(signature,0,SEEK_SET) ; gpgme_data_seek(msg,0,SEEK_SET) ; result = gpgme_op_sign(context, msg,signature, GPGME_SIG_MODE_DETACH) ; Q_ASSERT(gpgme_err_code(result) == GPG_ERR_NO_ERROR || gpgme_err_code(result) == GPG_ERR_BAD_PASSPHRASE || gpgme_err_code(result) == GPG_ERR_CANCELED) ; // gpgme_data_seek(signature,0,SEEK_SET) ; // gpgme_data_seek(msg,0,SEEK_SET) ; // // result = gpgme_op_verify (context, signature, msg , 0) ; // Q_ASSERT(gpgme_err_code(result) != GPG_ERR_INV_VALUE) ; // Q_ASSERT(gpgme_err_code(result) != GPG_ERR_NO_DATA) ; // Q_ASSERT(result == GPG_ERR_NO_ERROR) ; // // verification = gpgme_op_verify_result(context) ; // Q_ASSERT(verification != 0) ; // // signatures = verification->signatures ; // Q_ASSERT(verification->signatures != 0) ; // result = signatures->status ; // printf("status : %d\n",gpgme_err_code(result)) ; // printf("signature summary : %d\n",signatures->summary) ; // Q_ASSERT(signatures->summary == GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN) ; // QString signatureStr ; buffer = (char *) calloc(2048,sizeof(char)) ; gpgme_data_seek(signature,0,SEEK_SET) ; gpgme_data_read(signature,buffer,2048) ; signatureStr += buffer ; qDebug() << "signature" << signatureStr ; gpgme_data_release(signature) ; gpgme_key_unref(gpgkey) ; gpgme_data_release(msg) ; return signatureStr ; }
/* ------------------ * encrypt a plain string with the key found with fingerprint fpr * ------------------ */ static char* encrypt(const char* plain_str, const char* fpr) { gpgme_error_t error; gpgme_ctx_t ctx; gpgme_key_t key; gpgme_data_t plain,cipher; char* cipher_str = NULL; char* cipher_str_dup = NULL; size_t len; gpgme_key_t key_arr[2]; key_arr[0] = NULL; key_arr[1] = NULL; // connect to gpgme gpgme_check_version (NULL); error = gpgme_new(&ctx); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); return NULL; } // get key by fingerprint error = gpgme_get_key(ctx,fpr,&key,0); if (error || !key) { purple_debug_error(PLUGIN_ID,"gpgme_get_key failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } key_arr[0] = key; // create data containers gpgme_data_new_from_mem (&plain, plain_str,strlen(plain_str),1); gpgme_data_new(&cipher); // encrypt, ascii armored gpgme_set_armor(ctx,1); error = gpgme_op_encrypt (ctx, key_arr,GPGME_ENCRYPT_ALWAYS_TRUST,plain,cipher); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_op_encrypt failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return NULL; } // release memory for data containers gpgme_data_release(plain); cipher_str = gpgme_data_release_and_get_mem(cipher,&len); if (cipher_str != NULL) { cipher_str_dup = str_unarmor(cipher_str); } gpgme_free(cipher_str); // close gpgme connection gpgme_release (ctx); return cipher_str_dup; }
static GMimeSignatureList * pkcs7_get_signatures (Pkcs7Ctx *pkcs7, gboolean verify) { GMimeSignatureList *signatures; GMimeSignature *signature; gpgme_verify_result_t result; gpgme_subkey_t subkey; gpgme_signature_t sig; gpgme_user_id_t uid; gpgme_key_t key; /* get the signature verification results from GpgMe */ if (!(result = gpgme_op_verify_result (pkcs7->ctx)) || !result->signatures) return verify ? g_mime_signature_list_new () : NULL; /* create a new signature list to return */ signatures = g_mime_signature_list_new (); sig = result->signatures; while (sig != NULL) { signature = g_mime_signature_new (); g_mime_signature_list_add (signatures, signature); if (sig->status != GPG_ERR_NO_ERROR) g_mime_signature_set_status (signature, GMIME_SIGNATURE_STATUS_ERROR); else g_mime_signature_set_status (signature, GMIME_SIGNATURE_STATUS_GOOD); g_mime_certificate_set_pubkey_algo (signature->cert, sig->pubkey_algo); g_mime_certificate_set_digest_algo (signature->cert, sig->hash_algo); g_mime_certificate_set_fingerprint (signature->cert, sig->fpr); g_mime_signature_set_expires (signature, sig->exp_timestamp); g_mime_signature_set_created (signature, sig->timestamp); if (sig->exp_timestamp != 0 && sig->exp_timestamp <= time (NULL)) { /* signature expired, automatically results in a BAD signature */ signature->errors |= GMIME_SIGNATURE_ERROR_EXPSIG; signature->status = GMIME_SIGNATURE_STATUS_BAD; } if (gpgme_get_key (pkcs7->ctx, sig->fpr, &key, 0) == GPG_ERR_NO_ERROR && key) { /* get more signer info from their signing key */ g_mime_certificate_set_trust (signature->cert, pkcs7_trust (key->owner_trust)); g_mime_certificate_set_issuer_serial (signature->cert, key->issuer_serial); g_mime_certificate_set_issuer_name (signature->cert, key->issuer_name); /* get the keyid, name, and email address */ uid = key->uids; while (uid) { if (uid->name && *uid->name) g_mime_certificate_set_name (signature->cert, uid->name); if (uid->email && *uid->email) g_mime_certificate_set_email (signature->cert, uid->email); if (uid->uid && *uid->uid) g_mime_certificate_set_key_id (signature->cert, uid->uid); if (signature->cert->name && signature->cert->email && signature->cert->keyid) break; uid = uid->next; } /* get the subkey used for signing */ subkey = key->subkeys; while (subkey && !subkey->can_sign) subkey = subkey->next; if (subkey) { g_mime_certificate_set_created (signature->cert, subkey->timestamp); g_mime_certificate_set_expires (signature->cert, subkey->expires); if (subkey->revoked) { /* signer's key has been revoked, automatic BAD status */ signature->errors |= GMIME_SIGNATURE_ERROR_REVKEYSIG; signature->status = GMIME_SIGNATURE_STATUS_BAD; } if (subkey->expired) { /* signer's key has expired, automatic BAD status */ signature->errors |= GMIME_SIGNATURE_ERROR_EXPKEYSIG; signature->status = GMIME_SIGNATURE_STATUS_BAD; } } else { /* If we don't have the subkey used by the signer, then we can't * tell what the status is, so set to ERROR if it hasn't already * been designated as BAD. */ if (signature->status != GMIME_SIGNATURE_STATUS_BAD) signature->status = GMIME_SIGNATURE_STATUS_ERROR; signature->errors |= GMIME_SIGNATURE_ERROR_NO_PUBKEY; } gpgme_key_unref (key); } else { /* If we don't have the signer's public key, then we can't tell what * the status is, so set it to ERROR if it hasn't already been * designated as BAD. */ g_mime_certificate_set_trust (signature->cert, GMIME_CERTIFICATE_TRUST_UNDEFINED); if (signature->status != GMIME_SIGNATURE_STATUS_BAD) signature->status = GMIME_SIGNATURE_STATUS_ERROR; signature->errors |= GMIME_SIGNATURE_ERROR_NO_PUBKEY; } sig = sig->next; } return signatures; }
int main (int argc, char *argv[]) { gpgme_ctx_t ctx; gpgme_error_t err; struct gpgme_data_cbs cbs; gpgme_data_t in, out; gpgme_key_t key[3] = { NULL, NULL, NULL }; gpgme_encrypt_result_t result; size_t nbytes; struct cb_parms parms; if (argc > 1) nbytes = atoi (argv[1]); else nbytes = 100000; init_gpgme (GPGME_PROTOCOL_OpenPGP); memset (&cbs, 0, sizeof cbs); cbs.read = read_cb; cbs.write = write_cb; memset (&parms, 0, sizeof parms); parms.bytes_to_send = nbytes; err = gpgme_new (&ctx); fail_if_err (err); gpgme_set_armor (ctx, 0); /* Install a progress handler to enforce a bit of more work to the gpgme i/o system. */ gpgme_set_progress_cb (ctx, progress_cb, NULL); err = gpgme_data_new_from_cbs (&in, &cbs, &parms); fail_if_err (err); err = gpgme_data_new_from_cbs (&out, &cbs, &parms); fail_if_err (err); err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734", &key[0], 0); fail_if_err (err); err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", &key[1], 0); fail_if_err (err); err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); fail_if_err (err); result = gpgme_op_encrypt_result (ctx); if (result->invalid_recipients) { fprintf (stderr, "Invalid recipient encountered: %s\n", result->invalid_recipients->fpr); exit (1); } printf ("plaintext=%u bytes, ciphertext=%u bytes\n", (unsigned int)nbytes, (unsigned int)parms.bytes_received); gpgme_key_unref (key[0]); gpgme_key_unref (key[1]); gpgme_data_release (in); gpgme_data_release (out); gpgme_release (ctx); return 0; }