changeset 2187:e3b66c8ead4f

PGP: Change gpg_encrypt() so that several encryption keys can be used
author Mikael Berthe <mikael@lilotux.net>
date Sun, 04 Oct 2015 19:04:04 +0200
parents a852aed87ac0
children 84252c616919
files mcabber/mcabber/api.h mcabber/mcabber/pgp.c mcabber/mcabber/pgp.h mcabber/mcabber/xmpp.c
diffstat 4 files changed, 41 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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 <glib.h>
 #include <mcabber/config.h> // 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
 
--- 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 <mikael@lilotux.net>
+ * Copyright (C) 2006-2015 Mikael Berthe <mikael@lilotux.net>
  * 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)
--- 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);
 
--- 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;