void crypto_asym::decrypt(generic_file & ciphered, generic_file & clear) { #if GPGME_SUPPORT generic_file_overlay_for_gpgme o_clear = &clear; generic_file_overlay_for_gpgme o_ciphered = &ciphered; gpgme_error_t err = gpgme_op_decrypt_verify(context, o_ciphered.get_gpgme_handle(), o_clear.get_gpgme_handle()); signing_result.clear(); switch(gpgme_err_code(err)) { case GPG_ERR_NO_ERROR: fill_signing_result(); break; case GPG_ERR_INV_VALUE: throw SRC_BUG; case GPG_ERR_NO_DATA: throw Erange("crypto_asym::decrypt", gettext("No data to decrypt")); case GPG_ERR_DECRYPT_FAILED: throw Erange("crypto_asym::decrypt", gettext("Invalid Cipher text")); case GPG_ERR_BAD_PASSPHRASE: throw Erange("crypto_asym::decrypt", gettext("Failed retreiving passphrase")); default: throw Erange("crypto_asym::decrypt", string(gettext("Unexpected error reported by GPGME: ")) + tools_gpgme_strerror_r(err)); } #else throw Efeature("Asymetric Strong encryption algorithms using GPGME"); #endif }
int main (int argc, char *argv[]) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t in, out; gpgme_decrypt_result_t decrypt_result; gpgme_verify_result_t verify_result; char *cipher_2_asc = make_filename ("cipher-2.asc"); char *agent_info; init_gpgme (GPGME_PROTOCOL_OpenPGP); err = gpgme_new (&ctx); fail_if_err (err); agent_info = getenv("GPG_AGENT_INFO"); if (!(agent_info && strchr (agent_info, ':'))) gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); err = gpgme_data_new_from_file (&in, cipher_2_asc, 1); free (cipher_2_asc); fail_if_err (err); err = gpgme_data_new (&out); fail_if_err (err); err = gpgme_op_decrypt_verify (ctx, in, out); fail_if_err (err); decrypt_result = gpgme_op_decrypt_result (ctx); if (decrypt_result->unsupported_algorithm) { fprintf (stderr, "%s:%i: unsupported algorithm: %s\n", __FILE__, __LINE__, decrypt_result->unsupported_algorithm); exit (1); } print_data (out); verify_result = gpgme_op_verify_result (ctx); check_verify_result (verify_result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734", GPG_ERR_NO_ERROR); gpgme_data_release (in); gpgme_data_release (out); gpgme_release (ctx); return 0; }
static GMimeDecryptResult * pkcs7_decrypt (GMimeCryptoContext *context, GMimeStream *istream, GMimeStream *ostream, GError **err) { #ifdef ENABLE_SMIME GMimePkcs7Context *ctx = (GMimePkcs7Context *) context; GMimeDecryptResult *result; Pkcs7Ctx *pkcs7 = ctx->priv; gpgme_decrypt_result_t res; gpgme_data_t input, output; gpgme_error_t error; 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")); return NULL; } 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); return NULL; } /* decrypt the input stream */ if ((error = gpgme_op_decrypt_verify (pkcs7->ctx, input, output)) != GPG_ERR_NO_ERROR) { g_set_error (err, GMIME_GPGME_ERROR, error, _("Decryption failed")); gpgme_data_release (output); gpgme_data_release (input); return NULL; } gpgme_data_release (output); gpgme_data_release (input); return pkcs7_get_decrypt_result (pkcs7); #else g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("S/MIME support is not enabled in this build")); return NULL; #endif /* ENABLE_SMIME */ }
gpgme_data_t sgpgme_decrypt_verify(gpgme_data_t cipher, gpgme_verify_result_t *status, gpgme_ctx_t ctx) { struct passphrase_cb_info_s info; gpgme_data_t plain; gpgme_error_t err; memset (&info, 0, sizeof info); if ((err = gpgme_data_new(&plain)) != GPG_ERR_NO_ERROR) { gpgme_release(ctx); privacy_set_error(_("Couldn't initialize data, %s"), gpgme_strerror(err)); return NULL; } if (gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) { prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent); if (!getenv("GPG_AGENT_INFO") || !prefs_gpg_get_config()->use_gpg_agent) { info.c = ctx; gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } } else { prefs_gpg_enable_agent(TRUE); info.c = ctx; gpgme_set_passphrase_cb (ctx, NULL, &info); } if (gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) { err = gpgme_op_decrypt_verify(ctx, cipher, plain); if (err != GPG_ERR_NO_ERROR) { debug_print("can't decrypt (%s)\n", gpgme_strerror(err)); privacy_set_error("%s", gpgme_strerror(err)); gpgmegtk_free_passphrase(); gpgme_data_release(plain); return NULL; } err = cm_gpgme_data_rewind(plain); if (err) { debug_print("can't seek (%d %d %s)\n", err, errno, strerror(errno)); } debug_print("decrypted.\n"); *status = gpgme_op_verify_result (ctx); } else { err = gpgme_op_decrypt(ctx, cipher, plain); if (err != GPG_ERR_NO_ERROR) { debug_print("can't decrypt (%s)\n", gpgme_strerror(err)); privacy_set_error("%s", gpgme_strerror(err)); gpgmegtk_free_passphrase(); gpgme_data_release(plain); return NULL; } err = cm_gpgme_data_rewind(plain); if (err) { debug_print("can't seek (%d %d %s)\n", err, errno, strerror(errno)); } debug_print("decrypted.\n"); *status = gpgme_op_verify_result (ctx); } return plain; }
/* ############################################################################# * * 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 gpgDecrypt(char* buffer, int size, char** newbuffer, int* newsize, PASSPHRASE_FN password_cb, SHOWERROR_FN showerror_cb) { gpgme_ctx_t context; gpgme_error_t error; gpgme_data_t input, output; gpgme_decrypt_result_t decrypt_result = NULL; gpgme_verify_result_t verify_result; int showerror = 1; char* agent; char* tmpbuffer = NULL; TRACE(99, "gpgDecrypt()", NULL); /* we set our passphrase callback function */ passphrase_callback = password_cb; *newbuffer = NULL; *newsize = 0; error = gpgme_new(&context); if (error) { (showerror_cb)(_("GpgMe context error"), gpgme_strerror(error)); return 1; } else { /* we got a context, we set the passphrase callback */ /* 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) { error = gpgme_op_decrypt_verify(context, input, output); } if (!error) { decrypt_result = gpgme_op_decrypt_result(context); } if (!error && decrypt_result && decrypt_result -> unsupported_algorithm) { tmpbuffer = memAlloc(__FILE__, __LINE__, STDBUFFERLENGTH); snprintf(tmpbuffer, STDBUFFERLENGTH, _("unsupported algorithm: %s\n"), decrypt_result -> unsupported_algorithm); (showerror_cb)(_("GpgMe error"), tmpbuffer); memFree(__FILE__, __LINE__, tmpbuffer, STDBUFFERLENGTH); showerror = 0; error = 1; } if (!error) { verify_result = gpgme_op_verify_result(context); error = gpgCheckVerifyResult(showerror_cb, verify_result, GPG_ERR_NO_ERROR); showerror = !error; } /* we don't need the passphrase any longer */ clearPassphrase(0); if (!error) { tmpbuffer = gpgData2Char(output, newsize); } #ifdef GPGME_HAS_RECIPIENT /* we get the recipients of the message for the further re-encryption of * the file */ if (!error && decrypt_result && decrypt_result -> recipients) { error = gpgGetRecipients(decrypt_result -> recipients, showerror_cb); showerror = 0; } #endif gpgme_data_release(input); gpgme_data_release(output); gpgme_release(context); *newbuffer = tmpbuffer; if (error) { if (showerror) { (showerror_cb)(_("GpgMe decrypt error"), gpgme_strerror(error)); } return 1; } else return 0; }
/* The main GPG decryption routine for libfko. */ int gpgme_decrypt(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_error_t err; gpgme_decrypt_result_t decrypt_res; gpgme_verify_result_t verify_res; /* Initialize gpgme */ res = init_gpgme(fko_ctx); if(res != FKO_SUCCESS) return(res); gpg_ctx = fko_ctx->gpg_ctx; err = gpgme_data_new(&plaintext); 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); } /* Initialize the cipher data (place into gpgme_data object) */ err = gpgme_data_new_from_mem(&cipher, (char*)indata, in_len, 0); 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); } /* Set the passphrase callback. */ gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw); /* Now decrypt and verify. */ err = gpgme_op_decrypt_verify(gpg_ctx, cipher, plaintext); 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_DECRYPT_FAILED); } /* Done with the cipher text. */ gpgme_data_release(cipher); /* We check the "usupported_algorithm" flag in the decrypt result. */ decrypt_res = gpgme_op_decrypt_result(gpg_ctx); if(decrypt_res->unsupported_algorithm) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; return(FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM); } /* Now verify the signatures if so configured. */ if(fko_ctx->verify_gpg_sigs) { verify_res = gpgme_op_verify_result(gpg_ctx); res = process_sigs(fko_ctx, verify_res); if(res != FKO_SUCCESS) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; return(res); } } /* Get the encrypted data and its length from the gpgme data object. */ tmp_buf = gpgme_data_release_and_get_mem(plaintext, out_len); /* Use calloc here with an extra byte because I am not sure if all systems * will include the terminating NULL with the decrypted data (which is * expected to be a string). */ *out = calloc(1, *out_len+1); /* 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); }
/** \brief Decrypt data * * \param istream GMime input (encrypted) stream. * \param ostream GMime output (decrypted) stream. * \param protocol GpgME crypto protocol to use. * \param parent Parent window to be passed to the passphrase callback * function. * \param error Filled with error information on error. * \return A new signature status object on success, or NULL on error. * * Decrypt and -if applicable- verify the signature of the passed data * stream. If the input is not signed the returned signature status will * be GPG_ERR_NOT_SIGNED. */ GMimeGpgmeSigstat * libbalsa_gpgme_decrypt(GMimeStream * crypted, GMimeStream * plain, gpgme_protocol_t protocol, GtkWindow * parent, GError ** error) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t plain_data; gpgme_data_t crypt_data; GMimeGpgmeSigstat *result; 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(GMIME_IS_STREAM(crypted), NULL); g_return_val_if_fail(GMIME_IS_STREAM(plain), NULL); g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP || protocol == GPGME_PROTOCOL_CMS, NULL); /* create the GpgME context */ if ((err = gpgme_new_with_protocol(&ctx, protocol, parent, error)) != GPG_ERR_NO_ERROR) return NULL; /* create the data streams */ if ((err = gpgme_data_new_from_cbs(&crypt_data, &cbs, crypted)) != GPG_ERR_NO_ERROR) { g_set_error_from_gpgme(error, err, _("could not get data from stream")); gpgme_release(ctx); return NULL; } if ((err = gpgme_data_new_from_cbs(&plain_data, &cbs, plain)) != GPG_ERR_NO_ERROR) { g_set_error_from_gpgme(error, err, _("could not create new data object")); gpgme_data_release(crypt_data); gpgme_release(ctx); return NULL; } /* try to decrypt */ if ((err = gpgme_op_decrypt_verify(ctx, crypt_data, plain_data)) != GPG_ERR_NO_ERROR) { g_set_error_from_gpgme(error, err, _("decryption failed")); result = NULL; } else { /* decryption successful, check for signature */ result = g_mime_gpgme_sigstat_new_from_gpgme_ctx(ctx); } /* clean up */ gpgme_data_release(plain_data); gpgme_data_release(crypt_data); gpgme_release(ctx); return result; }
static PyObject * pygpgme_context_decrypt_verify(PyGpgmeContext *self, PyObject *args) { PyObject *py_cipher, *py_plain; gpgme_data_t cipher, plain; gpgme_error_t err; gpgme_verify_result_t result; if (!PyArg_ParseTuple(args, "OO", &py_cipher, &py_plain)) return NULL; if (pygpgme_data_new(&cipher, py_cipher)) { return NULL; } if (pygpgme_data_new(&plain, py_plain)) { gpgme_data_release(cipher); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_decrypt_verify(self->ctx, cipher, plain); Py_END_ALLOW_THREADS; gpgme_data_release(cipher); gpgme_data_release(plain); if (pygpgme_check_error(err)) { decode_decrypt_result(self); return NULL; } result = gpgme_op_verify_result(self->ctx); /* annotate exception */ if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyObject *list; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (result == NULL) goto end; if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; list = pygpgme_siglist_new(result->signatures); PyObject_SetAttrString(err_value, "signatures", list); Py_DECREF(list); end: PyErr_Restore(err_type, err_value, err_traceback); return NULL; } if (result) return pygpgme_siglist_new(result->signatures); else return PyList_New(0); }