Return dedicated error code for all subkeys expired or revoked.
* src/gpgme.h.in (GPGME_STATUS_KEY_CONSIDERED): New. (GPGME_SIGSUM_TOFU_CONFLICT): New. * src/status-table.c (KEY_CONSIDERED): New. * src/op-support.c (_gpgme_parse_inv_recp): Add argc KC_FPR and KC_FLAGS. Use calloc. Detect all expired or revoked subkeys. (_gpgme_parse_key_considered): New. * src/sign.c (op_data_t): Add fields KC_FPR and KC_FLAGS. (release_op_data): Free KC_FPR. (_gpgme_sign_status_handler): Handle STATUS_KEY_CONSIDERED. * src/encrypt.c (op_data_t): Add fields KC_FPR and KC_FLAGS. (release_op_data): Free KC_FPR. (_gpgme_encrypt_status_handler): Handle STATUS_KEY_CONSIDERED. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
9b36ebf37a
commit
315fb73d4a
@ -39,6 +39,12 @@ typedef struct
|
|||||||
/* The error code from a FAILURE status line or 0. */
|
/* The error code from a FAILURE status line or 0. */
|
||||||
gpg_error_t failure_code;
|
gpg_error_t failure_code;
|
||||||
|
|
||||||
|
/* The fingerprint from the last KEY_CONSIDERED status line. */
|
||||||
|
char *kc_fpr;
|
||||||
|
|
||||||
|
/* The flags from the last KEY_CONSIDERED status line. */
|
||||||
|
unsigned int kc_flags;
|
||||||
|
|
||||||
/* A pointer to the next pointer of the last invalid recipient in
|
/* A pointer to the next pointer of the last invalid recipient in
|
||||||
the list. This makes appending new invalid recipients painless
|
the list. This makes appending new invalid recipients painless
|
||||||
while preserving the order. */
|
while preserving the order. */
|
||||||
@ -60,6 +66,8 @@ release_op_data (void *hook)
|
|||||||
free (invalid_recipient);
|
free (invalid_recipient);
|
||||||
invalid_recipient = next;
|
invalid_recipient = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free (opd->kc_fpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -128,12 +136,26 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
|
|||||||
return opd->failure_code;
|
return opd->failure_code;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_INV_RECP:
|
case GPGME_STATUS_KEY_CONSIDERED:
|
||||||
err = _gpgme_parse_inv_recp (args, opd->lastp);
|
/* This is emitted during gpg's key lookup to give information
|
||||||
|
* about the lookup results. We store the last one so it can be
|
||||||
|
* used in connection with INV_RECP. */
|
||||||
|
free (opd->kc_fpr);
|
||||||
|
opd->kc_fpr = NULL;
|
||||||
|
err = _gpgme_parse_key_considered (args, &opd->kc_fpr, &opd->kc_flags);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_INV_RECP:
|
||||||
|
err = _gpgme_parse_inv_recp (args, 0, opd->kc_fpr, opd->kc_flags,
|
||||||
|
opd->lastp);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
opd->lastp = &(*opd->lastp)->next;
|
opd->lastp = &(*opd->lastp)->next;
|
||||||
|
free (opd->kc_fpr);
|
||||||
|
opd->kc_fpr = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_NO_RECP:
|
case GPGME_STATUS_NO_RECP:
|
||||||
|
@ -532,7 +532,8 @@ typedef enum
|
|||||||
GPGME_STATUS_BEGIN_SIGNING = 90,
|
GPGME_STATUS_BEGIN_SIGNING = 90,
|
||||||
GPGME_STATUS_KEY_NOT_CREATED = 91,
|
GPGME_STATUS_KEY_NOT_CREATED = 91,
|
||||||
GPGME_STATUS_INQUIRE_MAXLEN = 92,
|
GPGME_STATUS_INQUIRE_MAXLEN = 92,
|
||||||
GPGME_STATUS_FAILURE = 93
|
GPGME_STATUS_FAILURE = 93,
|
||||||
|
GPGME_STATUS_KEY_CONSIDERED = 94
|
||||||
}
|
}
|
||||||
gpgme_status_code_t;
|
gpgme_status_code_t;
|
||||||
|
|
||||||
@ -861,7 +862,12 @@ typedef struct _gpgme_key *gpgme_key_t;
|
|||||||
struct _gpgme_invalid_key
|
struct _gpgme_invalid_key
|
||||||
{
|
{
|
||||||
struct _gpgme_invalid_key *next;
|
struct _gpgme_invalid_key *next;
|
||||||
|
|
||||||
|
/* The string used to request the key. Despite the name this may
|
||||||
|
* not be a fingerprint. */
|
||||||
char *fpr;
|
char *fpr;
|
||||||
|
|
||||||
|
/* The error code. */
|
||||||
gpgme_error_t reason;
|
gpgme_error_t reason;
|
||||||
};
|
};
|
||||||
typedef struct _gpgme_invalid_key *gpgme_invalid_key_t;
|
typedef struct _gpgme_invalid_key *gpgme_invalid_key_t;
|
||||||
@ -1518,7 +1524,8 @@ typedef enum
|
|||||||
GPGME_SIGSUM_CRL_MISSING = 0x0100, /* CRL not available. */
|
GPGME_SIGSUM_CRL_MISSING = 0x0100, /* CRL not available. */
|
||||||
GPGME_SIGSUM_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
|
GPGME_SIGSUM_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
|
||||||
GPGME_SIGSUM_BAD_POLICY = 0x0400, /* A policy was not met. */
|
GPGME_SIGSUM_BAD_POLICY = 0x0400, /* A policy was not met. */
|
||||||
GPGME_SIGSUM_SYS_ERROR = 0x0800 /* A system error occurred. */
|
GPGME_SIGSUM_SYS_ERROR = 0x0800, /* A system error occurred. */
|
||||||
|
GPGME_SIGSUM_TOFU_CONFLICT=0x1000 /* Tofu conflict detected. */
|
||||||
}
|
}
|
||||||
gpgme_sigsum_t;
|
gpgme_sigsum_t;
|
||||||
|
|
||||||
@ -1541,7 +1548,7 @@ struct _gpgme_signature
|
|||||||
/* Signature creation time. */
|
/* Signature creation time. */
|
||||||
unsigned long timestamp;
|
unsigned long timestamp;
|
||||||
|
|
||||||
/* Signature exipration time or 0. */
|
/* Signature expiration time or 0. */
|
||||||
unsigned long exp_timestamp;
|
unsigned long exp_timestamp;
|
||||||
|
|
||||||
/* Key should not have been used for signing. */
|
/* Key should not have been used for signing. */
|
||||||
|
@ -33,6 +33,11 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
#if GPG_ERROR_VERSION_NUMBER < 0x011700 /* 1.23 */
|
||||||
|
# define GPG_ERR_SUBKEYS_EXP_REV 217
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
_gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
|
_gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
|
||||||
@ -190,16 +195,19 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse the INV_RECP or INV-SNDR status line in ARGS and return the
|
/* Parse the INV_RECP or INV_SNDR status line in ARGS and return the
|
||||||
result in KEY. */
|
result in KEY. If KC_FPR (from the KEY_CONSIDERED status line) is
|
||||||
|
not NULL take the KC_FLAGS in account. */
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
_gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
|
_gpgme_parse_inv_recp (char *args, int for_signing,
|
||||||
|
const char *kc_fpr, unsigned int kc_flags,
|
||||||
|
gpgme_invalid_key_t *key)
|
||||||
{
|
{
|
||||||
gpgme_invalid_key_t inv_key;
|
gpgme_invalid_key_t inv_key;
|
||||||
char *tail;
|
char *tail;
|
||||||
long int reason;
|
long int reason;
|
||||||
|
|
||||||
inv_key = malloc (sizeof (*inv_key));
|
inv_key = calloc (1, sizeof (*inv_key));
|
||||||
if (!inv_key)
|
if (!inv_key)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
inv_key->next = NULL;
|
inv_key->next = NULL;
|
||||||
@ -214,9 +222,11 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
|
|||||||
|
|
||||||
switch (reason)
|
switch (reason)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
case 0:
|
case 0:
|
||||||
inv_key->reason = gpg_error (GPG_ERR_GENERAL);
|
if (kc_fpr && (kc_flags & 2))
|
||||||
|
inv_key->reason = gpg_error (GPG_ERR_SUBKEYS_EXP_OR_REV);
|
||||||
|
else
|
||||||
|
inv_key->reason = gpg_error (GPG_ERR_GENERAL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@ -274,6 +284,10 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
|
|||||||
case 14:
|
case 14:
|
||||||
inv_key->reason = gpg_error (GPG_ERR_INV_USER_ID);
|
inv_key->reason = gpg_error (GPG_ERR_INV_USER_ID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
inv_key->reason = gpg_error (GPG_ERR_GENERAL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*tail && *tail == ' ')
|
while (*tail && *tail == ' ')
|
||||||
@ -287,14 +301,49 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
|
|||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
inv_key->fpr = NULL;
|
|
||||||
|
|
||||||
*key = inv_key;
|
*key = inv_key;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse a KEY_CONSIDERED status line in ARGS and store the
|
||||||
|
* fingerprint and the flags at R_FPR and R_FLAGS. The caller must
|
||||||
|
* free the value at R_FPR on success. */
|
||||||
|
gpgme_error_t
|
||||||
|
_gpgme_parse_key_considered (const char *args,
|
||||||
|
char **r_fpr, unsigned int *r_flags)
|
||||||
|
{
|
||||||
|
char *pend;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
*r_fpr = NULL;
|
||||||
|
|
||||||
|
pend = strchr (args, ' ');
|
||||||
|
if (!pend || pend == args)
|
||||||
|
return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Bogus status line. */
|
||||||
|
n = pend - args;
|
||||||
|
*r_fpr = malloc (n + 1);
|
||||||
|
if (!*r_fpr)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
memcpy (*r_fpr, args, n);
|
||||||
|
(*r_fpr)[n] = 0;
|
||||||
|
args = pend + 1;
|
||||||
|
|
||||||
|
gpg_err_set_errno (0);
|
||||||
|
*r_flags = strtoul (args, &pend, 0);
|
||||||
|
if (errno || args == pend || (*pend && *pend != ' '))
|
||||||
|
{
|
||||||
|
free (*r_fpr);
|
||||||
|
*r_fpr = NULL;
|
||||||
|
return trace_gpg_error (GPG_ERR_INV_ENGINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse the PLAINTEXT status line in ARGS and return the result in
|
/* Parse the PLAINTEXT status line in ARGS and return the result in
|
||||||
FILENAMEP. */
|
FILENAMEP. */
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
|
@ -57,9 +57,15 @@ gpgme_error_t _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type,
|
|||||||
/* Prepare a new operation on CTX. */
|
/* Prepare a new operation on CTX. */
|
||||||
gpgme_error_t _gpgme_op_reset (gpgme_ctx_t ctx, int synchronous);
|
gpgme_error_t _gpgme_op_reset (gpgme_ctx_t ctx, int synchronous);
|
||||||
|
|
||||||
|
/* Parse the KEY_CONSIDERED status line. */
|
||||||
|
gpgme_error_t _gpgme_parse_key_considered (const char *args,
|
||||||
|
char **r_fpr, unsigned int *r_flags);
|
||||||
|
|
||||||
/* Parse the INV_RECP status line in ARGS and return the result in
|
/* Parse the INV_RECP status line in ARGS and return the result in
|
||||||
KEY. */
|
KEY. */
|
||||||
gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key);
|
gpgme_error_t _gpgme_parse_inv_recp (char *args, int for_signing,
|
||||||
|
const char *kc_fpr, unsigned int kc_flags,
|
||||||
|
gpgme_invalid_key_t *key);
|
||||||
|
|
||||||
/* Parse the PLAINTEXT status line in ARGS and return the result in
|
/* Parse the PLAINTEXT status line in ARGS and return the result in
|
||||||
FILENAMEP. */
|
FILENAMEP. */
|
||||||
|
25
src/sign.c
25
src/sign.c
@ -42,6 +42,12 @@ typedef struct
|
|||||||
/* The error code from a FAILURE status line or 0. */
|
/* The error code from a FAILURE status line or 0. */
|
||||||
gpg_error_t failure_code;
|
gpg_error_t failure_code;
|
||||||
|
|
||||||
|
/* The fingerprint from the last KEY_CONSIDERED status line. */
|
||||||
|
char *kc_fpr;
|
||||||
|
|
||||||
|
/* The flags from the last KEY_CONSIDERED status line. */
|
||||||
|
unsigned int kc_flags;
|
||||||
|
|
||||||
/* A pointer to the next pointer of the last invalid signer in
|
/* A pointer to the next pointer of the last invalid signer in
|
||||||
the list. This makes appending new invalid signers painless
|
the list. This makes appending new invalid signers painless
|
||||||
while preserving the order. */
|
while preserving the order. */
|
||||||
@ -86,6 +92,7 @@ release_op_data (void *hook)
|
|||||||
}
|
}
|
||||||
|
|
||||||
release_signatures (opd->result.signatures);
|
release_signatures (opd->result.signatures);
|
||||||
|
free (opd->kc_fpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,6 +323,17 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
|||||||
opd->last_sig_p = &(*opd->last_sig_p)->next;
|
opd->last_sig_p = &(*opd->last_sig_p)->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_KEY_CONSIDERED:
|
||||||
|
/* This is emitted during gpg's key lookup to give information
|
||||||
|
* about the lookup results. We store the last one so it can be
|
||||||
|
* used in connection with INV_RECP. */
|
||||||
|
free (opd->kc_fpr);
|
||||||
|
opd->kc_fpr = NULL;
|
||||||
|
err = _gpgme_parse_key_considered (args, &opd->kc_fpr, &opd->kc_flags);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_INV_RECP:
|
case GPGME_STATUS_INV_RECP:
|
||||||
if (opd->inv_sgnr_seen && opd->ignore_inv_recp)
|
if (opd->inv_sgnr_seen && opd->ignore_inv_recp)
|
||||||
break;
|
break;
|
||||||
@ -323,11 +341,16 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
|||||||
case GPGME_STATUS_INV_SGNR:
|
case GPGME_STATUS_INV_SGNR:
|
||||||
if (code == GPGME_STATUS_INV_SGNR)
|
if (code == GPGME_STATUS_INV_SGNR)
|
||||||
opd->inv_sgnr_seen = 1;
|
opd->inv_sgnr_seen = 1;
|
||||||
err = _gpgme_parse_inv_recp (args, opd->last_signer_p);
|
free (opd->kc_fpr);
|
||||||
|
opd->kc_fpr = NULL;
|
||||||
|
err = _gpgme_parse_inv_recp (args, 1, opd->kc_fpr, opd->kc_flags,
|
||||||
|
opd->last_signer_p);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
opd->last_signer_p = &(*opd->last_signer_p)->next;
|
opd->last_signer_p = &(*opd->last_signer_p)->next;
|
||||||
|
free (opd->kc_fpr);
|
||||||
|
opd->kc_fpr = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_FAILURE:
|
case GPGME_STATUS_FAILURE:
|
||||||
|
@ -84,6 +84,7 @@ static struct status_table_s status_table[] =
|
|||||||
{ "INQUIRE_MAXLEN", GPGME_STATUS_INQUIRE_MAXLEN },
|
{ "INQUIRE_MAXLEN", GPGME_STATUS_INQUIRE_MAXLEN },
|
||||||
{ "INV_RECP", GPGME_STATUS_INV_RECP },
|
{ "INV_RECP", GPGME_STATUS_INV_RECP },
|
||||||
{ "INV_SGNR", GPGME_STATUS_INV_SGNR },
|
{ "INV_SGNR", GPGME_STATUS_INV_SGNR },
|
||||||
|
{ "KEY_CONSIDERED", GPGME_STATUS_KEY_CONSIDERED },
|
||||||
{ "KEY_CREATED", GPGME_STATUS_KEY_CREATED },
|
{ "KEY_CREATED", GPGME_STATUS_KEY_CREATED },
|
||||||
{ "KEY_NOT_CREATED", GPGME_STATUS_KEY_NOT_CREATED },
|
{ "KEY_NOT_CREATED", GPGME_STATUS_KEY_NOT_CREATED },
|
||||||
{ "KEYEXPIRED", GPGME_STATUS_KEYEXPIRED },
|
{ "KEYEXPIRED", GPGME_STATUS_KEYEXPIRED },
|
||||||
|
Loading…
Reference in New Issue
Block a user