# HG changeset patch # User Mikael Berthe # Date 1443978244 -7200 # Node ID e3b66c8ead4f1195886291b4c6e7e5d3382fb350 # Parent a852aed87ac0bcc09591fb7f8030a86f593eaa23 PGP: Change gpg_encrypt() so that several encryption keys can be used diff -r a852aed87ac0 -r e3b66c8ead4f mcabber/mcabber/api.h --- a/mcabber/mcabber/api.h Thu Oct 01 23:03:06 2015 +0200 +++ b/mcabber/mcabber/api.h Sun Oct 04 19:04:04 2015 +0200 @@ -4,8 +4,8 @@ #include #include // For MCABBER_BRANCH -#define MCABBER_API_VERSION 35 -#define MCABBER_API_MIN 35 +#define MCABBER_API_VERSION 36 +#define MCABBER_API_MIN 36 #define MCABBER_BRANCH_DEV 1 diff -r a852aed87ac0 -r e3b66c8ead4f mcabber/mcabber/pgp.c --- a/mcabber/mcabber/pgp.c Thu Oct 01 23:03:06 2015 +0200 +++ b/mcabber/mcabber/pgp.c Sun Oct 04 19:04:04 2015 +0200 @@ -1,7 +1,7 @@ /* * pgp.c -- PGP utility functions * - * Copyright (C) 2006-2009 Mikael Berthe + * Copyright (C) 2006-2015 Mikael Berthe * Some parts inspired by centericq (impgp.cc) * * This program is free software; you can redistribute it and/or modify @@ -381,21 +381,26 @@ return decrypted_data; } -// gpg_encrypt(gpg_data, keyid) -// Return encrypted gpg_data with the key keyid (or NULL). +// gpg_encrypt(gpg_data, keyids[], n) +// Return encrypted gpg_data with the n keys from the keyids array (or NULL). // The returned string must be freed with g_free() after use. -char *gpg_encrypt(const char *gpg_data, const char *keyid) +char *gpg_encrypt(const char *gpg_data, const char *keyids[], size_t nkeys) { gpgme_ctx_t ctx; gpgme_data_t in, out; char *encrypted_data = NULL, *edata; size_t nread; - gpgme_key_t key; + gpgme_key_t *keys; gpgme_error_t err; + unsigned i; if (!gpg.enabled) return NULL; + if (!keyids || !nkeys) { + return NULL; + } + err = gpgme_new(&ctx); if (err) { scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, @@ -407,9 +412,21 @@ gpgme_set_textmode(ctx, 0); gpgme_set_armor(ctx, 1); - err = gpgme_get_key(ctx, keyid, &key, 0); - if (!err && key) { - gpgme_key_t keys[] = { key, 0 }; + keys = g_new0(gpgme_key_t, 1+nkeys); + + for (i = 0; i < nkeys; i++) { + err = gpgme_get_key(ctx, keyids[i], &keys[i], 0); + if (err || !keys[i]) { + scr_LogPrint(LPRINT_LOGNORM, "GPGME encryption error: cannot use key %s", + keyids[i]); + // We need to have err not null to ensure we won't try to encrypt + // without this key. + if (!err) err = GPG_ERR_UNKNOWN_ERRNO; + break; + } + } + + if (!err) { err = gpgme_data_new_from_mem(&in, gpg_data, strlen(gpg_data), 0); if (!err) { err = gpgme_data_new(&out); @@ -422,14 +439,16 @@ } gpgme_data_release(in); } - gpgme_key_release(key); - } else { - scr_LogPrint(LPRINT_LOGNORM, "GPGME encryption error: key not found"); - err = 0; + + if (err && err != GPG_ERR_CANCELED) { + scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, + "GPGME encryption error: %s", gpgme_strerror(err)); + } } - if (err && err != GPG_ERR_CANCELED) - scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, - "GPGME encryption error: %s", gpgme_strerror(err)); + + for (i = 0; keys[i]; i++) + gpgme_key_release(keys[i]); + g_free(keys); gpgme_release(ctx); edata = strip_header_footer(encrypted_data); if (encrypted_data) diff -r a852aed87ac0 -r e3b66c8ead4f mcabber/mcabber/pgp.h --- a/mcabber/mcabber/pgp.h Thu Oct 01 23:03:06 2015 +0200 +++ b/mcabber/mcabber/pgp.h Sun Oct 04 19:04:04 2015 +0200 @@ -16,7 +16,7 @@ gpgme_sigsum_t *sigsum); char *gpg_sign(const char *gpg_data); char *gpg_decrypt(const char *gpg_data); -char *gpg_encrypt(const char *gpg_data, const char *keyid); +char *gpg_encrypt(const char *gpg_data, const char *keyid[], size_t n); int gpg_test_passphrase(void); diff -r a852aed87ac0 -r e3b66c8ead4f mcabber/mcabber/xmpp.c --- a/mcabber/mcabber/xmpp.c Thu Oct 01 23:03:06 2015 +0200 +++ b/mcabber/mcabber/xmpp.c Sun Oct 04 19:04:04 2015 +0200 @@ -382,8 +382,10 @@ key = settings_pgp_getkeyid(barejid); if (!key && res_pgpdata) key = res_pgpdata->sign_keyid; - if (key) - enc = gpg_encrypt(text, key); + if (key) { + const char *keys[] = { key }; + enc = gpg_encrypt(text, keys, 1); + } if (!enc && force) { if (encrypted) *encrypted = -1;