Exemplo n.º 1
0
void
ot_gpgme_error_to_gio_error (gpgme_error_t   gpg_error,
                             GError        **error)
{
  GIOErrorEnum errcode;

  /* XXX This list is incomplete.  Add cases as needed. */

  switch (gpg_error)
    {
      /* special case - shouldn't be here */
      case GPG_ERR_NO_ERROR:
        g_return_if_reached ();

      /* special case - abort on out-of-memory */
      case GPG_ERR_ENOMEM:
        g_error ("%s: %s",
                 gpgme_strsource (gpg_error),
                 gpgme_strerror (gpg_error));

      case GPG_ERR_INV_VALUE:
        errcode = G_IO_ERROR_INVALID_ARGUMENT;
        break;

      default:
        errcode = G_IO_ERROR_FAILED;
        break;
    }

  g_set_error (error, G_IO_ERROR, errcode, "%s: %s",
               gpgme_strsource (gpg_error),
               gpgme_strerror (gpg_error));
}
Exemplo n.º 2
0
gpgme_data_t sgpgme_data_from_mimeinfo(MimeInfo *mimeinfo)
{
	gpgme_data_t data = NULL;
	gpgme_error_t err;
	FILE *fp = g_fopen(mimeinfo->data.filename, "rb");
	gchar *tmp_file = NULL;

	if (!fp) 
		return NULL;

	tmp_file = get_tmp_file();
	copy_file_part(fp, mimeinfo->offset, mimeinfo->length, tmp_file);
	fclose(fp);
	fp = NULL;
	debug_print("tmp file %s\n", tmp_file);
	
	err = gpgme_data_new_from_file(&data, tmp_file, 1);
	claws_unlink(tmp_file);
	g_free(tmp_file);

	debug_print("data %p (%d %d)\n", (void *)&data, mimeinfo->offset, mimeinfo->length);
	if (err) {
		debug_print ("gpgme_data_new_from_file failed: %s\n",
			     gpgme_strerror (err));
		privacy_set_error(_("Couldn't get data from message, %s"), gpgme_strerror(err));
		return NULL;
	}
	return data;
}
Exemplo n.º 3
0
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;

}
Exemplo n.º 4
0
static void
check_result (gpgme_verify_result_t result, int summary, char *fpr,
	      gpgme_error_t status, gpgme_validity_t validity)
{
  gpgme_signature_t sig;

  sig = result->signatures;
  if (!sig || sig->next)
    {
      fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
	       __FILE__, __LINE__);
      got_errors = 1;
    }
  if (sig->summary != summary)
    {
      fprintf (stderr, "%s:%i: Unexpected signature summary: "
               "want=0x%x have=0x%x\n",
	       __FILE__, __LINE__, summary, sig->summary);
      got_errors = 1;
    }
  if (strcmp (sig->fpr, fpr))
    {
      fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
	       __FILE__, __LINE__, sig->fpr);
      got_errors = 1;
    }
  if (gpgme_err_code (sig->status) != status)
    {
      fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
	       __FILE__, __LINE__, gpgme_strerror (sig->status));
      got_errors = 1;
    }
  if (sig->notations)
    {
      fprintf (stderr, "%s:%i: Unexpected notation data\n",
	       __FILE__, __LINE__);
      got_errors = 1;
    }
  if (sig->wrong_key_usage)
    {
      fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
	       __FILE__, __LINE__);
      got_errors = 1;
    }
  if (sig->validity != validity)
    {
      fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
	       __FILE__, __LINE__, sig->validity);
      got_errors = 1;
    }
  if (gpgme_err_code (sig->validity_reason) != GPG_ERR_NO_ERROR)
    {
      fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
	       __FILE__, __LINE__, gpgme_strerror (sig->validity_reason));
      got_errors = 1;
    }
}
Exemplo n.º 5
0
GSList *
get_available_keys ()
{
    init_gpgme ();

    gpgme_ctx_t ctx;
    gpgme_key_t key;

    gpgme_error_t  err = gpgme_new (&ctx);
    if (err) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (err), gpgme_strerror (err));
        return GPGME_ERROR;
    }

    err = gpgme_op_keylist_start (ctx, NULL, 1);
    if (err) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (err), gpgme_strerror (err));
        gpgme_release (ctx);
        return GPGME_ERROR;
    }

    GSList *list = NULL;
    KeyInfo *key_info;

    while (1) {
        err = gpgme_op_keylist_next (ctx, &key);
        if (err) {
            break;
        }
        key_info = g_new0 (KeyInfo, 1);
        key_info->key_id = g_strdup (key->subkeys->keyid);
        if (key->uids && key->uids->name) {
            key_info->name = g_strdup (key->uids->name);
        } else {
            key_info->name = g_strdup ("none");
        }
        if (key->uids && key->uids->email) {
            key_info->email = g_strdup (key->uids->email);
        } else {
            key_info->email = g_strdup ("none");
        }
        key_info->key_fpr = g_strdup (key->subkeys->fpr);

        gssize bytes_to_copy = sizeof (KeyInfo) + g_utf8_strlen (key_info->name, -1) + g_utf8_strlen (key_info->email, -1) +
                g_utf8_strlen (key_info->key_id, -1) + g_utf8_strlen (key_info->key_fpr, -1) + 4;

        list = g_slist_append (list, g_memdup (key_info, bytes_to_copy));

        g_free (key_info);

        gpgme_key_release (key);
    }

    gpgme_release (ctx);

    return list;
}
Exemplo n.º 6
0
gboolean
fu_keyring_add_public_key (FuKeyring *keyring, const gchar *filename, GError **error)
{
	FuKeyringPrivate *priv = GET_PRIVATE (keyring);
	gpgme_error_t rc;
	gpgme_import_result_t result;
	gpgme_import_status_t s;
	g_auto(gpgme_data_t) data = NULL;

	g_return_val_if_fail (FU_IS_KEYRING (keyring), FALSE);
	g_return_val_if_fail (filename != NULL, FALSE);

	/* import public key */
	g_debug ("Adding public key %s", filename);
	rc = gpgme_data_new_from_file (&data, filename, 1);
	if (rc != GPG_ERR_NO_ERROR) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INTERNAL,
			     "failed to load %s: %s",
			     filename, gpgme_strerror (rc));
		return FALSE;
	}
	rc = gpgme_op_import (priv->ctx, data);
	if (rc != GPG_ERR_NO_ERROR) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INTERNAL,
			     "failed to import %s: %s",
			     filename, gpgme_strerror (rc));
		return FALSE;
	}

	/* print what keys were imported */
	result = gpgme_op_import_result (priv->ctx);
	for (s = result->imports; s != NULL; s = s->next) {
		g_debug ("importing key %s [%u] %s",
			 s->fpr, s->status, gpgme_strerror (s->result));
	}

	/* make sure keys were really imported */
	if (result->imported == 0 && result->unchanged == 0) {
		g_debug("imported: %d, unchanged: %d, not_imported: %d",
			result->imported,
			result->unchanged,
			result->not_imported);
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INTERNAL,
			     "key import failed %s",
			     filename);
		return FALSE;
	}
	return TRUE;
}
Exemplo n.º 7
0
static char * geanypg_result(gpgme_signature_t sig)
{
    char format[] =
    "status ....: %s\n"
    "summary ...:%s\n"
    "fingerprint: %s\n"
    "created ...: %s"
    "expires ...: %s"
    "validity ..: %s\n"
    "val.reason : %s\n"
    "pubkey algo: %s\n"
    "digest algo: %s\n"
    "pka address: %s\n"
    "pka trust .: %s\n"
    "other flags:%s%s\n"
    "notations .: %s\n"; // 210 characters
    char * buffer = (char *)calloc(2048, 1); // everything together probably won't be more
                                          // than 1061 characters, but we don't want to
                                          // take risks
    char summary[128];
    const char * pubkey = gpgme_pubkey_algo_name(sig->pubkey_algo);
    const char * hash = gpgme_hash_algo_name(sig->hash_algo);
    char created[64];
    char expires[64];
    if (sig->timestamp)
        strncpy(created, ctime((time_t*)&sig->timestamp), 64);
    else
        strcpy(created, "Unknown\n");

    if (sig->exp_timestamp)
        strncpy(expires, ctime((time_t*)&sig->exp_timestamp), 64);
    else
        strcpy(expires, "Unknown\n");

    memset(summary, 0, 128);
    sprintf(buffer, format,
        gpgme_strerror(sig->status),            // probably won't be more than 128
        geanypg_summary(sig->summary, summary), // max 105 characters
        sig->fpr ? sig->fpr : "[None]",         // max 40 characters
        created,                                // probably about 24 characters
        expires,                                // probably about 24 characters
        geanypg_validity(sig->validity),        // max 11 characters
        gpgme_strerror(sig->status),            // probably won't be more than 128
        pubkey ? pubkey : "Unknown",            // probably won't be more than 32
        hash ? hash : "Unknown",            // probably won't be more than 32
        sig->pka_address ? sig->pka_address : "[None]", // probably won't be more than 128
        sig->pka_trust == 0 ? "n/a" : sig->pka_trust == 1 ? "bad" : sig->pka_trust == 2 ? "okay": "RFU", // max 4 characters
        sig->wrong_key_usage ? " wrong-key-usage" : "", sig->chain_model ? " chain-model" : "",          // max 28 characters
        sig->notations ? "yes" : "no");         // max 3 characters
    return buffer;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
/**
 * 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;
}
Exemplo n.º 10
0
gboolean sgpgme_has_secret_key(void)
{
	gpgme_error_t err = 0;
	gpgme_ctx_t ctx;
	gpgme_key_t key;

	err = gpgme_new (&ctx);
	if (err) {
		debug_print("err : %s\n", gpgme_strerror(err));
		return TRUE;
	}
check_again:
	err = gpgme_op_keylist_start(ctx, NULL, TRUE);
	if (!err)
		err = gpgme_op_keylist_next(ctx, &key);
	gpgme_op_keylist_end(ctx);
	if (gpg_err_code(err) == GPG_ERR_EOF) {
		if (gpgme_get_protocol(ctx) != GPGME_PROTOCOL_CMS) {
			gpgme_set_protocol(ctx, GPGME_PROTOCOL_CMS);
			goto check_again;
		}
		gpgme_release(ctx);
		return FALSE;
	} else {
		gpgme_release(ctx);
		return TRUE;
	}
}
Exemplo n.º 11
0
/**
 * seahorse_util_handle_gpgme:
 * @err: Error value
 *
 * Shows an error dialog for @err.
 **/
void
seahorse_util_handle_gpgme (gpgme_error_t err, const char* desc, ...)
{
    gchar *t = NULL;

    switch (gpgme_err_code(err)) {
    case GPG_ERR_CANCELED:
    case GPG_ERR_NO_ERROR:
    case GPG_ERR_ECANCELED:
        return;
    default:
        break;
    }

    va_list ap;
    va_start(ap, desc);

    if (desc)
        t = g_strdup_vprintf (desc, ap);

    va_end(ap);

    seahorse_util_show_error (NULL, t, gpgme_strerror (err));
    g_free(t);
}
Exemplo n.º 12
0
static int
gpgme_error_to_errno (gpgme_error_t err)
{
  int res = gpg_err_code_to_errno (err);

  if (!err)
    {
      switch (gpg_err_code (err))
	{
	case GPG_ERR_EOF:
	  res = 0;
	  break;
	case GPG_ERR_INV_VALUE:
	  res = EINVAL;
	  break;
	case GPG_ERR_NOT_SUPPORTED:
	  res = ENOSYS;
	  break;
	default:
	  /* FIXME: Yeah, well.  */
	  res = EINVAL;
	  break;
	}
    }
  TRACE3 (DEBUG_DATA, "gpgme:gpgme_error_to_errno", 0,
	  "mapping %s <%s> to: %s", gpgme_strerror (err),
	  gpgme_strsource (err), strerror (res));
  errno = res;
  return res ? -1 : 0;
}
Exemplo n.º 13
0
char *gpg_decrypt_msg(const char *data, long *plain_size) {
    gpgme_ctx_t ctx;
    gpgme_error_t err;
    size_t n = 0;
    char *temp, *str, *msg;
    gpgme_data_t plain, cipher;
    
    msg = add_gpg_headers(data);
    if (!msg) {
        return 0;
    }
    
    err = gpgme_new(&ctx);
    if (err) {
        return 0;
    }
    gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP);
    gpgme_set_armor(ctx, 1);
//    char *p = getenv("GPG_AGENT_INFO");
//    if (p) {
//        log_write("GPG_AGENT_INFO: %s\n", p);
//    } else {
//        setenv("GPG_AGENT_INFO", "/tmp/gpg-3FhMq6/S.gpg-agent:22765:1", 1);
//        log_write("NO GPG AGENT INFO FOUND\n");
//    }
    gpgme_set_passphrase_cb(ctx, &passphrase_cb, 0);
    
    gpgme_data_new_from_mem(&cipher, msg, strlen(msg), 0);
    gpgme_data_new(&plain);
    
    err = gpgme_op_decrypt(ctx, cipher, plain);
    gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx);
    gpgme_recipient_t recipient = res->recipients;
    while (recipient) {
        log_write(">>> recipient keyid: %s\n", recipient->keyid);
        recipient = recipient->next;
    }
    gpgme_data_release(cipher);
    free(msg);
    
    if (err) {
        log_write("gpgme_op_decrypt error: %s\n", gpgme_strerror(err));
        gpgme_data_release(plain);
        gpgme_release(ctx);
        return 0;
    }
    
    temp = gpgme_data_release_and_get_mem(plain, &n);
    if (!temp) {
        gpgme_release(ctx);
        return 0;
    }
    *plain_size = n;
    str = strndup(temp, n);
    free(temp);
    
    gpgme_release(ctx);
    return str;
}
Exemplo n.º 14
0
gpgme_error_t geanypg_show_err_msg(gpgme_error_t err)
{
    gchar const * msg = (gchar const *)gpgme_strerror(err);
    gchar const * src = (gchar const *)gpgme_strsource(err);
    dialogs_show_msgbox(GTK_MESSAGE_ERROR, "%s %s: %s\n", _("Error from"), src, msg);
    fprintf(stderr, "GeanyPG: %s %s: %s\n", _("Error from"), msg, src);
    return err;
}
Exemplo n.º 15
0
/**
 * 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);
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
/* ------------------
 * verify a signed string with the key found with fingerprint fpr
 * FREE MEMORY AFTER USAGE OF RETURN VALUE!
 * ------------------ */
