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()); }
int main (int argc, char *argv[]) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t in, out; gpgme_sign_result_t result; init_gpgme (GPGME_PROTOCOL_CMS); err = gpgme_new (&ctx); fail_if_err (err); gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); gpgme_set_textmode (ctx, 1); gpgme_set_armor (ctx, 1); err = gpgme_data_new_from_mem (&in, "Hallo Leute!\n", 13, 0); fail_if_err (err); /* First a normal signature. */ err = gpgme_data_new (&out); fail_if_err (err); err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL); fail_if_err (err); result = gpgme_op_sign_result (ctx); check_result (result, GPGME_SIG_MODE_NORMAL); print_data (out); gpgme_data_release (out); /* Now a detached signature. */ gpgme_data_seek (in, 0, SEEK_SET); err = gpgme_data_new (&out); fail_if_err (err); err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_DETACH); fail_if_err (err); result = gpgme_op_sign_result (ctx); check_result (result, GPGME_SIG_MODE_DETACH); print_data (out); gpgme_data_release (out); gpgme_data_release (in); 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_verify_result_t result; char *agent_info; int i; 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_mem (&in, "Hallo Leute\n", 12, 0); fail_if_err (err); err = gpgme_data_new (&out); fail_if_err (err); for (i = 0; i < sizeof (expected_notations) / sizeof (expected_notations[0]); i++) { err = gpgme_sig_notation_add (ctx, expected_notations[i].name, expected_notations[i].value, expected_notations[i].flags); fail_if_err (err); } err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL); fail_if_err (err); gpgme_data_release (in); err = gpgme_data_new (&in); fail_if_err (err); gpgme_data_seek (out, 0, SEEK_SET); err = gpgme_op_verify (ctx, out, NULL, in); fail_if_err (err); result = gpgme_op_verify_result (ctx); check_result (result); gpgme_data_release (in); gpgme_data_release (out); gpgme_release (ctx); return 0; }
static int pkcs7_sign (GMimeCryptoContext *context, const char *userid, GMimeDigestAlgo digest, GMimeStream *istream, GMimeStream *ostream, GError **err) { #ifdef ENABLE_SMIME GMimePkcs7Context *ctx = (GMimePkcs7Context *) context; Pkcs7Ctx *pkcs7 = ctx->priv; gpgme_sign_result_t result; gpgme_data_t input, output; gpgme_error_t error; if (!pkcs7_add_signer (pkcs7, userid, err)) return -1; gpgme_set_armor (pkcs7->ctx, FALSE); 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 -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); return -1; } /* sign the input stream */ if ((error = gpgme_op_sign (pkcs7->ctx, input, output, GPGME_SIG_MODE_DETACH)) != GPG_ERR_NO_ERROR) { g_set_error (err, GMIME_GPGME_ERROR, error, _("Signing failed")); gpgme_data_release (output); gpgme_data_release (input); return -1; } gpgme_data_release (output); gpgme_data_release (input); /* return the digest algorithm used for signing */ result = gpgme_op_sign_result (pkcs7->ctx); return pkcs7_digest_id (context, gpgme_hash_algo_name (result->signatures->hash_algo)); #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 */ }
static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account, const gchar *from_addr) { MimeInfo *msgcontent; gchar *textstr, *tmp; FILE *fp; gchar *sigcontent; gpgme_ctx_t ctx; gpgme_data_t gpgtext, gpgsig; size_t len; gpgme_error_t err; struct passphrase_cb_info_s info; gpgme_sign_result_t result = NULL; memset (&info, 0, sizeof info); /* 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")); 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) { perror("my_tmpfile"); privacy_set_error(_("Couldn't create temporary file.")); return FALSE; } procmime_write_mimeinfo(msgcontent, fp); rewind(fp); /* read temporary file into memory */ textstr = fp_read_noconv(fp); fclose(fp); gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgsig); 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)); return FALSE; } gpgme_set_textmode(ctx, 1); gpgme_set_armor(ctx, 1); if (!sgpgme_setup_signers(ctx, account, from_addr)) { gpgme_release(ctx); return FALSE; } 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); } err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_CLEAR); if (err != GPG_ERR_NO_ERROR) { if (err == GPG_ERR_CANCELED) { /* ignore cancelled signing */ privacy_reset_error(); debug_print("gpgme_op_sign cancelled\n"); } else { privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err)); debug_print("gpgme_op_sign error : %x\n", err); } gpgme_release(ctx); return FALSE; } result = gpgme_op_sign_result(ctx); if (result && result->signatures) { gpgme_new_signature_t sig = result->signatures; while (sig) { debug_print("valid signature: %s\n", sig->fpr); sig = sig->next; } } else if (result && result->invalid_signers) { gpgme_invalid_key_t invalid = result->invalid_signers; while (invalid) { g_warning("invalid signer: %s (%s)", invalid->fpr, gpgme_strerror(invalid->reason)); privacy_set_error(_("Data signing failed due to invalid signer: %s"), gpgme_strerror(invalid->reason)); invalid = invalid->next; } gpgme_release(ctx); return FALSE; } else { /* can't get result (maybe no signing key?) */ debug_print("gpgme_op_sign_result error\n"); privacy_set_error(_("Data signing failed, no results.")); gpgme_release(ctx); return FALSE; } sigcontent = sgpgme_data_release_and_get_mem(gpgsig, &len); if (sigcontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Data signing failed, no contents.")); gpgme_data_release(gpgtext); g_free(textstr); g_free(sigcontent); gpgme_release(ctx); return FALSE; } tmp = g_malloc(len+1); g_memmove(tmp, sigcontent, len+1); tmp[len] = '\0'; gpgme_data_release(gpgtext); g_free(textstr); g_free(sigcontent); 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); /* avoid all sorts of clear-signing problems with non ascii * chars */ procmime_encode_content(msgcontent, ENC_BASE64); gpgme_release(ctx); return TRUE; }
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 ; }
/** \brief Sign data * * \param userid User ID of the signer. * \param istream GMime input stream. * \param ostream GMime output stream. * \param protocol GpgME crypto protocol of the signature. * \param singlepart_mode TRUE indicates single-part mode (integrated * signature), FALSE a detached signature. * \param parent Parent window to be passed to the passphrase callback * function. * \param error Filled with error information on error. * \return The hash algorithm used for creating the signature, or * GPGME_MD_NONE on error. * * Sign the passed matter and write the detached signature or the signed * input and the signature, respectively, to the output stream. The global * callback to read the passphrase for the user's private key will be * called by GpgME if no GPG Agent is running. */ gpgme_hash_algo_t libbalsa_gpgme_sign(const gchar * userid, GMimeStream * istream, GMimeStream * ostream, gpgme_protocol_t protocol, gboolean singlepart_mode, GtkWindow * parent, GError ** error) { gpgme_error_t err; gpgme_ctx_t ctx; gpgme_sig_mode_t sig_mode; gpgme_data_t in; gpgme_data_t out; gpgme_hash_algo_t hash_algo; 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(istream), GPGME_MD_NONE); 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, GPGME_MD_NONE); /* create the GpgME context */ if ((err = gpgme_new_with_protocol(&ctx, protocol, parent, error)) != GPG_ERR_NO_ERROR) return GPGME_MD_NONE; /* set the signature mode */ if (singlepart_mode) { if (protocol == GPGME_PROTOCOL_OpenPGP) sig_mode = GPGME_SIG_MODE_CLEAR; else sig_mode = GPGME_SIG_MODE_NORMAL; } else sig_mode = GPGME_SIG_MODE_DETACH; /* find the secret key for the "sign_for" address */ if (!gpgme_add_signer(ctx, userid, parent, error)) { gpgme_release(ctx); return GPGME_MD_NONE; } /* OpenPGP signatures are ASCII armored */ gpgme_set_armor(ctx, protocol == GPGME_PROTOCOL_OpenPGP); /* create gpgme data objects */ if ((err = gpgme_data_new_from_cbs(&in, &cbs, istream)) != GPG_ERR_NO_ERROR) { g_set_error_from_gpgme(error, err, _("could not get data from stream")); gpgme_release(ctx); return GPGME_MD_NONE; } if ((err = gpgme_data_new_from_cbs(&out, &cbs, ostream)) != GPG_ERR_NO_ERROR) { g_set_error_from_gpgme(error, err, _("could not create new data object")); gpgme_data_release(in); gpgme_release(ctx); return GPGME_MD_NONE; } /* sign and get the used hash algorithm */ err = gpgme_op_sign(ctx, in, out, sig_mode); if (err != GPG_ERR_NO_ERROR) { g_set_error_from_gpgme(error, err, _("signing failed")); hash_algo = GPGME_MD_NONE; } else hash_algo = gpgme_op_sign_result(ctx)->signatures->hash_algo; /* clean up */ gpgme_data_release(in); gpgme_data_release(out); gpgme_release(ctx); return hash_algo; }
/* ------------------ * 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; }
gpointer sign_file (const gchar *input_file_path, const gchar *fpr) { gpgme_error_t error; gpgme_ctx_t context; gpgme_key_t signing_key; gpgme_data_t clear_text, signed_text; gpgme_sign_result_t result; gchar *buffer; gssize nbytes; error = gpgme_new (&context); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); return GPGME_ERROR; } gpgme_set_armor (context, 0); error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } const char *keyring_dir = gpgme_get_dirinfo ("homedir"); error = gpgme_ctx_set_engine_info (context, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_get_key (context, fpr, &signing_key, 1); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_signers_add (context, signing_key); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } FILE *infp = g_fopen (input_file_path, "r"); if (infp == NULL) { g_printerr ("Couldn't open input file\n"); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return FILE_OPEN_ERROR; } error = gpgme_data_new_from_stream (&clear_text, infp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_new (&signed_text); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_op_sign (context, clear_text, signed_text, GPGME_SIG_MODE_DETACH); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } result = gpgme_op_sign_result (context); if (result->invalid_signers) { g_printerr ("Invalid signer found: %s\n", result->invalid_signers->fpr); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } if (!result->signatures || result->signatures->next) { g_printerr ("Unexpected number of signatures created\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_seek (signed_text, 0, SEEK_SET); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } buffer = g_try_malloc0 (SIG_MAXLEN); if (buffer == NULL) { g_printerr ("Couldn't allocate memory\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return MEMORY_ALLOCATION_ERROR; } nbytes = gpgme_data_read (signed_text, buffer, SIG_MAXLEN); if (nbytes == -1) { g_printerr ("Error while reading data\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } GError *gerr = NULL; gchar *output_file_path = g_strconcat (input_file_path, ".sig", NULL); GFile *fpout = g_file_new_for_path (output_file_path); GFileOutputStream *ostream = g_file_append_to (fpout, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &gerr); if (gerr != NULL) { g_printerr ("Couldn't open output file for writing\n"); cleanup (infp, fpout, NULL, output_file_path, &signing_key, &context); return FILE_OPEN_ERROR; } gssize wbytes = g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer, nbytes, NULL, &gerr); if (wbytes == -1) { g_printerr ("Couldn't write the request number of bytes (%s)\n", gerr->message); cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return FILE_WRITE_ERROR; } cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return SIGN_OK; }
int main (int argc, char **argv) { int last_argc = -1; gpgme_error_t err; gpgme_ctx_t ctx; const char *key_string = NULL; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_CLEAR; gpgme_data_t in, out; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) show_usage (0); else if (!strcmp (*argv, "--key")) { argc--; argv++; if (!argc) show_usage (1); key_string = *argv; argc--; argv++; } else if (!strncmp (*argv, "--", 2)) show_usage (1); } if (argc != 1) show_usage (1); init_gpgme (protocol); err = gpgme_new (&ctx); fail_if_err (err); gpgme_set_protocol (ctx, protocol); gpgme_set_armor (ctx, 1); if (key_string) { gpgme_key_t akey; err = gpgme_get_key (ctx, key_string, &akey, 1); if (err) { exit (1); } err = gpgme_signers_add (ctx, akey); fail_if_err (err); gpgme_key_unref (akey); } err = gpgme_data_new_from_file (&in, *argv, 1); if (err) { fprintf (stderr, PGM ": error reading `%s': %s\n", *argv, gpg_strerror (err)); exit (1); } err = gpgme_data_new (&out); fail_if_err (err); err = gpgme_op_sign (ctx, in, out, sigmode); if (err) { fprintf (stderr, PGM ": signing failed: %s\n", gpg_strerror (err)); exit (1); } print_data (out); gpgme_data_release (out); gpgme_data_release (in); gpgme_release (ctx); return 0; }
char* p_gpg_sign(const char *const str, const char *const fp) { 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); gpgme_key_t key = NULL; error = gpgme_get_key(ctx, fp, &key, 1); if (error || key == NULL) { log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); gpgme_release(ctx); return NULL; } gpgme_signers_clear(ctx); error = gpgme_signers_add(ctx, key); gpgme_key_unref(key); if (error) { log_error("GPG: Failed to load signer. %s %s", gpgme_strsource(error), gpgme_strerror(error)); gpgme_release(ctx); return NULL; } char *str_or_empty = NULL; if (str) { str_or_empty = strdup(str); } else { str_or_empty = strdup(""); } gpgme_data_t str_data; gpgme_data_new_from_mem(&str_data, str_or_empty, strlen(str_or_empty), 1); free(str_or_empty); gpgme_data_t signed_data; gpgme_data_new(&signed_data); gpgme_set_armor(ctx,1); error = gpgme_op_sign(ctx, str_data, signed_data, GPGME_SIG_MODE_DETACH); gpgme_data_release(str_data); gpgme_release(ctx); if (error) { log_error("GPG: Failed to sign string. %s %s", gpgme_strsource(error), gpgme_strerror(error)); gpgme_data_release(signed_data); return NULL; } char *result = NULL; size_t len = 0; char *signed_str = gpgme_data_release_and_get_mem(signed_data, &len); if (signed_str) { GString *signed_gstr = g_string_new(""); g_string_append_len(signed_gstr, signed_str, len); result = _remove_header_footer(signed_gstr->str, PGP_SIGNATURE_FOOTER); g_string_free(signed_gstr, TRUE); gpgme_free(signed_str); } if (passphrase_attempt) { passphrase = strdup(passphrase_attempt); } return result; }
gboolean pgpmime_sign(MimeInfo *mimeinfo, PrefsAccount *account, const gchar *from_addr) { MimeInfo *msgcontent, *sigmultipart, *newinfo; gchar *textstr, *micalg = NULL; FILE *fp; gchar *boundary = NULL; gchar *sigcontent; gpgme_ctx_t ctx; gpgme_data_t gpgtext, gpgsig; gpgme_error_t err; size_t len; struct passphrase_cb_info_s info; gpgme_sign_result_t result = NULL; gchar *test_msg; fp = my_tmpfile(); if (fp == NULL) { perror("my_tmpfile"); privacy_set_error(_("Couldn't create temporary file: %s"), g_strerror(errno)); return FALSE; } procmime_write_mimeinfo(mimeinfo, fp); rewind(fp); /* read temporary file into memory */ test_msg = file_read_stream_to_str(fp); claws_fclose(fp); memset (&info, 0, sizeof info); /* remove content node from message */ msgcontent = (MimeInfo *) mimeinfo->node->children->data; g_node_unlink(msgcontent->node); /* create temporary multipart for content */ sigmultipart = procmime_mimeinfo_new(); sigmultipart->type = MIMETYPE_MULTIPART; sigmultipart->subtype = g_strdup("signed"); do { g_free(boundary); boundary = generate_mime_boundary("Sig"); } while (strstr(test_msg, boundary) != NULL); g_free(test_msg); g_hash_table_insert(sigmultipart->typeparameters, g_strdup("boundary"), g_strdup(boundary)); g_hash_table_insert(sigmultipart->typeparameters, g_strdup("protocol"), g_strdup("application/pgp-signature")); g_node_append(sigmultipart->node, msgcontent->node); g_node_append(mimeinfo->node, sigmultipart->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)); return FALSE; } procmime_write_mimeinfo(sigmultipart, fp); rewind(fp); /* read temporary file into memory */ textstr = get_canonical_content(fp, boundary); g_free(boundary); claws_fclose(fp); gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgsig); 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)); return FALSE; } gpgme_set_textmode(ctx, 1); gpgme_set_armor(ctx, 1); gpgme_signers_clear (ctx); if (!sgpgme_setup_signers(ctx, account, from_addr)) { gpgme_release(ctx); return FALSE; } prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent); if (g_getenv("GPG_AGENT_INFO") && prefs_gpg_get_config()->use_gpg_agent) { debug_print("GPG_AGENT_INFO environment defined, running without passphrase callback\n"); } else { info.c = ctx; gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_DETACH); if (err != GPG_ERR_NO_ERROR) { if (err == GPG_ERR_CANCELED) { /* ignore cancelled signing */ privacy_reset_error(); debug_print("gpgme_op_sign cancelled\n"); } else { privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err)); debug_print("gpgme_op_sign error : %x\n", err); } gpgme_release(ctx); return FALSE; } result = gpgme_op_sign_result(ctx); if (result && result->signatures) { gpgme_new_signature_t sig = result->signatures; if (gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) { gchar *down_algo = g_ascii_strdown(gpgme_hash_algo_name( result->signatures->hash_algo), -1); micalg = g_strdup_printf("pgp-%s", down_algo); g_free(down_algo); } else { micalg = g_strdup(gpgme_hash_algo_name( result->signatures->hash_algo)); } while (sig) { debug_print("valid signature: %s\n", sig->fpr); sig = sig->next; } } else if (result && result->invalid_signers) { gpgme_invalid_key_t invalid = result->invalid_signers; while (invalid) { g_warning("invalid signer: %s (%s)", invalid->fpr, gpgme_strerror(invalid->reason)); privacy_set_error(_("Data signing failed due to invalid signer: %s"), gpgme_strerror(invalid->reason)); invalid = invalid->next; } gpgme_release(ctx); return FALSE; } else { /* can't get result (maybe no signing key?) */ debug_print("gpgme_op_sign_result error\n"); privacy_set_error(_("Data signing failed, no results.")); gpgme_release(ctx); return FALSE; } sigcontent = sgpgme_data_release_and_get_mem(gpgsig, &len); gpgme_data_release(gpgtext); g_free(textstr); if (sigcontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Data signing failed, no contents.")); g_free(micalg); g_free(sigcontent); return FALSE; } /* add signature */ g_hash_table_insert(sigmultipart->typeparameters, g_strdup("micalg"), micalg); newinfo = procmime_mimeinfo_new(); newinfo->type = MIMETYPE_APPLICATION; newinfo->subtype = g_strdup("pgp-signature"); newinfo->description = g_strdup(_("OpenPGP digital signature")); newinfo->content = MIMECONTENT_MEM; newinfo->data.mem = g_malloc(len + 1); g_memmove(newinfo->data.mem, sigcontent, len); newinfo->data.mem[len] = '\0'; g_node_append(sigmultipart->node, newinfo->node); g_free(sigcontent); gpgme_release(ctx); return TRUE; }
static PyObject * pygpgme_context_sign(PyGpgmeContext *self, PyObject *args) { PyObject *py_plain, *py_sig; gpgme_data_t plain, sig; int sig_mode = GPGME_SIG_MODE_NORMAL; gpgme_error_t err; gpgme_sign_result_t result; if (!PyArg_ParseTuple(args, "OO|i", &py_plain, &py_sig, &sig_mode)) return NULL; if (pygpgme_data_new(&plain, py_plain)) return NULL; if (pygpgme_data_new(&sig, py_sig)) { gpgme_data_release(plain); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_sign(self->ctx, plain, sig, sig_mode); Py_END_ALLOW_THREADS; gpgme_data_release(plain); gpgme_data_release(sig); result = gpgme_op_sign_result(self->ctx); /* annotate exception */ if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyObject *list; gpgme_invalid_key_t key; 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 = PyList_New(0); for (key = result->invalid_signers; key != NULL; key = key->next) { PyObject *item, *py_fpr, *err; if (key->fpr) py_fpr = PyUnicode_DecodeASCII(key->fpr, strlen(key->fpr), "replace"); else { py_fpr = Py_None; Py_INCREF(py_fpr); } err = pygpgme_error_object(key->reason); item = Py_BuildValue("(NN)", py_fpr, err); PyList_Append(list, item); Py_DECREF(item); } PyObject_SetAttrString(err_value, "invalid_signers", list); Py_DECREF(list); list = pygpgme_newsiglist_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_newsiglist_new(result->signatures); else return PyList_New(0); }