Fix returning new signatures when there are none.

* 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.
This commit is contained in:
Ben Kibbey 2014-11-09 16:42:54 -05:00 committed by Werner Koch
parent a9ae0d1428
commit 5942b0c7e0

View File

@ -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,48 @@ gpgme_op_sign_result (gpgme_ctx_t ctx)
sig = sig->next;
}
if (gpgme_signers_count (ctx)
&& 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;