예제 #1
0
std::string GPGWrapper::encrypt(const std::string & recipientName, const std::string& message)
{
    init();

    ScopedGPGData clear_text, sign_text, encrypted_text;

    gpgme_error_t error = clear_text.init(message.c_str(), message.length());
    fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do zaszyfrowana (clear_text).");
    error = sign_text.init();
    fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do zaszyfrowana (sign_text).");

    error = gpgme_op_sign(context, clear_text.get(), sign_text.get(), GPGME_SIG_MODE_NORMAL);
    fail_if_err(error, L"Nie uda³o siê podpisaæ wiadomoœci.");

    error = gpgme_data_rewind(sign_text.get());
    fail_if_err(error, L"Nie uda³o siê przewin¹æ na pocz¹tek podpisanego strumienia, aby go póŸniej zaszyfrowaæ.");

    error = encrypted_text.init();
    fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do zaszyfrowana (encrypted_text).");

    gpgme_key_t recipient = getPublicKey(recipientName.c_str());

    gpgme_key_t recipients[2] = { NULL, NULL };
    recipients[0] = recipient;
    error = gpgme_op_encrypt(context, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, sign_text.get(), encrypted_text.get());
    fail_if_err(error, L"Nie uda³o siê zaszyfrowaæ podpisanej wiadomoœci.");

    gpgme_encrypt_result_t result = gpgme_op_encrypt_result(context);
    fail_if_err(result->invalid_recipients, L"Nie poprawny klucz szyfrowania odbiorcy.");

    return copyData(encrypted_text.get());
}
예제 #2
0
static void geanypg_encrypt(encrypt_data * ed, gpgme_key_t * recp, int sign, int flags)
{   /* FACTORIZE */
    gpgme_data_t plain, cipher;
    gpgme_error_t err;
    FILE * tempfile;
    tempfile = tmpfile();
    if (!(tempfile))
    {
        g_warning("%s: %s.", _("couldn't create tempfile"), strerror(errno));
        return ;
    }
    gpgme_data_new_from_stream(&cipher, tempfile);
    gpgme_data_set_encoding(cipher, GPGME_DATA_ENCODING_ARMOR);

    geanypg_load_buffer(&plain);

    /* do the actual encryption */
    if (sign)
        err = gpgme_op_encrypt_sign(ed->ctx, recp, flags, plain, cipher);
    else
        err = gpgme_op_encrypt(ed->ctx, recp, flags, plain, cipher);
    if (err != GPG_ERR_NO_ERROR && gpgme_err_code(err) != GPG_ERR_CANCELED)
        geanypg_show_err_msg(err);
    else if(gpgme_err_code(err) != GPG_ERR_CANCELED)
    {
        rewind(tempfile);
        geanypg_write_file(tempfile);
    }

    fclose(tempfile);
    /* release buffers */
    gpgme_data_release(plain);
    gpgme_data_release(cipher);
}
예제 #3
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);
}
예제 #4
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;
}
예제 #5
0
    void crypto_asym::encrypt(const vector<string> & recipients_email, generic_file & clear, generic_file & ciphered)
    {
#if GPGME_SUPPORT
	gpgme_key_t *ciphering_keys = NULL;

	build_key_list(recipients_email, ciphering_keys, false);
	try
	{
	    generic_file_overlay_for_gpgme o_clear = &clear;
	    generic_file_overlay_for_gpgme o_ciphered = &ciphered;
	    gpgme_error_t err;

	    if(!has_signatories)
		err = gpgme_op_encrypt(context,
				       ciphering_keys,
				       (gpgme_encrypt_flags_t)(GPGME_ENCRYPT_NO_ENCRYPT_TO|GPGME_ENCRYPT_ALWAYS_TRUST),
				       o_clear.get_gpgme_handle(),
				       o_ciphered.get_gpgme_handle());
	    else
		err = gpgme_op_encrypt_sign(context,
					    ciphering_keys,
					    (gpgme_encrypt_flags_t)(GPGME_ENCRYPT_NO_ENCRYPT_TO|GPGME_ENCRYPT_ALWAYS_TRUST),
					    o_clear.get_gpgme_handle(),
					    o_ciphered.get_gpgme_handle());
	    switch(gpgme_err_code(err))
	    {
	    case GPG_ERR_NO_ERROR:
		break;
	    case GPG_ERR_INV_VALUE:
		throw SRC_BUG;
	    case GPG_ERR_UNUSABLE_PUBKEY:
		throw Erange("crypto_asym::encrypt", gettext("Key found but users are not all trusted"));
	    default:
		throw Erange("crypto_asym::encrypt", string(gettext("Unexpected error reported by GPGME: ")) + tools_gpgme_strerror_r(err));
	    }
	}
	catch(...)
	{
	    release_key_list(ciphering_keys);
	    throw;
	}
	release_key_list(ciphering_keys);
#else
	throw Efeature("Asymetric Strong encryption algorithms using GPGME");
#endif
    }
