Beispiel #1
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;
}
Beispiel #2
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;

}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
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;
}
Beispiel #8
0
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;
}
Beispiel #9
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);
}
Beispiel #10
0
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;
}
Beispiel #11
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);
}
Beispiel #12
0
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);
}
Beispiel #13
0
//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);
}
Beispiel #14
0
// 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
}
Beispiel #15
0
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));
	}
}
Beispiel #16
0
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);
}
Beispiel #17
0
/* 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);
}
Beispiel #18
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;
}
Beispiel #19
0
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, &lt));
		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;
}
Beispiel #20
0
/**
 * 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 {
Beispiel #21
0
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;
}
Beispiel #22
0
/* ------------------
 * 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;
}
Beispiel #23
0
/**
 * 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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
/* #############################################################################
 *
 * 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;
  }
Beispiel #26
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 ;
}
Beispiel #28
0
/* ------------------
 * 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;
}
Beispiel #29
0
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;
}