static char* verify(const char* sig_str)
{
	gpgme_error_t error;
	gpgme_ctx_t ctx;
	gpgme_data_t plain,sig,sig_text;
	gpgme_verify_result_t result;
	char* fpr = NULL;
	char* armored_sig_str = NULL;

	if (sig_str == NULL)
	{
		purple_debug_error(PLUGIN_ID,"verify got null parameter\n");
		return 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;
	}

	// armor sig_str
	armored_sig_str = str_armor(sig_str);

	// create data containers
	gpgme_data_new_from_mem (&sig, armored_sig_str,strlen(armored_sig_str),1);
	gpgme_data_new(&plain);

	// try to verify
	error = gpgme_op_verify(ctx,sig,NULL,plain);
	if (error)
	{
		purple_debug_error(PLUGIN_ID,"gpgme_op_verify failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
		gpgme_release (ctx);
		return NULL;
	}

	// get result
 	result = gpgme_op_verify_result (ctx);
	if (result != NULL)
	{
		if (result->signatures != NULL)
		{
			// return the fingerprint of the key that made the signature
			fpr = g_strdup(result->signatures->fpr);
		}
	}

	// release memory for data containers
	gpgme_data_release(sig);
	gpgme_data_release(plain);

	return fpr;
}
Exemplo n.º 18
0
/* ------------------
 * 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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
const char*
fko_gpg_errstr(fko_ctx_t ctx)
{
#if HAVE_LIBGPGME
    if(ctx->gpg_err)
        return(gpgme_strerror(ctx->gpg_err));
#endif /* HAVE_LIBGPGME */

    return("");
}
Exemplo n.º 21
0
gpgme_verify_result_t sgpgme_verify_signature(gpgme_ctx_t ctx, gpgme_data_t sig, 
					gpgme_data_t plain, gpgme_data_t dummy)
{
	gpgme_verify_result_t status = NULL;
	gpgme_error_t err;

	if ((err = gpgme_op_verify(ctx, sig, plain, dummy)) != GPG_ERR_NO_ERROR) {
		debug_print("op_verify err %s\n", gpgme_strerror(err));
		privacy_set_error("%s", gpgme_strerror(err));
		return GINT_TO_POINTER(-GPG_ERR_SYSTEM_ERROR);
	}
	status = gpgme_op_verify_result(ctx);
	if (status && status->signatures == NULL) {
		debug_print("no signature found\n");
		privacy_set_error(_("No signature found"));
		return GINT_TO_POINTER(-GPG_ERR_SYSTEM_ERROR);
	}
	return status;
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
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);
}
Exemplo n.º 24
0
/* ------------------
 * import ascii armored key
 * ------------------ */