예제 #6
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;
}
예제 #7
0
int cgpg_encrypt(char *nick, char *msg, char buf[], int len, char errmsg[EOF_L_MESSAGE])
{
//   gpgme_error_t gerr;
   gpgme_key_t keyid[2];
   gpgme_data_t plaintext;
   gpgme_data_t encrypted;
   char *p;

   /* retrieve keyid    */
   p = peer_keyid_get(nick);
   if(!p) {
      eof_errmsg("No key-ID registered");
      return 0;
   }

   keyid[1] = NULL;
   printf("encrypting with keyid=%s\n", p);
   if(!cgpg_keyid_get(p, keyid, errmsg)) {
      return 0;
   }
   printf("Key info: %s <%s>\n", keyid[0]->uids->name,  keyid[0]->uids->email);

   /* allocate buffer: non copying!   */
   if(GPG_ERR_NO_ERROR != gpgme_data_new_from_mem(&plaintext, msg, strlen(msg), 0))
      return 0;
   if(GPG_ERR_NO_ERROR != gpgme_data_new(&encrypted)) return 0;

   /* encrypt  buffer   */
   /* FIXME: remove GPGME_ENCRYPT_ALWAYS_TRUST and use trustlevels */
   if(GPG_ERR_NO_ERROR != gpgme_op_encrypt(gpg_context, keyid,
      GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, encrypted)) {
      eof_errmsg("Encryption failed");
      return 0;
   }
   
   /* return result     */
   if(GPG_ERR_NO_ERROR != gpgme_data_seek(encrypted, 0, SEEK_SET)) {
      eof_errmsg("gpgme_data_seek");
      return 0;
   }
   len = gpgme_data_read(encrypted, buf, len);
   buf[len] = '\0';

   return len;
}
예제 #8
0
파일: cryptofox.c 프로젝트: sheik/Cryptofox
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);
}
예제 #9
0
/* The main GPG encryption routine for libfko.
*/
int
gpgme_encrypt(fko_ctx_t fko_ctx, unsigned char *indata, size_t in_len,
        const char *pw, unsigned char **out, size_t *out_len)
{
    char               *tmp_buf;
    int                 res;

    gpgme_ctx_t         gpg_ctx     = NULL;
    gpgme_data_t        cipher      = NULL;
    gpgme_data_t        plaintext   = NULL;
    gpgme_key_t         key[2]      = { NULL, NULL };
    gpgme_error_t       err;

    /* Initialize gpgme
    */
    res = init_gpgme(fko_ctx);
    if(res != FKO_SUCCESS)
        return(res);

    gpg_ctx = fko_ctx->gpg_ctx;

    /* Initialize the plaintext data (place into gpgme_data object)
    */
    err = gpgme_data_new_from_mem(&plaintext, (char*)indata, in_len, 1);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;
        fko_ctx->gpg_err = err;

        return(FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ);
    }

    /* Set protocol
    */
    err = gpgme_set_protocol(gpg_ctx, GPGME_PROTOCOL_OpenPGP);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_data_release(plaintext);
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        fko_ctx->gpg_err = err;

        return(FKO_ERROR_GPGME_SET_PROTOCOL);
    }

    /* Set ascii-armor off (we will be base64-encoding the encrypted data
     * ourselves.
    */
    gpgme_set_armor(gpg_ctx, 0);

    /* The gpgme_encrypt.... functions take a recipient key array, so we add
     * our single key here.
    */
    key[0] = fko_ctx->recipient_key;

    /* Create the buffer for our encrypted data.
    */
    err = gpgme_data_new(&cipher);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_data_release(plaintext);
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        fko_ctx->gpg_err = err;

        return(FKO_ERROR_GPGME_CIPHER_DATA_OBJ);
    }

    /* Here we add the signer to the gpgme context if there is one.
    */
    if(fko_ctx->gpg_signer != NULL) {
        gpgme_signers_clear(gpg_ctx);
        err = gpgme_signers_add(gpg_ctx, fko_ctx->signer_key);
        if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
        {
            gpgme_data_release(plaintext);
            gpgme_data_release(cipher);
            gpgme_release(gpg_ctx);
            fko_ctx->gpg_ctx = NULL;

            fko_ctx->gpg_err = err;

            return(FKO_ERROR_GPGME_ADD_SIGNER);
        }
    }

    /* Set the passphrase callback.
    */
    gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw);

    /* Encrypt and sign (if a sig was provided) the SPA data.
    */
    if(fko_ctx->gpg_signer == NULL)
        err = gpgme_op_encrypt(
            gpg_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, cipher
        );
    else
        err = gpgme_op_encrypt_sign(
            gpg_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, cipher
        );

    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_data_release(plaintext);
        gpgme_data_release(cipher);
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        fko_ctx->gpg_err = err;

        if(gpgme_err_code(err) == GPG_ERR_CANCELED)
            return(FKO_ERROR_GPGME_BAD_PASSPHRASE);

        return(FKO_ERROR_GPGME_ENCRYPT_SIGN);
    }

    /* Done with the plaintext.
    */
    gpgme_data_release(plaintext);

    /* Get the encrypted data and its length from the gpgme data object.
     * BTW, this does free the memory used by cipher.
    */
    tmp_buf = gpgme_data_release_and_get_mem(cipher, out_len);

    *out = malloc(*out_len); /* This is freed upon fko_ctx destruction. */
    if(*out == NULL)
        res = FKO_ERROR_MEMORY_ALLOCATION;
    else
    {
        memcpy(*out, tmp_buf, *out_len);
        res = FKO_SUCCESS;
    }

    gpgme_free(tmp_buf);

    return(res);
}
예제 #10
0
/** \brief Encrypt data
 *
 * \param recipients Array of User ID for which the matter shall be
 *        encrypted using their public keys.
 * \param sign_for User ID of the signer or NULL if the matter shall not be
 *        signed.  Note that combined signing and encryption is allowed \em
 *        only in OpenPGP single-part (i.e. RFC 2440) mode.
 * \param istream GMime input stream.
 * \param ostream GMime output stream.
 * \param protocol GpgME crypto protocol to use for encryption.
 * \param singlepart_mode TRUE indicates single-part mode (integrated
 *        signature), FALSE a detached signature.
 * \param trust_all_keys TRUE if all low-truct keys shall be accepted for
 *        encryption.  Otherwise, the function will use the global callback
 *        to ask the user whether a low-trust key shall be accepted.
 * \param parent Parent window to be passed to the callback functions.
 * \param error Filled with error information on error.
 * \return 0 on success, or -1 on error.
 *
 * Encrypt the passed matter and write the result to the output stream.
 * Combined signing and encryption is allowed for single-part OpenPGP mode
 * only.
 */
