aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2009-08-06 17:17:18 +0000
committerWerner Koch <[email protected]>2009-08-06 17:17:18 +0000
commit0fcf3ee915a1c90bd7471ec371924a1ff7a5fcdd (patch)
treebb3ff05956cb91ba2dae86d75b3ac900fe3dc488 /src
parentAdd issing file. (diff)
downloadgpgme-0fcf3ee915a1c90bd7471ec371924a1ff7a5fcdd.tar.gz
gpgme-0fcf3ee915a1c90bd7471ec371924a1ff7a5fcdd.zip
Fix detection of invalid signer keys.
Support the new INV_SGNR status code.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog13
-rw-r--r--src/engine-gpgsm.c5
-rw-r--r--src/gpgme.h.in4
-rw-r--r--src/op-support.c8
-rw-r--r--src/sign.c27
5 files changed, 47 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index feebbdc9..33019498 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+2009-08-06 Werner Koch <[email protected]>
+
+ * op-support.c (_gpgme_parse_inv_recp): Allow for no fingerprint.
+
+ * engine-gpgsm.c (gpgsm_sign): Hook up the status func for the
+ SIGNER command.
+ * gpgme.h.in (GPGME_STATUS_INV_SGNR, GPGME_STATUS_NO_SGNR): New.
+ * sign.c (op_data_t): Add fields IGNORE_INV_RECP and INV_SGNR_SEEN.
+ (_gpgme_op_sign_init_result): Factor code out to ...
+ (sign_init_result): .. new. Init new fields.
+ (sign_start): Use sign_init_result.
+ (_gpgme_sign_status_handler): Take care of the new INV_SGNR.
+
2009-07-07 Werner Koch <[email protected]>
* engine-gpgsm.c (struct engine_gpgsm): Add fields
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 4067b99b..647fd931 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1870,7 +1870,7 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0)
return gpg_error_from_errno (errno);
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, assuan_cmd,
- NULL, NULL);
+ NULL, NULL);
free (assuan_cmd);
if (err)
return err;
@@ -1885,7 +1885,8 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
strcpy (stpcpy (buf, "SIGNER "), s);
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, buf,
- NULL, NULL);
+ gpgsm->status.fnc,
+ gpgsm->status.fnc_value);
}
else
err = gpg_error (GPG_ERR_INV_VALUE);
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index b9f76f56..0b42798c 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -485,7 +485,9 @@ typedef enum
GPGME_STATUS_PKA_TRUST_BAD = 79,
GPGME_STATUS_PKA_TRUST_GOOD = 80,
- GPGME_STATUS_PLAINTEXT = 81
+ GPGME_STATUS_PLAINTEXT = 81,
+ GPGME_STATUS_INV_SGNR = 82,
+ GPGME_STATUS_NO_SGNR = 83
}
gpgme_status_code_t;
diff --git a/src/op-support.c b/src/op-support.c
index c3ba7785..90e1283e 100644
--- a/src/op-support.c
+++ b/src/op-support.c
@@ -162,8 +162,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
}
-/* Parse the INV_RECP status line in ARGS and return the result in
- KEY. */
+/* Parse the INV_RECP or INV-SNDR status line in ARGS and return the
+ result in KEY. */
gpgme_error_t
_gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
{
@@ -177,7 +177,7 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
inv_key->next = NULL;
errno = 0;
reason = strtol (args, &tail, 0);
- if (errno || args == tail || *tail != ' ')
+ if (errno || args == tail || (*tail && *tail != ' '))
{
/* The crypto backend does not behave. */
free (inv_key);
@@ -236,7 +236,7 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
break;
}
- while (*tail == ' ')
+ while (*tail && *tail == ' ')
tail++;
if (*tail)
{
diff --git a/src/sign.c b/src/sign.c
index 03007bdf..1d3716fd 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -46,6 +46,10 @@ typedef struct
/* Likewise for signature information. */
gpgme_new_signature_t *last_sig_p;
+
+ /* Flags used while processing the status lines. */
+ unsigned int ignore_inv_recp:1;
+ unsigned int inv_sgnr_seen:1;
} *op_data_t;
@@ -266,6 +270,12 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
break;
case GPGME_STATUS_INV_RECP:
+ if (opd->inv_sgnr_seen && opd->ignore_inv_recp)
+ break;
+ /* FALLTROUGH */
+ case GPGME_STATUS_INV_SGNR:
+ if (code == GPGME_STATUS_INV_SGNR)
+ opd->inv_sgnr_seen = 1;
err = _gpgme_parse_inv_recp (args, opd->last_signer_p);
if (err)
return err;
@@ -297,8 +307,8 @@ sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
}
-gpgme_error_t
-_gpgme_op_sign_init_result (gpgme_ctx_t ctx)
+static gpgme_error_t
+sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp)
{
gpgme_error_t err;
void *hook;
@@ -311,9 +321,17 @@ _gpgme_op_sign_init_result (gpgme_ctx_t ctx)
return err;
opd->last_signer_p = &opd->result.invalid_signers;
opd->last_sig_p = &opd->result.signatures;
+ opd->ignore_inv_recp = !!ignore_inv_recp;
+ opd->inv_sgnr_seen = 0;
return 0;
}
+gpgme_error_t
+_gpgme_op_sign_init_result (gpgme_ctx_t ctx)
+{
+ return sign_init_result (ctx, 0);
+}
+
static gpgme_error_t
sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
@@ -325,7 +343,10 @@ sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
if (err)
return err;
- err = _gpgme_op_sign_init_result (ctx);
+ /* If we are using the CMS protocol, we ignore the INV_RECP status
+ code if a newer GPGSM is in use. GPGMS does not support combined
+ sign+encrypt and thus this can't harm. */
+ err = sign_init_result (ctx, (ctx->protocol == GPGME_PROTOCOL_CMS));
if (err)
return err;