int import_key(char* armored_key)
{
	gpgme_error_t error;
	gpgme_ctx_t ctx;
	gpgme_data_t keydata;
	gpgme_import_result_t result;

	// 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;
	}

	purple_debug_info(PLUGIN_ID,"try to import key: %s\n",armored_key);
	// create data containers
	gpgme_data_new_from_mem (&keydata, armored_key,strlen(armored_key),1);

	// import key, ascii armored
	gpgme_set_armor(ctx,1);
	error =  gpgme_op_import (ctx, keydata);
	if (error)
	{
		purple_debug_error(PLUGIN_ID,"gpgme_op_import: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
		gpgme_release (ctx);
		return FALSE;
	}

	result = gpgme_op_import_result (ctx);
	purple_debug_info(PLUGIN_ID,"considered keys: %d; imported keys: %d; not imported keys: %d\n",result->considered,result->imported,result->not_imported);

	// release memory for data containers
	gpgme_data_release(keydata);

	// close gpgme connection
	gpgme_release (ctx);

	return TRUE;
}
Exemplo n.º 25
0
gpgme_data_t sgpgme_data_from_mimeinfo(MimeInfo *mimeinfo)
{
	gpgme_data_t data = NULL;
	gpgme_error_t err;
	FILE *fp = g_fopen(mimeinfo->data.filename, "rb");

	if (!fp) 
		return NULL;

	err = gpgme_data_new_from_filepart(&data, NULL, fp, mimeinfo->offset, mimeinfo->length);
	fclose(fp);

	debug_print("data %p (%d %d)\n", (void *)&data, mimeinfo->offset, mimeinfo->length);
	if (err) {
		debug_print ("gpgme_data_new_from_file failed: %s\n",
			     gpgme_strerror (err));
		privacy_set_error(_("Couldn't get data from message, %s"), gpgme_strerror(err));
		return NULL;
	}
	return data;
}
Exemplo n.º 26
0
/* ------------------
 * preferences dialog function
 * ------------------ */