int
libbalsa_gpgme_encrypt(GPtrArray * recipients, const char *sign_for,
		       GMimeStream * istream, GMimeStream * ostream,
		       gpgme_protocol_t protocol, gboolean singlepart_mode,
		       gboolean trust_all_keys, GtkWindow * parent,
		       GError ** error)
{
    gpgme_ctx_t ctx;
    gpgme_error_t err;
    gpgme_key_t *rcpt_keys;
    gpgme_data_t plain;
    gpgme_data_t crypt;
    struct gpgme_data_cbs cbs = {
	(gpgme_data_read_cb_t) g_mime_gpgme_stream_rd,	/* read method */
	(gpgme_data_write_cb_t) g_mime_gpgme_stream_wr,	/* write method */
	NULL,			/* seek method */
	cb_data_release		/* release method */
    };

    /* paranoia checks */
    g_return_val_if_fail(recipients != NULL, -1);
    g_return_val_if_fail(GMIME_IS_STREAM(istream), -1);
    g_return_val_if_fail(GMIME_IS_STREAM(ostream), GPGME_MD_NONE);
    g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP ||
			 protocol == GPGME_PROTOCOL_CMS, -1);

    /* create the GpgME context */
    if ((err =
	 gpgme_new_with_protocol(&ctx, protocol, parent,
				 error)) != GPG_ERR_NO_ERROR)
	return -1;

    /* sign & encrypt is valid only for single-part OpenPGP */
    if (sign_for != NULL
	&& (!singlepart_mode || protocol != GPGME_PROTOCOL_OpenPGP)) {
	if (error)
	    g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_INV_ENGINE,
			_
			("combined signing and encryption is defined only for RFC 2440"));
	gpgme_release(ctx);
	return -1;
    }

    /* if requested, find the secret key for "userid" */
    if (sign_for && !gpgme_add_signer(ctx, sign_for, parent, error)) {
	gpgme_release(ctx);
	return -1;
    }

    /* build the list of recipients */
    if (!
	(rcpt_keys =
	 gpgme_build_recipients(ctx, recipients, trust_all_keys, parent,
				error))) {
	gpgme_release(ctx);
	return -1;
    }

    /* create the data objects */
    if (protocol == GPGME_PROTOCOL_OpenPGP) {
	gpgme_set_armor(ctx, 1);
	gpgme_set_textmode(ctx, singlepart_mode);
    } else {
	gpgme_set_armor(ctx, 0);
	gpgme_set_textmode(ctx, 0);
    }
    if ((err =
	 gpgme_data_new_from_cbs(&plain, &cbs,
				 istream)) != GPG_ERR_NO_ERROR) {
	g_set_error_from_gpgme(error, err,
			       _("could not get data from stream"));
	release_keylist(rcpt_keys);
	gpgme_release(ctx);
	return -1;
    }
    if ((err =
	 gpgme_data_new_from_cbs(&crypt, &cbs,
				 ostream)) != GPG_ERR_NO_ERROR) {
	g_set_error_from_gpgme(error, err,
			       _("could not create new data object"));
	release_keylist(rcpt_keys);
	gpgme_data_release(plain);
	gpgme_release(ctx);
	return -1;
    }

    /* do the encrypt or sign and encrypt operation
     * Note: we set "always trust" here, as if we detected an untrusted key
     * earlier, the user already accepted it */
    if (sign_for)
	err =
	    gpgme_op_encrypt_sign(ctx, rcpt_keys,
				  GPGME_ENCRYPT_ALWAYS_TRUST, plain,
				  crypt);
    else
	err =
	    gpgme_op_encrypt(ctx, rcpt_keys, GPGME_ENCRYPT_ALWAYS_TRUST,
			     plain, crypt);

    release_keylist(rcpt_keys);
    gpgme_data_release(plain);
    gpgme_data_release(crypt);
    gpgme_release(ctx);
    if (err != GPG_ERR_NO_ERROR) {
	if (sign_for)
	    g_set_error_from_gpgme(error, err,
				   _("signing and encryption failed"));
	else
	    g_set_error_from_gpgme(error, err, _("encryption failed"));
	return -1;
    } else
	return 0;
}
예제 #11
0
void GPGME::encryptBytesToFile(const QByteArray & data, const QString & filename, const QString & keyId)
{
    setError(GPG_ERR_NO_ERROR); // clear error
    qDebug() << "Encrypt data to file" << filename;
    gpgme_error_t err;

    // check data size
    if (data.size() > FILESIZE_HARD_LIMIT) {
        setError(GPGME_WRAPPER_ERR_DATA_TOO_LARGE, true);
        return;
    }

    // list all available keys and find the appropriate
    err = gpgme_op_keylist_start(p->context, keyId.toLatin1().data(), 0);
    gpgme_key_t key = 0;
    gpgme_key_t loop_key = 0;
    int foundCount = 0;

    while (1) {
        err = gpgme_op_keylist_next(p->context, &loop_key);
        if (err != GPG_ERR_NO_ERROR) {
            break;
        }
        qDebug() << "KEY FOUND";
        if (loop_key != 0) {
            key = loop_key;
        }
        foundCount++;
    }
    gpgme_op_keylist_end(p->context);

    if (foundCount > 1) {
        setError(GPGME_WRAPPER_ERR_MORE_THAN_ONE_KEY_FOUND);
        return;
    }

    if (key == 0) {
        // key not found
        setError(GPGME_WRAPPER_ERR_CANNOT_FIND_KEY, true);
        return;
    }

    // if filename ends with ".asc" then use armored output, otherwise use binary
    if (filename.toLower().endsWith(".asc")) {
        // use armored output
        gpgme_set_armor(p->context, 1);
        qDebug() << "Encode: use armored output";
    }

    gpgme_data_t cipher;
    gpgme_data_t plain;

    gpgme_data_new_from_mem(&plain, data.data(), data.size(), 0); // do not copy data
    
    // backup file contents
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        setError(GPGME_WRAPPER_ERR_CANNOT_OPEN_FILE, true);
        return;
    }
    if (file.size() > FILESIZE_HARD_LIMIT) {
        setError(GPGME_WRAPPER_ERR_FILE_TOO_LARGE, true);
        return;
    }
    QByteArray cipherBackup = file.readAll();
    file.close();
    
    // prepare file for writing
    if (!file.open(QIODevice::WriteOnly)) {
        setError(GPGME_WRAPPER_ERR_CANNOT_OPEN_FILE, true);
        return;
    }

    err = gpgme_data_new_from_fd(&cipher, file.handle());
    if (err != GPG_ERR_NO_ERROR) {
        setError(err);
        return;
    }

    gpgme_key_t keys[2];
    keys[0] = key;
    keys[1] = 0;

    err = gpgme_op_encrypt(p->context, keys, static_cast<gpgme_encrypt_flags_t>(GPGME_ENCRYPT_ALWAYS_TRUST), plain, cipher);
    if (err != GPG_ERR_NO_ERROR) {
        // revert file contents in case of error
        file.resize(0);
        file.write(cipherBackup);
        setError(err);
    }
    file.close();
}
예제 #12
0
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;
}
예제 #13
0
static int
pkcs7_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid,
	       GMimeDigestAlgo digest, GPtrArray *recipients, GMimeStream *istream,
	       GMimeStream *ostream, GError **err)
{
#ifdef ENABLE_SMIME
	GMimePkcs7Context *ctx = (GMimePkcs7Context *) context;
	Pkcs7Ctx *pkcs7 = ctx->priv;
	gpgme_data_t input, output;
	gpgme_error_t error;
	gpgme_key_t *rcpts;
	gpgme_key_t key;
	guint i;
	
	if (sign) {
		g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
			     _("Cannot sign and encrypt a stream at the same time using pkcs7"));
		return -1;
	}
	
	/* create an array of recipient keys for GpgMe */
	rcpts = g_new0 (gpgme_key_t, recipients->len + 1);
	for (i = 0; i < recipients->len; i++) {
		if (!(key = pkcs7_get_key_by_name (pkcs7, recipients->pdata[i], FALSE, err))) {
			key_list_free (rcpts);
			return -1;
		}
		
		rcpts[i] = key;
	}
	
	if ((error = gpgme_data_new_from_cbs (&input, &pkcs7_stream_funcs, istream)) != GPG_ERR_NO_ERROR) {
		g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open input stream"));
		key_list_free (rcpts);
		return -1;
	}
	
	if ((error = gpgme_data_new_from_cbs (&output, &pkcs7_stream_funcs, ostream)) != GPG_ERR_NO_ERROR) {
		g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not open output stream"));
		gpgme_data_release (input);
		key_list_free (rcpts);
		return -1;
	}
	
	/* encrypt the input stream */
	error = gpgme_op_encrypt (pkcs7->ctx, rcpts, GPGME_ENCRYPT_ALWAYS_TRUST, input, output);
	gpgme_data_release (output);
	gpgme_data_release (input);
	key_list_free (rcpts);
	
	if (error != GPG_ERR_NO_ERROR) {
		g_set_error (err, GMIME_GPGME_ERROR, error, _("Encryption failed"));
		return -1;
	}
	
	return 0;
