gpgme: No error code with missing secret key for GPGME_ENCRYPT_CHG_RECP
Open, HighPublic

Assigned To
None
Authored By
tfry
Wed, Jun 3, 10:53 AM
Subscribers

Description

Using gpgme_op_encrypt() with GPGME_ENCRYPT_CHG_RECP or GPGME_ENCRYPT_ADD_RECP, no error code is returned, in case no suitable secret key is available.

This diff demonstrates the problem based on tests/gpg/t-encrypt (to be split into a separate testcase, but the diff is smaller like this):

diff --git a/tests/gpg/t-encrypt.c b/tests/gpg/t-encrypt.c
index 76d9e397..69610335 100644
--- a/tests/gpg/t-encrypt.c
+++ b/tests/gpg/t-encrypt.c
@@ -76,10 +76,43 @@ main (int argc, char *argv[])
     }
   print_data (out);
 
+  // Reencrypt, swapping out the first key for a different one
+  gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
+  gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
+  gpgme_key_unref (key[0]);
+  err = gpgme_get_key (ctx, "61EE841A2A27EB983B3B3C26413F4AF31AFDAB6C",
+                       &key[0], 0);
+  fail_if_err (err);
+  gpgme_data_t out2;
+  err = gpgme_data_new (&out2);
+  fail_if_err (err);
+  gpgme_data_seek (out, 0, SEEK_SET);
+  err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST | GPGME_ENCRYPT_CHG_RECP, out, out2);
+  fail_if_err (err);
+  fprintf (stderr, "\nReencrypted:\n");
+  print_data (out2);
+
+  // Try to reencrypt once more. We no longer have a secret key, so this should fail:
+  gpgme_key_unref (key[0]);
+  err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2",
+                       &key[0], 0);
+  gpgme_data_t out3;
+  err = gpgme_data_new (&out3);
+  fail_if_err (err);
+  gpgme_data_seek (out2, 0, SEEK_SET);
+  err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST | GPGME_ENCRYPT_CHG_RECP, out2, out3);
+  if (!err) {
+    fprintf (stderr, "\nThis should have failed but did not. (Empty) result data below:\n");
+    print_data (out3);
+    exit (1);
+  }
+
   gpgme_key_unref (key[0]);
   gpgme_key_unref (key[1]);
   gpgme_data_release (in);
   gpgme_data_release (out);
+  gpgme_data_release (out2);
+  gpgme_data_release (out3);
   gpgme_release (ctx);
   return 0;
 }