diff options
| author | Werner Koch <[email protected]> | 2016-08-25 09:38:03 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2016-08-25 09:38:03 +0000 | 
| commit | 9ee103957e4136337b92d238283f8ef30fd4a7c5 (patch) | |
| tree | 28efd68346717ec611619c22bc9f3799f44d29bf /src | |
| parent | core: Adjust for TOFU_STATS change in gnupg 2.1.16. (diff) | |
| download | gpgme-9ee103957e4136337b92d238283f8ef30fd4a7c5.tar.gz gpgme-9ee103957e4136337b92d238283f8ef30fd4a7c5.zip | |
core: Add GPGME_KEYLIST_MODE_WITH_TOFU.
* src/gpgme.h.in (GPGME_KEYLIST_MODE_WITH_TOFU): New.
* src/engine-gpg.c (gpg_keylist_build_options): Use that.
* src/keylist.c: Include limits.h.
(parse_tfs_record): New.
(keylist_colon_handler): Support TFS record.
* tests/run-keylist.c: Include time.h.
(isotimestr): New.
(main): Add option --tofu.  Print TOFU info.
* tests/run-verify.c: Include time.h.
(isotimestr): New.
(print_result): Use isotimestr for TOFU dates.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to '')
| -rw-r--r-- | src/engine-gpg.c | 7 | ||||
| -rw-r--r-- | src/gpgme.h.in | 3 | ||||
| -rw-r--r-- | src/keylist.c | 100 | 
3 files changed, 104 insertions, 6 deletions
| diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 3edac6ca..7036ee08 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2338,8 +2338,13 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,          err = add_arg (gpg, "--with-fingerprint");      } +  if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU) +      && have_gpg_version (gpg, "2.1.16")) +    err = add_arg (gpg, "--with-tofu-info"); +    if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))      err = add_arg (gpg, "--with-secret"); +    if (!err        && (mode & GPGME_KEYLIST_MODE_SIGS)        && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS)) @@ -2348,6 +2353,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,        if (!err)  	err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");      } +    if (!err)      {        if ( (mode & GPGME_KEYLIST_MODE_EXTERN) ) @@ -2379,6 +2385,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,                              ? "--check-sigs" : "--list-keys"));          }      } +    if (!err)      err = add_arg (gpg, "--"); diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 79a7b9fd..57f34469 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -411,6 +411,7 @@ gpgme_protocol_t;  #define GPGME_KEYLIST_MODE_SIGS			4  #define GPGME_KEYLIST_MODE_SIG_NOTATIONS	8  #define GPGME_KEYLIST_MODE_WITH_SECRET       	16 +#define GPGME_KEYLIST_MODE_WITH_TOFU       	32  #define GPGME_KEYLIST_MODE_EPHEMERAL            128  #define GPGME_KEYLIST_MODE_VALIDATE		256 @@ -843,7 +844,7 @@ struct _gpgme_user_id     * NULL is stored.  */    char *address; -  /* The malloced tofo information or NULL.  */ +  /* The malloced TOFU information or NULL.  */    gpgme_tofu_info_t tofu;  };  typedef struct _gpgme_user_id *gpgme_user_id_t; diff --git a/src/keylist.c b/src/keylist.c index 38ddd0c5..9f1e68db 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -33,6 +33,7 @@  #include <assert.h>  #include <ctype.h>  #include <errno.h> +#include <limits.h>  /* Suppress warning for accessing deprecated member "class".  */  #define _GPGME_IN_GPGME @@ -403,6 +404,84 @@ parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)  } +/* Parse a tfs record.  */ +static gpg_error_t +parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield) +{ +  gpg_error_t err; +  gpgme_tofu_info_t ti; +  unsigned long uval; + +  /* We add only the first TOFU record in case future versions emit +   * several.  */ +  if (uid->tofu) +    return 0; + +  /* Check that we have enough fields and that the version is supported.  */ +  if (nfield < 8 || atoi(field[1]) != 1) +    return trace_gpg_error (GPG_ERR_INV_ENGINE); + +  ti = calloc (1, sizeof *ti); +  if (!ti) +    return gpg_error_from_syserror (); + +  /* Note that we allow a value of up to 7 which is what we can store +   * in the ti->validity.  */ +  err = _gpgme_strtoul_field (field[2], &uval); +  if (err || uval > 7) +    goto inv_engine; +  ti->validity = uval; + +  /* Parse the sign-count.  */ +  err = _gpgme_strtoul_field (field[3], &uval); +  if (err) +    goto inv_engine; +  if (uval > USHRT_MAX) +    uval = USHRT_MAX; +  ti->signcount = uval; + +  /* Parse the encr-count.  */ +  err = _gpgme_strtoul_field (field[4], &uval); +  if (err) +    goto inv_engine; +  if (uval > USHRT_MAX) +    uval = USHRT_MAX; +  ti->encrcount = uval; + +  /* Parse the policy.  */ +  if (!strcmp (field[5], "none")) +    ti->policy = GPGME_TOFU_POLICY_NONE; +  else if (!strcmp (field[5], "auto")) +    ti->policy = GPGME_TOFU_POLICY_AUTO; +  else if (!strcmp (field[5], "good")) +    ti->policy = GPGME_TOFU_POLICY_GOOD; +  else if (!strcmp (field[5], "bad")) +    ti->policy = GPGME_TOFU_POLICY_BAD; +  else if (!strcmp (field[5], "ask")) +    ti->policy = GPGME_TOFU_POLICY_ASK; +  else /* "unknown" and invalid policy strings.  */ +    ti->policy = GPGME_TOFU_POLICY_UNKNOWN; + +  /* Parse first and last seen timestamps.  */ +  err = _gpgme_strtoul_field (field[6], &uval); +  if (err) +    goto inv_engine; +  ti->firstseen = uval; +  err = _gpgme_strtoul_field (field[7], &uval); +  if (err) +    goto inv_engine; +  ti->lastseen = uval; + +  /* Ready.  */ +  uid->tofu = ti; +  return 0; + + inv_engine: +  free (ti); +  return trace_gpg_error (GPG_ERR_INV_ENGINE); +} + +  /* We have read an entire key into tmp_key and should now finish it.     It is assumed that this releases tmp_key.  */  static void @@ -426,7 +505,7 @@ keylist_colon_handler (void *priv, char *line)    gpgme_ctx_t ctx = (gpgme_ctx_t) priv;    enum      { -      RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_GRP, +      RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP,        RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK      }    rectype = RT_NONE; @@ -483,6 +562,8 @@ keylist_colon_handler (void *priv, char *line)      rectype = RT_GRP;    else if (!strcmp (field[0], "uid") && key)      rectype = RT_UID; +  else if (!strcmp (field[0], "tfs") && key) +    rectype = RT_TFS;    else if (!strcmp (field[0], "sub") && key)      rectype = RT_SUB;    else if (!strcmp (field[0], "ssb") && key) @@ -492,10 +573,10 @@ keylist_colon_handler (void *priv, char *line)    else      rectype = RT_NONE; -  /* Only look at signatures immediately following a user ID.  For -     this, clear the user ID pointer when encountering anything but a -     signature.  */ -  if (rectype != RT_SIG && rectype != RT_REV) +  /* Only look at signature and trust info records immediately +     following a user ID.  For this, clear the user ID pointer when +     encountering anything but a signature or trust record.  */ +  if (rectype != RT_SIG && rectype != RT_REV && rectype != RT_TFS)      opd->tmp_uid = NULL;    /* Only look at subpackets immediately following a signature.  For @@ -695,6 +776,15 @@ keylist_colon_handler (void *priv, char *line)  	}        break; +    case RT_TFS: +      if (opd->tmp_uid) +	{ +          err = parse_tfs_record (opd->tmp_uid, field, fields); +          if (err) +            return err; +        } +      break; +      case RT_FPR:        /* Field 10 has the fingerprint (take only the first one).  */        if (fields >= 10 && field[9] && *field[9]) | 