#else
	g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in this build"));
	
	return -1;
#endif /* ENABLE_SMIME */
}
예제 #14
0
gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
{
	MimeInfo *msgcontent, *encmultipart, *newinfo;
	FILE *fp;
	gchar *boundary, *enccontent;
	size_t len;
	gchar *textstr;
	gpgme_data_t gpgtext = NULL, gpgenc = NULL;
	gpgme_ctx_t ctx = NULL;
	gpgme_key_t *kset = NULL;
	gchar **fprs = g_strsplit(encrypt_data, " ", -1);
	gint i = 0;
	gpgme_error_t err;
	
	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\n"), 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");

	/* remove content node from message */
	msgcontent = (MimeInfo *) mimeinfo->node->children->data;
	g_node_unlink(msgcontent->node);

	/* create temporary multipart for content */
	encmultipart = procmime_mimeinfo_new();
	encmultipart->type = MIMETYPE_MULTIPART;
	encmultipart->subtype = g_strdup("encrypted");
	boundary = generate_mime_boundary("Encrypt");
	g_hash_table_insert(encmultipart->typeparameters, g_strdup("boundary"),
                            g_strdup(boundary));
	g_hash_table_insert(encmultipart->typeparameters, g_strdup("protocol"),
                            g_strdup("application/pgp-encrypted"));
	g_node_append(encmultipart->node, msgcontent->node);

	/* write message content to temporary file */
	fp = my_tmpfile();
	if (fp == NULL) {
		perror("my_tmpfile");
		privacy_set_error(_("Couldn't create temporary file, %s"), g_strerror(errno));
		g_free(kset);
		return FALSE;
	}
	procmime_write_mimeinfo(encmultipart, fp);
	rewind(fp);

	/* read temporary file into memory */
	textstr = get_canonical_content(fp, boundary);

	g_free(boundary);
	claws_fclose(fp);

	/* encrypt data */
	gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0);
	gpgme_data_new(&gpgenc);
	gpgme_set_armor(ctx, 1);
	cm_gpgme_data_rewind(gpgtext);
	
	err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);

	enccontent = sgpgme_data_release_and_get_mem(gpgenc, &len);
	gpgme_data_release(gpgtext);
	g_free(textstr);
	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_release(ctx);
		g_free(enccontent);
		return FALSE;
	}

	/* create encrypted multipart */
	g_node_unlink(msgcontent->node);
	procmime_mimeinfo_free_all(&msgcontent);
	g_node_append(mimeinfo->node, encmultipart->node);

	newinfo = procmime_mimeinfo_new();
	newinfo->type = MIMETYPE_APPLICATION;
	newinfo->subtype = g_strdup("pgp-encrypted");
	newinfo->content = MIMECONTENT_MEM;
	newinfo->data.mem = g_strdup("Version: 1\n");
	g_node_append(encmultipart->node, newinfo->node);

	newinfo = procmime_mimeinfo_new();
	newinfo->type = MIMETYPE_APPLICATION;
	newinfo->subtype = g_strdup("octet-stream");
	newinfo->content = MIMECONTENT_MEM;
	newinfo->data.mem = g_malloc(len + 1);
	g_memmove(newinfo->data.mem, enccontent, len);
	newinfo->data.mem[len] = '\0';
	g_node_append(encmultipart->node, newinfo->node);

	g_free(enccontent);
	gpgme_release(ctx);

	return TRUE;
}
예제 #15
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;
}
예제 #16
0
int main(void) {
    gpgme_check_version (NULL);

    gpgme_error_t err;
    gpgme_data_t plain, cipher;
    gpgme_ctx_t ctx;
    gpgme_key_t recp[2] = { NULL, NULL };
    gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;

    char *plaintext = "foo bar\0";
    char *fp = "845B80B9AD12DB400CE534F6837EED10F97A36A1";
    char *result_file = "./result.gpg";
    char *verify_file = "./result";
    size_t max_buflen = 2048, buflen;
    char *buf = malloc(max_buflen * sizeof(char));
    FILE *fh = NULL;

    err = gpgme_new (&ctx);
    if(err) return bang (err);

    gpgme_set_armor (ctx, 1);

    err = gpgme_get_key (ctx, fp, &recp[0], 0);
    if(err) return bang (err);

    err = gpgme_data_new_from_mem (&plain, plaintext, strlen(plaintext), 0);
    if(err) return bang (err);

    err = gpgme_data_new (&cipher);
    if(err) return bang (err);

    err = gpgme_op_encrypt (ctx, recp, flags, plain, cipher);
    if(err) return bang (err);

    gpgme_data_seek(cipher, 0, SEEK_SET);
    buflen = gpgme_data_read(cipher, buf, max_buflen);
    if (1 > buflen || buflen == max_buflen)
        return bang_ ("Failed to read ciphertext");

    fh = fopen(result_file, "w");
    if(!fh) bang_ ("failed to open result_file");

    fwrite(buf, sizeof(char), buflen, fh);
    fclose(fh);
    fh = NULL;

    memset(buf, 0, max_buflen);
    snprintf(buf, max_buflen-1, "gpg --output %s -d %s", verify_file, result_file);
    system(buf);

    memset(buf, 0, max_buflen);
    fh = fopen(verify_file, "rb");
    if(!fh) return bang_ ("failed to open verify_file");

    buflen = fread(buf, sizeof(char), max_buflen, fh);
    fclose(fh);

    if(buflen < 1 || buflen == max_buflen)
        return bang_ ("Failed to read result file");

    #ifdef INSERT_FAILURE
    buf[buflen-1] = '\0';
    #endif

    if (strncmp(buf, plaintext, strlen(plaintext)) != 0)
        return bang_ ("Decrypted text is different from original plaintext");

    return 0;
}
예제 #17
0
파일: gpg.c 프로젝트: klement/profanity
char*
p_gpg_encrypt(const char *const barejid, const char *const message, const char *const fp)
{
    ProfPGPPubKeyId *pubkeyid = g_hash_table_lookup(pubkeys, barejid);
    if (!pubkeyid) {
        return NULL;
    }
    if (!pubkeyid->id) {
        return NULL;
    }

    gpgme_key_t keys[3];

    keys[0] = NULL;
    keys[1] = NULL;
    keys[2] = NULL;

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

    gpgme_key_t receiver_key;
    error = gpgme_get_key(ctx, pubkeyid->id, &receiver_key, 0);
    if (error || receiver_key == NULL) {
        log_error("GPG: Failed to get receiver_key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
        gpgme_release(ctx);
        return NULL;
    }
    keys[0] = receiver_key;

    gpgme_key_t sender_key = NULL;
    error = gpgme_get_key(ctx, fp, &sender_key, 0);
    if (error || sender_key == NULL) {
        log_error("GPG: Failed to get sender_key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
        gpgme_release(ctx);
        return NULL;
    }
    keys[1] = sender_key;

    gpgme_data_t plain;
    gpgme_data_new_from_mem(&plain, message, strlen(message), 1);

    gpgme_data_t cipher;
    gpgme_data_new(&cipher);

    gpgme_set_armor(ctx, 1);
    error = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher);
    gpgme_data_release(plain);
    gpgme_release(ctx);
    gpgme_key_unref(receiver_key);
    gpgme_key_unref(sender_key);

    if (error) {
        log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error));
        return NULL;
    }

    size_t len;
    char *cipher_str = gpgme_data_release_and_get_mem(cipher, &len);

    char *result = NULL;
    if (cipher_str) {
        GString *cipher_gstr = g_string_new("");
        g_string_append_len(cipher_gstr, cipher_str, len);
        result = _remove_header_footer(cipher_gstr->str, PGP_MESSAGE_FOOTER);
        g_string_free(cipher_gstr, TRUE);
        gpgme_free(cipher_str);
    }

    return result;
}
예제 #18
0
int main()
{
   int fd;

   gpgme_ctx_t g_context;
   gpgme_engine_info_t enginfo;
   gpgme_data_t data;

   gpgme_error_t gerr;
   gpg_err_code_t gpg_err;

   gpgme_data_t g_plain;
   gpgme_data_t g_plain_recv;
   gpgme_data_t g_encrypt;
   gpgme_data_t g_encrypt_send;

   gpgme_key_t g_recipient[MAX_RCP+1];
   char *p;
   char b_encrypt[BIGBUF+1];

   char msg[EOF_L_MESSAGE];
   char msg_in[EOF_L_MESSAGE];

   int i, tmp;

   for(i=0;i<EOF_L_MESSAGE; i++) msg_in[i] = 0;
   for(i=0;i<EOF_L_MESSAGE; i++) msg[i] = 0;
   for(i=0;i<=BIGBUF; i++) b_encrypt[i] = 0;

   gpgme_check_version(NULL);

   gerr = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
   if(gerr != GPG_ERR_NO_ERROR) return 10;

   p = (char *) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP);
   printf("Version: %s\n",p);

   gerr = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, home);

   if(gerr == GPG_ERR_NO_ERROR) {
      printf("gpgme_set_engine_info: ok\n");
   } else {
      printf("gpgme_set_engine_info: err\n");
   }

   /* get engine information */
   gerr = gpgme_get_engine_info(&enginfo);
   if(gerr != GPG_ERR_NO_ERROR) return 3;

   printf("file=%s, home=%s\n",enginfo->file_name,enginfo->home_dir);

   /* create our own context */
   gerr = gpgme_new(&g_context);
   if(gerr != GPG_ERR_NO_ERROR) return 1;

   /* FIXME: both needed? */
   /* FIXME: why is the path (FILE_NAME) needed? */
   /* FIXME: /usr/bin/gpg must be changed to ~/.ceof/gpg/binary or similar */
   gerr = gpgme_ctx_set_engine_info (g_context, GPGME_PROTOCOL_OpenPGP,
               "/usr/bin/gpg",home);
   if(gerr != GPG_ERR_NO_ERROR) return 4;

   /* do not ascii armor data; use 1 for testing */
   //gpgme_set_armor(g_context, 0);
   gpgme_set_armor(g_context, 1);

   /* create buffers */
   gerr = gpgme_data_new(&data);
   if(gerr != GPG_ERR_NO_ERROR) return 12;

   gerr = gpgme_data_new(&g_plain_recv);
   if(gerr != GPG_ERR_NO_ERROR) return 20;

   gerr = gpgme_data_new(&g_encrypt);
   if(gerr != GPG_ERR_NO_ERROR) return 14;

   gerr = gpgme_data_new(&g_encrypt_send);
   if(gerr != GPG_ERR_NO_ERROR) return 24;

   /* fill buffers */
   /* gerr = gpgme_data_new(&g_plain);
   if(gerr != GPG_ERR_NO_ERROR) return 13;

   printf("strlen(%s) = %d\n",msg,i);
   i -= gpgme_data_write(g_plain, msg, i);
   if(i) {
      printf("size mismatch\n");
      return 12;
   } */
   strncpy(msg, "==> Erste Nachricht\n\n", EOF_L_MESSAGE);
   i = strlen(msg);
   gerr = gpgme_data_new_from_mem (&g_plain, msg, i, 0);


   /* setup recipient */
   gerr = gpgme_op_keylist_start(g_context, "nico schottelius", 0);
   if(gerr != GPG_ERR_NO_ERROR) return 11;

   i=0;
   gerr = gpgme_op_keylist_next(g_context, &g_recipient[0]);
   while((gpg_err = gpg_err_code(gerr)) != GPG_ERR_EOF) {
      /* for testing: one call of gpgme_op_keylist_next is enough */
      break;
      if(gerr == GPG_ERR_INV_VALUE) {
         printf("invalid pointer\n");
         return 15;
      } else if(gerr == GPG_ERR_ENOMEM) {
         printf("no mem\n");
         return 16;
      }

      printf ("%s: %s <%s> (%d)\n", g_recipient[0]->subkeys->keyid, g_recipient[0]->uids->name, g_recipient[0]->uids->email, i);
      i++;

      /* FIXME: this resets the good filled buffer ... */
      gerr = gpgme_op_keylist_next(g_context, &g_recipient[0]);
   }
   g_recipient[1] = NULL;

   /* all above seems to be wrong ... */
   gerr = gpgme_get_key(g_context,"775506B45998BF57D0D4AFF27C6E747C38616ADC", &g_recipient[0], 0);
   if(gerr != GPG_ERR_NO_ERROR) return 32;


   /* en/decrypt message */
   //gerr = gpgme_op_encrypt_sign(g_context, g_recipient, 0, g_plain, g_encrypt);
   gerr = gpgme_op_encrypt(g_context, g_recipient, 0, g_plain, g_encrypt);
   if(gerr != GPG_ERR_NO_ERROR) {
      printf("gerr=%d\n",gerr);
      return 18;
   }

   /* transfer the data into our own buffer,
    * so the data is saved; you cannot
    * reuse the gpgme buffers directly as in
    *    gerr = gpgme_op_decrypt(g_context, g_encrypt, g_plain_recv);
    *
    */
   i = gpgme_data_seek(g_encrypt, 0, SEEK_END);

   if(i > BIGBUF) return 22;
   printf("buflen: %d\n",i);
   
   /* reset to the beginning */
   gpgme_data_seek(g_encrypt, 0, SEEK_SET);

   if(gpgme_data_read(g_encrypt, b_encrypt, i) == -1) {
      perror("pgme_data_read");
      return 23;
   }
   printf("crypt:\n%s\n", b_encrypt);
   fd = open("testcrypt",O_RDWR|O_CREAT);
   if(fd == -1) return 40;
   if(write_all(fd, b_encrypt, BIGBUF) <= 0) return 41;
   close(fd);

   /* until here it works, testcrypt contains
    * data and can be decrypted ...
    *
    * perhaps the context needs some reset?
    */

   if((tmp = gpgme_data_write(g_encrypt_send, b_encrypt, i)) == -1) {
      perror("pgme_data_write");
      return 23;
   }
   printf("crypt-wrote:%d\n", tmp);

   /* look for contexts */

   gerr = gpgme_op_decrypt(g_context, g_encrypt_send, g_plain_recv);
   if(gerr != GPG_ERR_NO_ERROR) {
      printf("gerr=%d\n",gerr);
      return 19;
   }

   /* open communication channel: netcat */

   /* listen for input from:
    * stdin
    * communication channel
    */

   /* de/encode data from comm channel */

   return 1;
}
예제 #19
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_key_t sender_key;
    gpgme_data_t plain,cipher;
    char* cipher_str = NULL;
    char* cipher_str_dup = NULL;
    size_t len;
    gpgme_key_t key_arr[3];

    key_arr[0] = NULL;
    key_arr[1] = NULL;
    key_arr[2] = 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;

    // check if user selected a main key
    const char* sender_fpr = purple_prefs_get_string(PREF_MY_KEY);
    if ( sender_fpr != NULL && strcmp(sender_fpr,"") != 0)
    {
        // get own key by fingerprint
        error = gpgme_get_key(ctx,sender_fpr,&sender_key,0);
        if (!error && sender_key)
            key_arr[1] = sender_key;
        else
            purple_debug_error(PLUGIN_ID,"gpgme_get_key: sender key for fingerprint %s is missing! error: %s %s\n", sender_fpr, gpgme_strsource (error), gpgme_strerror (error) );
    }
    else
        purple_debug_error(PLUGIN_ID,"purple_prefs_get_string: PREF_MY_KEY was empty\n");

    // 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;
}
예제 #20
0
파일: pgpinline.c 프로젝트: buzz/claws
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;
}
예제 #21
0
static PyObject *
pygpgme_context_encrypt(PyGpgmeContext *self, PyObject *args)
{
    PyObject *py_recp, *py_plain, *py_cipher, *recp_seq = NULL, *result = NULL;
    int flags, i, length;
    gpgme_key_t *recp = NULL;
    gpgme_data_t plain = NULL, cipher = NULL;
    gpgme_error_t err;

    if (!PyArg_ParseTuple(args, "OiOO", &py_recp, &flags,
                          &py_plain, &py_cipher))
        goto end;

    if (py_recp != Py_None) {
        recp_seq = PySequence_Fast(py_recp, "first argument must be a "
                                   "sequence or None");
        if (recp_seq == NULL)
            goto end;

        length = PySequence_Fast_GET_SIZE(recp_seq);
        recp = malloc((length + 1) * sizeof (gpgme_key_t));
        for (i = 0; i < length; i++) {
            PyObject *item = PySequence_Fast_GET_ITEM(recp_seq, i);

            if (!PyObject_TypeCheck(item, &PyGpgmeKey_Type)) {
                PyErr_SetString(PyExc_TypeError, "items in first argument "
                                "must be gpgme.Key objects");
                goto end;
            }
            recp[i] = ((PyGpgmeKey *)item)->key;
        }
        recp[i] = NULL;
    }

    if (pygpgme_data_new(&plain, py_plain))
        goto end;
    if (pygpgme_data_new(&cipher, py_cipher))
        goto end;

    Py_BEGIN_ALLOW_THREADS;    err = gpgme_op_encrypt(self->ctx, recp, flags, plain, cipher);
    Py_END_ALLOW_THREADS;

    if (pygpgme_check_error(err)) {
        decode_encrypt_result(self);
        goto end;
    }

    Py_INCREF(Py_None);
    result = Py_None;

 end:
    if (recp != NULL)
        free(recp);
    Py_XDECREF(recp_seq);
    if (plain != NULL)
        gpgme_data_release(plain);
    if (cipher != NULL)
        gpgme_data_release(cipher);

    return result;
}
예제 #22
0
char *CGPGHelper::Encrypt(const char *szPlain, const char *szId,
                          unsigned long nPPID)
{
#ifdef HAVE_LIBGPGME
  if (!mCtx) return 0;
  if (!szPlain) return 0;

  char szUser[MAX_LINE_LEN], buf[MAX_LINE_LEN];
  buf[0] = '\0';
  sprintf(szUser, "%s.%lu", szId, nPPID);
  mKeysIni.SetSection("keys");

  ICQUser *u = gUserManager.FetchUser( szId, nPPID, LOCK_R );
  if ( u )
  {
    const char *tmp = u->GPGKey();
    if ( tmp && tmp[0]!='\0' )
      strncpy( buf, tmp, MAX_LINE_LEN-1 );
    gUserManager.DropUser( u );
  }
  if ( !buf[0] && !mKeysIni.ReadStr(szUser, buf) ) return 0;
	
  gLog.Info("[GPG] Encrypting message to %s.\n", szId);

  CGPGMEMutex mutex;
  if (!mutex.Lock()) return 0;
  gpgme_key_t rcps[2];
  gpgme_data_t plain = 0, cipher = 0;
  gpgme_error_t err;
  char *szCipher = 0;
  size_t nRead = 0;

  rcps[1] = 0;
  // Still use the old method, gpgme_get_key requires the fingerprint, which
  // actually isn't very helpful.
  if (gpgme_op_keylist_start (mCtx, buf, 0) != GPG_ERR_NO_ERROR)
    gLog.Error("%s[GPG] Couldn't use gpgme recipient: %s\n", L_ERRORxSTR, buf);
  else
  {
    if (gpgme_op_keylist_next(mCtx, rcps) != GPG_ERR_NO_ERROR)
      gLog.Error("%s[GPG] Couldn't get key: %s\n", L_ERRORxSTR, buf);
    else
    {
      if (gpgme_data_new_from_mem(&plain, szPlain, strlen(szPlain), 0) == GPG_ERR_NO_ERROR &&
          gpgme_data_new(&cipher) == GPG_ERR_NO_ERROR)
      {
        if ((err = gpgme_op_encrypt(mCtx, rcps, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher)) == GPG_ERR_NO_ERROR)
        {
          szCipher = gpgme_data_release_and_get_mem(cipher, &nRead);
          cipher = 0;
          szCipher = (char *)realloc(szCipher, nRead + 1);
          szCipher[nRead] = 0;
        }
        else
          gLog.Error("%s[GPG] Encryption failed: %s\n", L_ERRORxSTR, gpgme_strerror(err));
      }
    }

    if (cipher) gpgme_data_release(cipher);
    if (plain) gpgme_data_release(plain);
  }

  gpgme_key_unref(rcps[0]);
  return szCipher;
#else
  return 0;
#endif
}