diff --git a/README.org b/README.org index 60cc3c1..436d359 100644 --- a/README.org +++ b/README.org @@ -51,7 +51,6 @@ - libxml2 (dynamic, dependency) - lmdb (dynamic, dependency) - libomemo-c (libsignal-protocol-c) (dynamic, dependency) - - rnp (dynamic, dependency) - gpgme (dynamic, dependency) - weechat (>= v3.0) @@ -158,14 +157,13 @@ * [ ] Delete bookmarks * [ ] Roster * [ ] OTR (libotr) - * [X] PGP (rnpgp) - * [X] Use keyrings (e.g. exported from gnupg) + * [X] PGP (gpgme) + * [X] Use keyrings (from gnupg) * [X] Presence * [X] Decryption * [X] Encryption * [X] Custom set/clear key (/pgp) * [ ] Save pgp key set per jid/muc - * [ ] GPGME * [ ] Room Explorer (https://search.jabber.network/docs/api) ** TODO [#C] Adhere to CCS (milestone v0.3) ** TODO [#D] Close all issues (milestone v1.0) diff --git a/makefile b/makefile index f862aea..f45ca38 100644 --- a/makefile +++ b/makefile @@ -9,7 +9,6 @@ FIND=find INCLUDES=-Ilibstrophe -Ideps -Ideps/fmt/include \ $(shell xml2-config --cflags) \ $(shell pkg-config --cflags gpgme) \ - $(shell pkg-config --cflags librnp) \ $(shell pkg-config --cflags libsignal-protocol-c) CFLAGS+=$(DBGCFLAGS) \ -fno-omit-frame-pointer -fPIC \ @@ -36,7 +35,6 @@ LDLIBS=-lstrophe \ -lpthread \ $(shell xml2-config --libs) \ $(shell pkg-config --libs gpgme) \ - $(shell pkg-config --libs librnp) \ $(shell pkg-config --libs libsignal-protocol-c) \ -lgcrypt \ -llmdb diff --git a/pgp.cpp b/pgp.cpp index adc7913..0f35a44 100644 --- a/pgp.cpp +++ b/pgp.cpp @@ -6,47 +6,61 @@ #include #include #include -#include +#include #include #include "plugin.hh" #include "pgp.hh" -#define RNP_SUCCESS 0 - -#define PGP_MESSAGE_HEADER "-----BEGIN PGP MESSAGE-----\r\n\r\n" -#define PGP_MESSAGE_FOOTER "\r\n-----END PGP MESSAGE-----\r\n" -#define PGP_SIGNATURE_HEADER "-----BEGIN PGP SIGNATURE-----\r\n\r\n" -#define PGP_SIGNATURE_FOOTER "\r\n-----END PGP SIGNATURE-----\r\n" +#define PGP_MESSAGE_HEADER "-----BEGIN PGP MESSAGE-----\r\n" +#define PGP_MESSAGE_FOOTER "\r\n-----END PGP MESSAGE-----" +#define PGP_SIGNATURE_HEADER "-----BEGIN PGP SIGNATURE-----\r\n" +#define PGP_SIGNATURE_FOOTER "\r\n-----END PGP SIGNATURE-----" const char *PGP_ADVICE = "[PGP encrypted message (XEP-0027)]"; void pgp__init(struct t_pgp **pgp, const char *pub, const char *sec) { struct t_pgp *new_pgp; - rnp_input_t keyring; + gpgme_error_t err; + gpgme_data_t keydata; + + gpgme_check_version(NULL); new_pgp = (struct t_pgp*)calloc(1, sizeof(**pgp)); - if (rnp_ffi_create(&new_pgp->context, - RNP_KEYSTORE_GPG, RNP_KEYSTORE_GPG) != RNP_SUCCESS) { + err = gpgme_new(&new_pgp->gpgme); + if (err) { + return; + } + gpgme_set_armor(new_pgp->gpgme, true); + + err = gpgme_data_new_from_file(&keydata, pub, true); + if (err) { return; } - if (rnp_input_from_path(&keyring, pub) == RNP_SUCCESS) { - if (rnp_load_keys(new_pgp->context, RNP_KEYSTORE_GPG, - keyring, RNP_LOAD_SAVE_PUBLIC_KEYS) == RNP_SUCCESS) { - rnp_input_destroy(keyring); - } + err = gpgme_op_import(new_pgp->gpgme, keydata); + if (err) { + return; + } + + gpgme_import_result_t impRes = gpgme_op_import_result(new_pgp->gpgme); + weechat_printf(nullptr, "(gpg) imported %d keys", impRes->imported); + + err = gpgme_data_new_from_file(&keydata, sec, true); + if (err) { + return; } - if (rnp_input_from_path(&keyring, sec) == RNP_SUCCESS) { - if (rnp_load_keys(new_pgp->context, RNP_KEYSTORE_GPG, - keyring, RNP_LOAD_SAVE_SECRET_KEYS) == RNP_SUCCESS) { - rnp_input_destroy(keyring); - } + err = gpgme_op_import(new_pgp->gpgme, keydata); + if (err) { + return; } + impRes = gpgme_op_import_result(new_pgp->gpgme); + weechat_printf(nullptr, "(gpg) imported %d secret keys", impRes->imported); + *pgp = new_pgp; } @@ -54,335 +68,236 @@ void pgp__free(struct t_pgp *pgp) { if (pgp) { - if (pgp->context) - free(pgp->context); + if (pgp->gpgme) + gpgme_release(pgp->gpgme); free(pgp); } } char *pgp__encrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *target, const char *message) { - rnp_op_encrypt_t encrypt = NULL; - rnp_key_handle_t key = NULL; - rnp_input_t keyfile = NULL; - rnp_input_t input = NULL; - rnp_output_t output = NULL; + std::string encrypted; + gpgme_key_t keys[3] = {NULL,NULL,NULL}; char * result = NULL; - rnp_result_t ret; - - /* create memory input and file output objects for the message and encrypted message */ - if ((ret = rnp_input_from_memory(&input, (uint8_t *)message, strlen(message), false)) != - RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create input object: %s\n", weechat_prefix("error"), reason); - goto encrypt_finish; - } + int ret; + gpgme_error_t err; + gpgme_data_t in, out; - if ((ret = rnp_output_to_memory(&output, 0)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create output object: %s\n", weechat_prefix("error"), reason); + /* Initialize input buffer. */ + err = gpgme_data_new_from_mem(&in, message, strlen(message), false); + if (err) { goto encrypt_finish; } - /* create encryption operation */ - if ((ret = rnp_op_encrypt_create(&encrypt, pgp->context, input, output)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create encrypt operation: %s\n", weechat_prefix("error"), reason); + /* Initialize output buffer. */ + err = gpgme_data_new(&out); + if (err) { goto encrypt_finish; } - /* setup encryption parameters */ - rnp_op_encrypt_set_armor(encrypt, true); - rnp_op_encrypt_set_file_name(encrypt, "message.txt"); - rnp_op_encrypt_set_file_mtime(encrypt, time(NULL)); - rnp_op_encrypt_set_compression(encrypt, "ZIP", 6); - rnp_op_encrypt_set_cipher(encrypt, RNP_ALGNAME_AES_256); - rnp_op_encrypt_set_aead(encrypt, "None"); - - /* locate recipient's key and add it to the operation context. */ - if ((ret = rnp_locate_key(pgp->context, "keyid", target, &key)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to locate recipient key: %s\n", weechat_prefix("error"), reason); + /* Encrypt data. */ + err = gpgme_get_key(pgp->gpgme, target, &keys[0], false); + if (err) { goto encrypt_finish; } - - if ((ret = rnp_op_encrypt_add_recipient(encrypt, key)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to add recipient: %s\n", weechat_prefix("error"), reason); + err = gpgme_get_key(pgp->gpgme, source, &keys[1], false); + if (err) { goto encrypt_finish; } - rnp_key_handle_destroy(key); - key = NULL; - - /* locate carbon-copy key and add it to the operation context. */ - if ((ret = rnp_locate_key(pgp->context, "keyid", source, &key)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to locate recipient key: %s\n", weechat_prefix("error"), reason); + err = gpgme_op_encrypt(pgp->gpgme, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + if (err) { goto encrypt_finish; } - - if ((ret = rnp_op_encrypt_add_recipient(encrypt, key)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to add recipient: %s\n", weechat_prefix("error"), reason); - goto encrypt_finish; - } - rnp_key_handle_destroy(key); - key = NULL; - - /* execute encryption operation */ - if ((ret = rnp_op_encrypt_execute(encrypt)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: encryption failed: %s\n", weechat_prefix("error"), reason); + if (gpgme_encrypt_result_t enc_result = gpgme_op_encrypt_result(pgp->gpgme); + enc_result->invalid_recipients) + { goto encrypt_finish; + } + gpgme_data_seek(out, 0, SEEK_SET); + char data[512 + 1]; + while ((ret = gpgme_data_read(out, data, 512)) > 0) + { + encrypted += std::string_view(data, ret); } - uint8_t *buf; - size_t buf_len; + gpgme_data_release(in); + gpgme_data_release(out); - rnp_output_memory_get_buf(output, &buf, &buf_len, false); - result = strndup((char *)buf + strlen(PGP_MESSAGE_HEADER), - buf_len - strlen(PGP_MESSAGE_HEADER) - strlen(PGP_MESSAGE_FOOTER)); + result = strndup(encrypted.data() + strlen(PGP_MESSAGE_HEADER), + encrypted.size() - strlen(PGP_MESSAGE_HEADER) - strlen(PGP_MESSAGE_FOOTER)); encrypt_finish: - rnp_op_encrypt_destroy(encrypt); - rnp_input_destroy(keyfile); - rnp_input_destroy(input); - rnp_output_destroy(output); - rnp_key_handle_destroy(key); return result; } //"hQIMAzlgcSFDGLKEAQ//cGG3DFughC5xBF7xeXz1RdayOfhBAPfoZIq62MVuSnfS\nMfig65Zxz1LtAnnFq90TZY7hiHPBtVlYqg47AbSoYweMdpXsKgbUrd3NNf6k2nsZ\nUkChCtyGuHi8pTzclfle7gT0nNXJ1WcLCZ4ORZCrg3D5A+YTO9tdmE8GQsTT6TdV\nbbxF5yR4JF5SzFhuFL3ZoXPXrWylcwKXarYfoOTa6M2vSsCwApVIXQgJ/FI46sLT\nb0B/EVCjFvcvjkNr7+K7mQtth+x0a0pC4BtEhRvnIRAe/sdGp8NY+DP76clx4U+k\nIDG4H92F632pR6eEIoZttnBoaj0O4sTVAJCao5AoecR4w2FDqBWWtIyQp5vbo17/\nMtzungkk5vQP6Jhu36wa+JKpbHoxomVpHPZfAtIoyaY6pzQ0bUomIlSVpbZDvF68\nZKTlFd89Pm5x0JO5gsVYvf+N9Ed33d34n/0CFz5K5Tgu4Bk0v4LWEy3wtNsuQB4p\nkBSZJk7I2BakcRwP0zwld6rRHFIX1pb7zqThBPZGB9RkWPltiktUTibOII12tWhi\nksFpQJ8l1A8h9vM5kUXIeD6H2yP0CBUEIZF3Sf+jiSRZ/1/n3KoUrKEzkf/y4xgv\n1LA4pMjNLEr6J2fqGyYRFv4Bxv3PIvF17V5CwOtguxGRJHJXdIzm1BSHSqXxHezS\nYAFXMUb9fw3QX7Ed23KiyZjzd/LRsQBqMs9RsYyZB2PqF9x84lQYYbE8lErrryvK\nUEtmJKPw3Hvb7kgGox5vl5+KCg9q64EU9TgQpufYNShKtDz7Fsvc+ncgZoshDUeo\npw==\n=euIB" char *pgp__decrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *ciphertext) { - rnp_input_t input = NULL; - rnp_output_t output = NULL; + std::string decrypted; uint8_t * buf = NULL; size_t buf_len = 0; char * result = NULL; - rnp_result_t ret; + int ret; buf_len = strlen(PGP_MESSAGE_HEADER) + strlen(ciphertext) + strlen(PGP_MESSAGE_FOOTER) + 1; buf = (uint8_t*)malloc(sizeof(char) * buf_len); buf_len = snprintf((char *)buf, buf_len, PGP_MESSAGE_HEADER "%s" PGP_MESSAGE_FOOTER, ciphertext); - /* create file input and memory output objects for the encrypted message and decrypted - * message */ - if ((ret = rnp_input_from_memory(&input, buf, buf_len, false)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create input object: %s\n", weechat_prefix("error"), reason); + gpgme_error_t err; + gpgme_data_t in, out; + + /* Initialize input buffer. */ + err = gpgme_data_new_from_mem(&in, (char *)buf, buf_len, false); + if (err) { goto decrypt_finish; } - if ((ret = rnp_output_to_memory(&output, 0)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create output object: %s\n", weechat_prefix("error"), reason); + /* Initialize output buffer. */ + err = gpgme_data_new(&out); + if (err) { goto decrypt_finish; } - if ((ret = rnp_decrypt(pgp->context, input, output)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: public-key decryption failed: %s\n", weechat_prefix("error"), reason); + /* Decrypt data. */ + err = gpgme_op_decrypt(pgp->gpgme, in, out); + if (err) { goto decrypt_finish; } - free(buf); - - /* get the decrypted message from the output structure */ - if (rnp_output_memory_get_buf(output, &buf, &buf_len, false) != RNP_SUCCESS) { + if (gpgme_decrypt_result_t dec_result = gpgme_op_decrypt_result(pgp->gpgme); + dec_result->unsupported_algorithm) + { goto decrypt_finish; + } + gpgme_data_seek(out, 0, SEEK_SET); + char data[512 + 1]; + while ((ret = gpgme_data_read(out, data, 512)) > 0) + { + decrypted += std::string_view(data, ret); } - result = strndup((const char *)buf, (int)buf_len); + gpgme_data_release(in); + gpgme_data_release(out); + + result = strndup(decrypted.data(), decrypted.size()); decrypt_finish: - rnp_input_destroy(input); - rnp_output_destroy(output); return result; } char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *certificate) { - rnp_op_verify_t verify = NULL; - rnp_input_t input = NULL; - rnp_input_t signature = NULL; uint8_t * buf = NULL; size_t buf_len = 0; size_t sigcount = 0; char * result = NULL; - rnp_result_t ret; + int ret; buf_len = strlen(PGP_SIGNATURE_HEADER) + strlen(certificate) + strlen(PGP_SIGNATURE_FOOTER) + 1; buf = (uint8_t*)malloc(sizeof(char) * buf_len); buf_len = snprintf((char *)buf, buf_len, PGP_SIGNATURE_HEADER "%s" PGP_SIGNATURE_FOOTER, certificate); - /* create file input memory objects for the signed message and verified message */ - if ((ret = rnp_input_from_memory(&input, buf, buf_len, false)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create input object: %s\n", weechat_prefix("error"), reason); - goto verify_finish; - } + gpgme_verify_result_t vrf_result; + gpgme_error_t err; + gpgme_data_t in, out; - if ((ret = rnp_input_from_memory(&signature, buf, buf_len, false)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create input object: %s\n", weechat_prefix("error"), reason); + /* Initialize input buffer. */ + err = gpgme_data_new_from_mem(&in, (char *)buf, buf_len, false); + if (err) { goto verify_finish; } - if ((ret = rnp_op_verify_detached_create(&verify, pgp->context, input, signature)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to create verification context: %s\n", weechat_prefix("error"), reason); + /* Initialize output buffer. */ + err = gpgme_data_new(&out); + if (err) { goto verify_finish; } - //if (( - ret = rnp_op_verify_execute(verify) - ; - // ) != RNP_ERROR_SIGNATURE_INVALID) - // if (ret != RNP_ERROR_SIGNATURE_INVALID) { - // const char *reason = rnp_result_to_string(ret); - // weechat_printf(buffer, "%spgp: failed to execute verification operation: %s\n", weechat_prefix("error"), reason); - // goto verify_finish; - // } - - /* now check signatures and get some info about them */ - if ((ret = rnp_op_verify_get_signature_count(verify, &sigcount)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to get signature count: %s\n", weechat_prefix("error"), reason); + /* Verify data. */ + err = gpgme_op_verify(pgp->gpgme, in, out, nullptr); + if (err) { goto verify_finish; } + if (vrf_result = gpgme_op_verify_result(pgp->gpgme); + !(vrf_result->signatures->summary & GPGME_SIGSUM_VALID)) + { + goto verify_finish; + } - for (size_t i = 0; i < sigcount; i++) { - rnp_op_verify_signature_t sig = NULL; - rnp_key_handle_t key = NULL; - rnp_signature_handle_t signature = NULL; - char * keyid = NULL; - - if ((ret = rnp_op_verify_get_signature_at(verify, i, &sig)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to get signature %d: %s\n", weechat_prefix("error"), (int)i, reason); - goto verify_finish; - } - - if ((ret = rnp_op_verify_signature_get_key(sig, &key)) == RNP_SUCCESS) { - if ((ret = rnp_key_get_keyid(key, &keyid)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to get key id %d: %s\n", weechat_prefix("error"), (int)i, reason); - rnp_key_handle_destroy(key); - goto verify_finish; - } - - if ((ret = rnp_key_get_signature_at(key, 0, &signature)) == RNP_SUCCESS) { - if ((ret = rnp_signature_get_keyid(signature, &keyid)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to get key id: %s\n", weechat_prefix("error"), reason); - rnp_key_handle_destroy(key); - goto verify_finish; - } - rnp_signature_handle_destroy(signature); - } - } else { - if ((ret = rnp_op_verify_signature_get_handle(sig, &signature)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to get signature's %d handle: %s\n", weechat_prefix("error"), (int)i, reason); - goto verify_finish; - } - - if ((ret = rnp_signature_get_keyid(signature, &keyid)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(buffer, "%spgp: failed to get key id: %s\n", weechat_prefix("error"), reason); - rnp_key_handle_destroy(key); - goto verify_finish; - } - } - - result = strdup(keyid); - rnp_buffer_destroy(keyid); - rnp_key_handle_destroy(key); - break; - } + result = strdup(vrf_result->signatures->fpr); verify_finish: - rnp_op_verify_destroy(verify); - rnp_input_destroy(input); - rnp_input_destroy(signature); return result; } char *pgp__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *message) { - rnp_input_t keyfile = NULL; - rnp_input_t input = NULL; - rnp_output_t output = NULL; - rnp_op_sign_t sign = NULL; - rnp_key_handle_t key = NULL; + std::string signature; uint8_t * buf = NULL; size_t buf_len = 0; char * result = NULL; + int ret; - /* create file input and memory output objects for the encrypted message and decrypted - * message */ - if (rnp_input_from_memory(&input, (uint8_t *)message, strlen(message), false) != - RNP_SUCCESS) { - weechat_printf(buffer, "%spgp: failed to create input object\n", weechat_prefix("error")); - goto sign_finish; - } + gpgme_error_t err; + gpgme_data_t in, out; + gpgme_key_t key; - if (rnp_output_to_memory(&output, 0) != RNP_SUCCESS) { - weechat_printf(buffer, "%spgp: failed to create output object\n", weechat_prefix("error")); + /* Initialize input buffer. */ + err = gpgme_data_new_from_mem(&in, (char *)message, strlen(message), false); + if (err) { goto sign_finish; } - /* initialize and configure sign operation */ - if (rnp_op_sign_detached_create(&sign, pgp->context, input, output) != RNP_SUCCESS) { - weechat_printf(buffer, "%spgp: failed to create sign operation\n", weechat_prefix("error")); + /* Initialize output buffer. */ + err = gpgme_data_new(&out); + if (err) { goto sign_finish; } - /* armor, file name, compression */ - rnp_op_sign_set_armor(sign, true); - rnp_op_sign_set_file_name(sign, "message.txt"); - rnp_op_sign_set_file_mtime(sign, time(NULL)); - rnp_op_sign_set_compression(sign, "ZIP", 6); - /* signatures creation time - by default will be set to the current time as well */ - rnp_op_sign_set_creation_time(sign, time(NULL)); - /* signatures expiration time - by default will be 0, i.e. never expire */ - rnp_op_sign_set_expiration_time(sign, 365 * 24 * 60 * 60); - /* set hash algorithm - should be compatible for all signatures */ - rnp_op_sign_set_hash(sign, RNP_ALGNAME_SHA256); - - /* now add signatures. First locate the signing key, then add and setup signature */ - if (rnp_locate_key(pgp->context, "keyid", source, &key) != RNP_SUCCESS) { - weechat_printf(buffer, "%spgp: failed to locate signing key: %s\n", weechat_prefix("error"), source); + /* Include signature within key. */ + { + gpgme_keylist_mode_t kmode = gpgme_get_keylist_mode(pgp->gpgme); + kmode |= GPGME_KEYLIST_MODE_SIGS; + err = gpgme_set_keylist_mode(pgp->gpgme, kmode); + } + if (err) { goto sign_finish; } - if (rnp_op_sign_add_signature(sign, key, NULL) != RNP_SUCCESS) { - weechat_printf(buffer, "%spgp: failed to add signature for key: %s\n", weechat_prefix("error"), source); + err = gpgme_get_key(pgp->gpgme, source, &key, false); + if (err) { + weechat_printf(nullptr, "(gpg) get key fail for %s", source); goto sign_finish; } - - rnp_key_handle_destroy(key); - key = NULL; - - /* finally do signing */ - if (rnp_op_sign_execute(sign) != RNP_SUCCESS) { - weechat_printf(buffer, "%spgp: failed to sign with key: %s\n", weechat_prefix("error"), source); + err = gpgme_signers_add(pgp->gpgme, key); + if (err) { + weechat_printf(nullptr, "(gpg) add key fail for %s", source); goto sign_finish; } - /* get the signature from the output structure */ - if (rnp_output_memory_get_buf(output, &buf, &buf_len, false) != RNP_SUCCESS) { + /* Sign data. */ + err = gpgme_op_sign(pgp->gpgme, in, out, GPGME_SIG_MODE_DETACH); + if (err) { + weechat_printf(nullptr, "(gpg) sign fail for %s", source); goto sign_finish; } + if (gpgme_sign_result_t sgn_result = gpgme_op_sign_result(pgp->gpgme); + !sgn_result->signatures) + { + weechat_printf(nullptr, "(gpg) signature fail for %s", source); + } + gpgme_data_seek(out, 0, SEEK_SET); + char data[512 + 1]; + while ((ret = gpgme_data_read(out, data, 512)) > 0) + { + signature += std::string_view(data, ret); + } + + gpgme_data_release(in); + gpgme_data_release(out); - result = strndup((char *)buf + strlen(PGP_SIGNATURE_HEADER), - buf_len - strlen(PGP_SIGNATURE_HEADER) - strlen(PGP_SIGNATURE_FOOTER)); + result = strndup(signature.data() + strlen(PGP_SIGNATURE_HEADER), + signature.size() - strlen(PGP_SIGNATURE_HEADER) - strlen(PGP_SIGNATURE_FOOTER)); sign_finish: - rnp_input_destroy(keyfile); - rnp_key_handle_destroy(key); - rnp_op_sign_destroy(sign); - rnp_input_destroy(input); - rnp_output_destroy(output); return result; } diff --git a/pgp.hh b/pgp.hh index fa86414..1a40706 100644 --- a/pgp.hh +++ b/pgp.hh @@ -4,11 +4,13 @@ #pragma once +#include + extern const char *PGP_ADVICE; struct t_pgp { - struct rnp_ffi_st *context; + struct gpgme_context *gpgme; const char *keyid; };