From 641aae783e46af9eb47994dd598df4e51fb8296c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 22 Feb 2018 16:39:52 +0100 Subject: [PATCH 1/6] doc: Fix recently introduced typo in gpgsm.texi. -- --- doc/gpgsm.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index cd2a74165..7c6c3153f 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -256,7 +256,7 @@ fingerprints or keygrips. @item --export-secret-key-p12 @var{key-id} @opindex export-secret-key-p12 -Export the private key and the certificate identified by @var{key-id} in +Export the private key and the certificate identified by @var{key-id} using the PKCS#12 format. When used with the @code{--armor} option a few informational lines are prepended to the output. Note, that the PKCS#12 format is not very secure and proper transport security should be used From ecfc4db3a2f8bc2652ba4ac4de5ca1cd13bfcbec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Wed, 31 Jan 2018 16:57:19 +0100 Subject: [PATCH 2/6] dirmngr: Handle failures related to missing IPv6 gracefully * dirmngr/ks-engine-hkp.c (handle_send_request_error): Handle two more error codes. -- Handle the two possible connect failures related to missing IPv6 support gracefully by marking the host dead and retrying with another one. If IPv6 is disabled via procfs, connect() will return EADDRNOTAVAIL. If IPv6 is not compiled into the kernel, it will return EAFNOSUPPORT. This makes it possible to use dual-stack hkp servers on hosts not having IPv6 without random connection failures. GnuPG-bug-id: 3331 -- The above description seems to be for Linux, so it is possible that other systems might behave different. However, it is worth to try this patch. Signed-off-by: Werner Koch --- dirmngr/ks-engine-hkp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 4a0b08f4f..a9bb93666 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1353,6 +1353,8 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request, case GPG_ERR_UNKNOWN_HOST: case GPG_ERR_NETWORK: case GPG_ERR_EIO: /* Sometimes used by estream cookie functions. */ + case GPG_ERR_EADDRNOTAVAIL: /* e.g. when IPv6 is disabled */ + case GPG_ERR_EAFNOSUPPORT: /* e.g. when IPv6 is not compiled in */ if (mark_host_dead (request) && *tries_left) retry = 1; break; From e43844c3b0b9ec93b7f2a88752bcd6b6244aacfb Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Wed, 28 Feb 2018 16:29:56 +0100 Subject: [PATCH 3/6] gpgconf, w32: Allow UNC paths * tools/gpgconf-comp.c (get_config_filename): Allow UNC paths. -- The homedir of GnuPG on Windows can be on a network share e.g. if %APPDATA% is redirected to a network share. The file API calls work and GnuPG itself works nicely with such paths so gpgconf should work with them, too. GnuPG-Bug-Id: T3818 Signed-off-by: Andre Heinecke --- tools/gpgconf-comp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index f705f3ab5..b10b146f4 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2076,7 +2076,9 @@ get_config_filename (gc_component_t component, gc_backend_t backend) #elif defined(HAVE_DOSISH_SYSTEM) if (!(filename[0] && filename[1] == ':' - && (filename[2] == '/' || filename[2] == '\\'))) + && (filename[2] == '/' || filename[2] == '\\')) /* x:\ or x:/ */ + && !((filename[0] == '\\' && filename[1] == '\\') + || (filename[0] == '/' && filename[1] == '/'))) /* \\server */ #else if (filename[0] != '/') #endif From fd595c9d3642dba437fbe0f6e25d7aaaae095f94 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Mar 2018 19:03:23 +0100 Subject: [PATCH 4/6] gpg: Print the keygrip with --card-status * g10/call-agent.h (agent_card_info_s): Add fields grp1, grp2 and grp3. * g10/call-agent.c (unhexify_fpr): Allow for space as delimiter. (learn_status_cb): Parse KEYPARIINFO int the grpX fields. * g10/card-util.c (print_keygrip): New. (current_card_status): Print "grp:" records or with --with-keygrip a human readable keygrip. -- Suggested-by: Peter Lebbing Signed-off-by: Werner Koch --- g10/call-agent.c | 21 ++++++++++++++++++++- g10/call-agent.h | 3 +++ g10/card-util.c | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 545b2448a..f29e1b131 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -381,10 +381,11 @@ unhexify_fpr (const char *hexstr, unsigned char *fpr) for (s=hexstr, n=0; hexdigitp (s); s++, n++) ; - if (*s || (n != 40)) + if ((*s && *s != ' ') || (n != 40)) return 0; /* no fingerprint (invalid or wrong length). */ for (s=hexstr, n=0; *s; s += 2, n++) fpr[n] = xtoi_2 (s); + return 1; /* okay */ } @@ -625,6 +626,24 @@ learn_status_cb (void *opaque, const char *line) else if (no == 3) parm->fpr3time = strtoul (line, NULL, 10); } + else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen)) + { + const char *hexgrp = line; + int no; + + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + if (strncmp (line, "OPENPGP.", 8)) + ; + else if ((no = atoi (line+8)) == 1) + unhexify_fpr (hexgrp, parm->grp1); + else if (no == 2) + unhexify_fpr (hexgrp, parm->grp2); + else if (no == 3) + unhexify_fpr (hexgrp, parm->grp3); + } else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen)) { int no = atoi (line); diff --git a/g10/call-agent.h b/g10/call-agent.h index f45b64d90..53775c5c8 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -47,6 +47,9 @@ struct agent_card_info_s u32 fpr1time; u32 fpr2time; u32 fpr3time; + char grp1[20]; /* The keygrip for OPENPGP.1 */ + char grp2[20]; /* The keygrip for OPENPGP.2 */ + char grp3[20]; /* The keygrip for OPENPGP.3 */ unsigned long sig_counter; int chv1_cached; /* True if a PIN is not required for each signing. Note that the gpg-agent might cache diff --git a/g10/card-util.c b/g10/card-util.c index 759dde8e8..bda4e83b9 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -263,6 +263,21 @@ print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr) } +static void +print_keygrip (estream_t fp, const unsigned char *grp) +{ + int i; + + if (opt.with_keygrip) + { + tty_fprintf (fp, " keygrip ....: "); + for (i=0; i < 20 ; i++, grp++) + es_fprintf (fp, "%02X", *grp); + tty_fprintf (fp, "\n"); + } +} + + static void print_name (estream_t fp, const char *text, const char *name) { @@ -517,6 +532,11 @@ current_card_status (ctrl_t ctrl, estream_t fp, es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n", (unsigned long)info.fpr1time, (unsigned long)info.fpr2time, (unsigned long)info.fpr3time); + es_fputs ("grp:", fp); + print_sha1_fpr_colon (fp, info.grp1); + print_sha1_fpr_colon (fp, info.grp2); + print_sha1_fpr_colon (fp, info.grp3); + es_putc ('\n', fp); } else { @@ -593,18 +613,27 @@ current_card_status (ctrl_t ctrl, estream_t fp, tty_fprintf (fp, "Signature key ....:"); print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL); if (info.fpr1valid && info.fpr1time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr1time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr1time)); + print_keygrip (fp, info.grp1); + } tty_fprintf (fp, "Encryption key....:"); print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); if (info.fpr2valid && info.fpr2time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr2time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr2time)); + print_keygrip (fp, info.grp2); + } tty_fprintf (fp, "Authentication key:"); print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); if (info.fpr3valid && info.fpr3time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr3time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr3time)); + print_keygrip (fp, info.grp2); + } tty_fprintf (fp, "General key info..: "); thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : From bf43b39c05cfc68ea17483c78f14bfca6faf08eb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Mar 2018 19:10:10 +0100 Subject: [PATCH 5/6] gpg: Fix regression in last --card-status patch -- Sorry, I accidentally pushed the last commit without having amended it with this fix. Fixes-commit: fd595c9d3642dba437fbe0f6e25d7aaaae095f94 Signed-off-by: Werner Koch --- g10/call-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index f29e1b131..ea530e7ac 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -383,7 +383,7 @@ unhexify_fpr (const char *hexstr, unsigned char *fpr) ; if ((*s && *s != ' ') || (n != 40)) return 0; /* no fingerprint (invalid or wrong length). */ - for (s=hexstr, n=0; *s; s += 2, n++) + for (s=hexstr, n=0; *s && n < 20; s += 2, n++) fpr[n] = xtoi_2 (s); return 1; /* okay */ From f060cb5c63923d6caec784f65f3bb0aadf52f795 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Mar 2018 16:22:42 +0100 Subject: [PATCH 6/6] agent: Also evict cached items via a timer. * agent/cache.c (agent_cache_housekeeping): New func. * agent/gpg-agent.c (handle_tick): Call it. -- This change mitigates the risk of having cached items in a post mortem dump. GnuPG-bug-id: 3829 Signed-off-by: Werner Koch --- agent/agent.h | 1 + agent/cache.c | 20 ++++++++++++++++++++ agent/gpg-agent.c | 3 +++ doc/gpg-agent.texi | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/agent/agent.h b/agent/agent.h index c2d857959..743b76595 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -450,6 +450,7 @@ int agent_clear_passphrase (ctrl_t ctrl, /*-- cache.c --*/ void initialize_module_cache (void); void deinitialize_module_cache (void); +void agent_cache_housekeeping (void); void agent_flush_cache (void); int agent_put_cache (const char *key, cache_mode_t cache_mode, const char *data, int ttl); diff --git a/agent/cache.c b/agent/cache.c index 80d5f8d1e..ed5c97cd2 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -258,6 +258,26 @@ housekeeping (void) } +void +agent_cache_housekeeping (void) +{ + int res; + + if (DBG_CACHE) + log_debug ("agent_cache_housekeeping\n"); + + res = npth_mutex_lock (&cache_lock); + if (res) + log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); + + housekeeping (); + + res = npth_mutex_unlock (&cache_lock); + if (res) + log_fatal ("failed to release cache mutex: %s\n", strerror (res)); +} + + void agent_flush_cache (void) { diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a1964ece8..bd9a471e8 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2398,6 +2398,9 @@ handle_tick (void) } #endif + /* Need to check for expired cache entries. */ + agent_cache_housekeeping (); + /* Check whether the homedir is still available. */ if (!shutdown_pending && (!have_homedir_inotify || !reliable_homedir_inotify) diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 3e8bd894d..4781bbdca 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -403,7 +403,10 @@ control this behavior but this command line option takes precedence. Set the time a cache entry is valid to @var{n} seconds. The default is 600 seconds. Each time a cache entry is accessed, the entry's timer is reset. To set an entry's maximum lifetime, use -@command{max-cache-ttl}. +@command{max-cache-ttl}. Note that a cached passphrase may not +evicted immediately from memory if no client requests a cache +operation. This is due to an internal housekeeping function which is +only run every few seconds. @item --default-cache-ttl-ssh @var{n} @opindex default-cache-ttl