[PATCH] Fix returning new signatures when there are none.

Ben Kibbey bjk at luxsci.net
Sun Nov 9 23:10:25 CET 2014


* src/sign.c (gpgme_op_sign_result): Test that invalid and valid
signatures add up to gpgme_signers_count().
--

When invalid and valid signatures do not equal gpgme_signers_count() it
means that there was a bad passphrase during signing after the first
signer. This leaves the result.signatures from previous signers intact
which isn't correct since gpg will report:

gpg: number of one-pass packets does not match number of signature
packets
gpg: can't handle this ambiguous signature data

during verify. So when this happens append the valid signatures to the
.invalid_signers list with .reason set to GPG_ERR_GENERAL.
---
 src/sign.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 53 insertions(+), 8 deletions(-)

diff --git a/src/sign.c b/src/sign.c
index c55441d..9ad589d 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -54,12 +54,22 @@ typedef struct
 } *op_data_t;
 
 
+static void release_signatures (gpgme_new_signature_t sig)
+{
+  while (sig)
+    {
+      gpgme_new_signature_t next = sig->next;
+      free (sig->fpr);
+      free (sig);
+      sig = next;
+    }
+}
+
 static void
 release_op_data (void *hook)
 {
   op_data_t opd = (op_data_t) hook;
   gpgme_invalid_key_t invalid_signer = opd->result.invalid_signers;
-  gpgme_new_signature_t sig = opd->result.signatures;
 
   while (invalid_signer)
     {
@@ -70,13 +80,7 @@ release_op_data (void *hook)
       invalid_signer = next;
     }
 
-  while (sig)
-    {
-      gpgme_new_signature_t next = sig->next;
-      free (sig->fpr);
-      free (sig);
-      sig = next;
-    }
+  release_signatures (opd->result.signatures);
 }
 
 
@@ -115,6 +119,47 @@ gpgme_op_sign_result (gpgme_ctx_t ctx)
 	  sig = sig->next;
 	}
 
+      if (signatures + inv_signers != gpgme_signers_count (ctx))
+        {
+          TRACE_LOG3 ("result: invalid signers: %i, signatures: %i, count: %i",
+                      inv_signers, signatures, gpgme_signers_count (ctx));
+
+          sig = opd->result.signatures;
+          while (sig)
+            {
+              gpgme_invalid_key_t key;
+
+              key = malloc (sizeof (*key));
+              key->fpr = strdup (sig->fpr);
+              key->reason = GPG_ERR_GENERAL;
+              key->next = NULL;
+
+              inv_key = opd->result.invalid_signers;
+              if (!inv_key)
+                {
+                  opd->result.invalid_signers = inv_key = key;
+                  sig = sig->next;
+                  continue;
+                }
+
+              while (inv_key)
+                {
+                  if (!inv_key->next)
+                    {
+                      inv_key->next = key;
+                      break;
+                    }
+
+                  inv_key = inv_key->next;
+                }
+
+              sig = sig->next;
+            }
+
+          release_signatures (opd->result.signatures);
+          opd->result.signatures = NULL;
+        }
+
       TRACE_LOG2 ("result: invalid signers: %i, signatures: %i",
 		  inv_signers, signatures);
       inv_key = opd->result.invalid_signers;
-- 
2.1.1




More information about the Gnupg-devel mailing list