static GMimeDecryptResult * pkcs7_get_decrypt_result (Pkcs7Ctx *pkcs7) { GMimeDecryptResult *result; gpgme_decrypt_result_t res; gpgme_recipient_t recipient; GMimeCertificate *cert; result = g_mime_decrypt_result_new (); result->recipients = g_mime_certificate_list_new (); result->signatures = pkcs7_get_signatures (pkcs7, FALSE); if (!(res = gpgme_op_decrypt_result (pkcs7->ctx)) || !res->recipients) return result; recipient = res->recipients; while (recipient != NULL) { cert = g_mime_certificate_new (); g_mime_certificate_list_add (result->recipients, cert); g_mime_certificate_set_pubkey_algo (cert, recipient->pubkey_algo); g_mime_certificate_set_key_id (cert, recipient->keyid); recipient = recipient->next; } return result; }
char *gpg_decrypt_msg(const char *data, long *plain_size) { gpgme_ctx_t ctx; gpgme_error_t err; size_t n = 0; char *temp, *str, *msg; gpgme_data_t plain, cipher; msg = add_gpg_headers(data); if (!msg) { return 0; } err = gpgme_new(&ctx); if (err) { return 0; } gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); gpgme_set_armor(ctx, 1); // char *p = getenv("GPG_AGENT_INFO"); // if (p) { // log_write("GPG_AGENT_INFO: %s\n", p); // } else { // setenv("GPG_AGENT_INFO", "/tmp/gpg-3FhMq6/S.gpg-agent:22765:1", 1); // log_write("NO GPG AGENT INFO FOUND\n"); // } gpgme_set_passphrase_cb(ctx, &passphrase_cb, 0); gpgme_data_new_from_mem(&cipher, msg, strlen(msg), 0); gpgme_data_new(&plain); err = gpgme_op_decrypt(ctx, cipher, plain); gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx); gpgme_recipient_t recipient = res->recipients; while (recipient) { log_write(">>> recipient keyid: %s\n", recipient->keyid); recipient = recipient->next; } gpgme_data_release(cipher); free(msg); if (err) { log_write("gpgme_op_decrypt error: %s\n", gpgme_strerror(err)); gpgme_data_release(plain); gpgme_release(ctx); return 0; } temp = gpgme_data_release_and_get_mem(plain, &n); if (!temp) { gpgme_release(ctx); return 0; } *plain_size = n; str = strndup(temp, n); free(temp); gpgme_release(ctx); return str; }
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; }
int main (int argc, char *argv[]) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t in, out; gpgme_decrypt_result_t result; char *cipher_1_asc = make_filename ("cipher-1.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_1_asc, 1); free (cipher_1_asc); fail_if_err (err); err = gpgme_data_new (&out); fail_if_err (err); err = gpgme_op_decrypt (ctx, in, out); fail_if_err (err); result = gpgme_op_decrypt_result (ctx); if (result->unsupported_algorithm) { fprintf (stderr, "%s:%i: unsupported algorithm: %s\n", __FILE__, __LINE__, result->unsupported_algorithm); exit (1); } print_data (out); gpgme_data_release (in); gpgme_data_release (out); gpgme_release (ctx); return 0; }
/* Not that this closure is called in the context of the waiter_thread. */ static void decrypt_closure (closure_data_t cld, gpgme_ctx_t ctx, gpg_error_t err) { update_passphrase_cache (err, &cld->pw_cb); if (!err && !cld->with_verify) ; else if (!err) { gpgme_verify_result_t res; /* Decryption succeeded. Now check the state of the signatures. */ res = gpgme_op_verify_result (ctx); if (res && res->signatures) verify_dialog_box (gpgme_get_protocol (ctx), res, NULL); } else if (gpg_err_code (err) == GPG_ERR_DECRYPT_FAILED) { /* The decryption failed. See whether we can figure out a more suitable error code. */ gpgme_decrypt_result_t res; res = gpgme_op_decrypt_result (ctx); if (res && res->recipients && gpgme_err_code (res->recipients->status) == GPG_ERR_NO_SECKEY) err = gpg_error (GPG_ERR_NO_SECKEY); /* Fixme: return the keyids */ } else { /* Decryption failed for other reasons. */ } /* If the passphrase callback indicated a cancel operation, change the the error code accordingly. */ if (err && (cld->pw_cb.opts & OPT_FLAG_CANCEL)) err = gpg_error (GPG_ERR_CANCELED); engine_private_finished (cld->filter, err); }
bool KGpgMe::decrypt(const QByteArray& inBuffer, QByteArray* outBuffer) { gpgme_error_t err = 0; gpgme_data_t in = 0, out = 0; gpgme_decrypt_result_t result = 0; outBuffer->resize(0); if(m_ctx) { err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); if(!err) { err = gpgme_data_new(&out); if(!err) { err = gpgme_op_decrypt(m_ctx, in, out); if(!err) { result = gpgme_op_decrypt_result(m_ctx); if(result->unsupported_algorithm) { KMessageBox::error(kapp->activeWindow(), QString("%1: %2") .arg(i18n("Unsupported algorithm")) .arg(result->unsupported_algorithm)); } 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(in) gpgme_data_release(in); if(out) gpgme_data_release(out); return (err == GPG_ERR_NO_ERROR); }
static void decode_decrypt_result(PyGpgmeContext *self) { PyObject *err_type, *err_value, *err_traceback; PyObject *value; gpgme_decrypt_result_t res; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; res = gpgme_op_decrypt_result(self->ctx); if (res == NULL) goto end; if (res->unsupported_algorithm) { value = PyUnicode_DecodeUTF8(res->unsupported_algorithm, strlen(res->unsupported_algorithm), "replace"); } else { Py_INCREF(Py_None); value = Py_None; } if (value) { PyObject_SetAttrString(err_value, "unsupported_algorithm", value); Py_DECREF(value); } value = PyBool_FromLong(res->wrong_key_usage); if (value) { PyObject_SetAttrString(err_value, "wrong_key_usage", value); Py_DECREF(value); } end: PyErr_Restore(err_type, err_value, err_traceback); }
/* ############################################################################# * * 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); }
char* p_gpg_decrypt(const char *const cipher) { 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_set_passphrase_cb(ctx, (gpgme_passphrase_cb_t)_p_gpg_passphrase_cb, NULL); char *cipher_with_headers = _add_header_footer(cipher, PGP_MESSAGE_HEADER, PGP_MESSAGE_FOOTER); gpgme_data_t cipher_data; gpgme_data_new_from_mem(&cipher_data, cipher_with_headers, strlen(cipher_with_headers), 1); free(cipher_with_headers); gpgme_data_t plain_data; gpgme_data_new(&plain_data); error = gpgme_op_decrypt(ctx, cipher_data, plain_data); gpgme_data_release(cipher_data); if (error) { log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error)); gpgme_data_release(plain_data); gpgme_release(ctx); return NULL; } gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx); if (res) { GString *recipients_str = g_string_new(""); gpgme_recipient_t recipient = res->recipients; while (recipient) { gpgme_key_t key; error = gpgme_get_key(ctx, recipient->keyid, &key, 1); if (!error && key) { const char *addr = gpgme_key_get_string_attr(key, GPGME_ATTR_EMAIL, NULL, 0); if (addr) { g_string_append(recipients_str, addr); } gpgme_key_unref(key); } if (recipient->next) { g_string_append(recipients_str, ", "); } recipient = recipient->next; } log_debug("GPG: Decrypted message for recipients: %s", recipients_str->str); g_string_free(recipients_str, TRUE); } gpgme_release(ctx); size_t len = 0; char *plain_str = gpgme_data_release_and_get_mem(plain_data, &len); char *result = NULL; if (plain_str) { plain_str[len] = 0; result = g_strdup(plain_str); } gpgme_free(plain_str); if (passphrase_attempt) { passphrase = strdup(passphrase_attempt); } return result; }
QByteArray GPGME::decryptFile(const QString & filename, QString & keyId, QWidget * parent) { setError(GPG_ERR_NO_ERROR); // clear error CallbackData cbData; cbData.parent = parent; qDebug() << "ERERR" << gpg_err_source(GPG_ERR_CODE_DIM+1); gpgme_set_passphrase_cb(p->context, passphraseCallback, &cbData); qDebug() << "decrypting file" << filename; gpgme_data_t data; gpgme_error_t err; QFile file(filename); if (!file.exists()) { setError(GPGME_WRAPPER_ERR_FILE_NOT_FOUND, true); return QByteArray(); } if (!file.open(QIODevice::ReadOnly)) { setError(GPGME_WRAPPER_ERR_CANNOT_OPEN_FILE, true); return QByteArray(); } if (file.size() > FILESIZE_HARD_LIMIT) { setError(GPGME_WRAPPER_ERR_FILE_TOO_LARGE, true); return QByteArray(); } err = gpgme_data_new_from_fd(&data, file.handle()); if (err != GPG_ERR_NO_ERROR) { setError(err); return QByteArray(); } // process data (it's cipher) gpgme_data_t plain; gpgme_data_new(&plain); err = gpgme_op_decrypt(p->context, data, plain); // unset passphrase callback gpgme_set_passphrase_cb(p->context, 0, 0); if (err != GPG_ERR_NO_ERROR) { gpgme_data_release(data); gpgme_data_release(plain); setError(err); return QByteArray(); } // decryption is successful so load plain data QByteArray resBytes; const int bufSize = 1000; int read; char buf[bufSize]; gpgme_data_seek(plain, 0, SEEK_SET); while (true) { read = gpgme_data_read(plain, (void*)buf, bufSize); if (read == 0) { break; } if (read == -1) { // error, ignore for now break; } resBytes.append(buf, read); } gpgme_decrypt_result_t decrypt_res = gpgme_op_decrypt_result(p->context); gpgme_recipient_t recipient; if (decrypt_res) { recipient = decrypt_res->recipients; while (recipient) { keyId = recipient->keyid; recipient = recipient->next; break; // just ignore the other recipients } } return resBytes; }