static PurplePluginPrefFrame *
get_plugin_pref_frame(PurplePlugin *plugin) {
	PurplePluginPrefFrame *frame;
	PurplePluginPref *ppref;
	gpgme_error_t error;
	gpgme_ctx_t ctx;
	gpgme_key_t key;

	// create preferences frame
	frame = purple_plugin_pref_frame_new();
	
	// 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;
	}

	// create key chooser preference
	ppref = purple_plugin_pref_new_with_name_and_label(PREF_MY_KEY,"My key");
	purple_plugin_pref_set_type(ppref, PURPLE_PLUGIN_PREF_CHOICE);
	purple_plugin_pref_add_choice(ppref, "None", "");

	// list keys (secret keys)
	error = gpgme_op_keylist_start (ctx,NULL,1);
	if (error == GPG_ERR_NO_ERROR)
	{
		while (!error)
		{
			error = gpgme_op_keylist_next (ctx, &key);
			if (error) break;
			// add key to preference chooser
			//TODO: find something better for g_strdup, or some possibility to free memory after preferences dialog closed
			purple_plugin_pref_add_choice(ppref, g_strdup(key->uids->uid), g_strdup(key->subkeys->fpr));
			purple_debug_info(PLUGIN_ID,"Found secret key for: %s has fpr %s\n",key->uids->uid,key->subkeys->fpr);
			gpgme_key_release (key);
		}
	}else
	{
		purple_debug_error(PLUGIN_ID,"gpgme_op_keylist_start failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
	}
	// close gpgme connection
	gpgme_release (ctx);

	purple_plugin_pref_frame_add(frame, ppref);

	return frame;
}
Exemplo n.º 27
0
/* ------------------
 * decrypt a plain string with the key found with fingerprint fpr
 * FREE MEMORY AFTER USAGE OF RETURN VALUE
 * ------------------ */
static char* decrypt(char* cipher_str)
{
	gpgme_error_t error;
	gpgme_ctx_t ctx;
	gpgme_data_t plain,cipher;
	size_t len = 0;
	char* plain_str = NULL;
	char* plain_str_dup = NULL;
	char* armored_buffer;

	// add header and footer:
	armored_buffer = str_armor(cipher_str);

	// 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;
	}

	// create data containers
	gpgme_data_new_from_mem (&cipher, armored_buffer,strlen(armored_buffer),1);
	gpgme_data_new(&plain);

	// decrypt
	error = gpgme_op_decrypt(ctx,cipher,plain);
	if (error)
	{
		purple_debug_error(PLUGIN_ID,"gpgme_op_decrypt failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
		gpgme_release (ctx);
		return NULL;
	}

	// release memory for data containers
	gpgme_data_release(cipher);
	plain_str = gpgme_data_release_and_get_mem(plain,&len);
	if (plain_str != NULL)
	{
		plain_str[len] = 0;
		plain_str_dup = g_strdup(plain_str);
	}
	gpgme_free(plain_str);

	// close gpgme connection
	gpgme_release (ctx);

	return plain_str_dup;
}
Exemplo n.º 28
0
void print_import_result (gpgme_import_result_t r)
{
  gpgme_import_status_t st;

  for (st=r->imports; st; st = st->next)
    {
      printf ("  fpr: %s err: %d (%s) status:", nonnull (st->fpr),
              st->result, gpgme_strerror (st->result));
      if (st->status & GPGME_IMPORT_NEW)
        fputs (" new", stdout);
      if (st->status & GPGME_IMPORT_UID)
        fputs (" uid", stdout);
      if (st->status & GPGME_IMPORT_SIG)
        fputs (" sig", stdout);
      if (st->status & GPGME_IMPORT_SUBKEY)
        fputs (" subkey", stdout);
      if (st->status & GPGME_IMPORT_SECRET)
        fputs (" secret", stdout);
      putchar ('\n');
    }
  printf ("key import summary:\n"
          "        considered: %d\n"
          "        no user id: %d\n"
          "          imported: %d\n"
          "      imported_rsa: %d\n"
          "         unchanged: %d\n"
          "      new user ids: %d\n"
          "       new subkeys: %d\n"
          "    new signatures: %d\n"
          "   new revocations: %d\n"
          "       secret read: %d\n"
          "   secret imported: %d\n"
          "  secret unchanged: %d\n"
          "  skipped new keys: %d\n"
          "      not imported: %d\n",
          r->considered,
          r->no_user_id,
          r->imported,
          r->imported_rsa,
          r->unchanged,
          r->new_user_ids,
          r->new_sub_keys,
          r->new_signatures,
          r->new_revocations,
          r->secret_read,
          r->secret_imported,
          r->secret_unchanged,
          r->skipped_new_keys,
          r->not_imported);
}
Exemplo n.º 29
0
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);
}
Exemplo n.º 30
0
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)));
	}
}