From c27534de955370dde2f516d217e4c1bb117d2697 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 13 Mar 2024 15:32:10 +0100 Subject: gpg-check-pattern: Consider an empty pattern file as valid * tools/gpg-check-pattern.c (read_file): Check length before calling fread. -- The problem with an empty file is that es_fread is called to read one element of length zero which seems to be undefined behaviour and results in ENOENT on my test box. --- tools/gpg-check-pattern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c index d7481fffb..2698431c9 100644 --- a/tools/gpg-check-pattern.c +++ b/tools/gpg-check-pattern.c @@ -285,7 +285,7 @@ read_file (const char *fname, size_t *r_length) buflen = st.st_size; buf = xmalloc (buflen+1); - if (es_fread (buf, buflen, 1, fp) != 1) + if (buflen && es_fread (buf, buflen, 1, fp) != 1) { log_error ("error reading '%s': %s\n", fname, strerror (errno)); es_fclose (fp); -- cgit v1.2.3 From 122803bf1ac9ee720d9fc214f5ae5c2a0ec22bf5 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 14 Mar 2024 21:41:15 +0100 Subject: gpg: Make sure a DECRYPTION_OKAY is never issued for a bad OCB tag. * g10/mainproc.c (proc_encrypted): Force a decryption failure if any error has been seen. * g10/decrypt-data.c (aead_checktag): Issue an ERROR line. -- GnuPG-bug-id: 7042 Note that gpg in any case returns a failure exit code but due to double forking GPGME would not see it. --- g10/decrypt-data.c | 1 + g10/mainproc.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 86e208d01..ea4d48955 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -205,6 +205,7 @@ aead_checktag (decode_filter_ctx_t dfx, int final, const void *tagbuf) { log_error ("gcry_cipher_checktag%s failed: %s\n", final? " (final)":"", gpg_strerror (err)); + write_status_error ("aead_checktag", err); return err; } if (DBG_FILTER) diff --git a/g10/mainproc.c b/g10/mainproc.c index 5f3f6df86..e722618ca 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -781,9 +781,13 @@ proc_encrypted (CTX c, PACKET *pkt) compliance_de_vs |= 2; } - /* Trigger the deferred error. */ + /* Trigger the deferred error. The second condition makes sure that a + * log_error printed in the cry_cipher_checktag never gets ignored. */ if (!result && early_plaintext) result = gpg_error (GPG_ERR_BAD_DATA); + else if (!result && pkt->pkt.encrypted->aead_algo + && log_get_errorcount (0)) + result = gpg_error (GPG_ERR_BAD_SIGNATURE); if (result == -1) ; -- cgit v1.2.3 From 759adb249310abff30e707c0800c9910de97a6dd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Mar 2024 11:14:19 +0100 Subject: gpgconf: Check readability of some files with -X * tools/gpgconf.c (list_dirs): Rename arg from special to show_config_mode. Add "S.Uiserver" test and test existsing files for readability. --- tools/gpgconf.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 6a5add42b..0515aa807 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -260,10 +260,10 @@ gpgconf_write_status (int no, const char *format, ...) static void -list_dirs (estream_t fp, char **names, int special) +list_dirs (estream_t fp, char **names, int show_config_mode) { static struct { - const char *name; + const char *name; /* If NULL only a file check will be done. */ const char *(*fnc)(void); const char *extra; } list[] = { @@ -280,12 +280,13 @@ list_dirs (estream_t fp, char **names, int special) { "agent-extra-socket", gnupg_socketdir, GPG_AGENT_EXTRA_SOCK_NAME }, { "agent-browser-socket",gnupg_socketdir, GPG_AGENT_BROWSER_SOCK_NAME }, { "agent-socket", gnupg_socketdir, GPG_AGENT_SOCK_NAME }, + { NULL, gnupg_socketdir, "S.uiserver" }, { "homedir", gnupg_homedir, NULL } }; int idx, j; char *tmp; const char *s; - + gpg_error_t err; for (idx = 0; idx < DIM (list); idx++) { @@ -297,7 +298,10 @@ list_dirs (estream_t fp, char **names, int special) } else tmp = NULL; - if (!names) + + if (!list[idx].name) + ; + else if (!names) es_fprintf (fp, "%s:%s\n", list[idx].name, gc_percent_escape (s)); else { @@ -309,6 +313,23 @@ list_dirs (estream_t fp, char **names, int special) } } + /* In show config mode check that the socket files are accessible. */ + if (list[idx].extra && show_config_mode) + { + estream_t tmpfp; + + tmpfp = es_fopen (s, "rb"); + if (tmpfp) + es_fclose (tmpfp); /* All fine - we can read that file. */ + else if ((err=gpg_error_from_syserror ()) == GPG_ERR_ENOENT + || err == GPG_ERR_ENXIO) + ; /* No such file/ No such device or address - this is okay. */ + else + es_fprintf (fp, + "### Warning: error reading existing file '%s': %s\n", + s, gpg_strerror (err)); + } + xfree (tmp); } @@ -339,7 +360,7 @@ list_dirs (estream_t fp, char **names, int special) } es_fflush (fp); - if (special) + if (show_config_mode) es_fprintf (fp, "\n" "### Note: homedir taken from registry key %s%s\\%s:%s\n" "\n", @@ -357,7 +378,7 @@ list_dirs (estream_t fp, char **names, int special) { xfree (tmp); es_fflush (fp); - if (special) + if (show_config_mode) es_fprintf (fp, "\n" "### Note: registry %s without value in HKCU or HKLM\n" "\n", GNUPG_REGISTRY_DIR); @@ -367,7 +388,7 @@ list_dirs (estream_t fp, char **names, int special) } #else /*!HAVE_W32_SYSTEM*/ - (void)special; + (void)show_config_mode; #endif /*!HAVE_W32_SYSTEM*/ } @@ -1342,7 +1363,7 @@ show_versions (estream_t fp) /* Copy data from file SRC to DST. Returns 0 on success or an error * code on failure. If LISTP is not NULL, that strlist is updated - * with the variabale or registry key names detected. Flag bit 0 + * with the variable or registry key names detected. Flag bit 0 * indicates a registry entry. */ static gpg_error_t my_copy_file (estream_t src, estream_t dst, strlist_t *listp) -- cgit v1.2.3 From 98e287ba6d55a74dad3ce9b8b33501d3f960787c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Apr 2024 15:09:12 +0200 Subject: gpgconf: Change layout of the gpgconf -X output. * tools/gpgconf.c (list_dirs): Change the config mode output. (my_copy_file): Adjust output for org-mode style. (show_configs_one_file): Ditto. (show_other_registry_entries): Ditto. (show_registry_entries_from_file): Ditto. (show_configs): Ditto. --- tools/gpgconf.c | 123 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 52 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 0515aa807..061a4f727 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -288,6 +288,8 @@ list_dirs (estream_t fp, char **names, int show_config_mode) const char *s; gpg_error_t err; + if (show_config_mode) + es_fprintf (fp, "#+begin_example\n"); for (idx = 0; idx < DIM (list); idx++) { s = list[idx].fnc (); @@ -302,12 +304,15 @@ list_dirs (estream_t fp, char **names, int show_config_mode) if (!list[idx].name) ; else if (!names) - es_fprintf (fp, "%s:%s\n", list[idx].name, gc_percent_escape (s)); + es_fprintf (fp, "%s%s:%s\n", show_config_mode? " ":"", + list[idx].name, gc_percent_escape (s)); else { for (j=0; names[j]; j++) if (!strcmp (names[j], list[idx].name)) { + if (show_config_mode) + es_fputs (" ", fp); es_fputs (s, fp); es_putc (opt.null? '\0':'\n', fp); } @@ -326,12 +331,14 @@ list_dirs (estream_t fp, char **names, int show_config_mode) ; /* No such file/ No such device or address - this is okay. */ else es_fprintf (fp, - "### Warning: error reading existing file '%s': %s\n", + "# Warning: error reading existing file '%s': %s\n", s, gpg_strerror (err)); } xfree (tmp); } + if (show_config_mode) + es_fprintf (fp, "#+end_example\n"); #ifdef HAVE_W32_SYSTEM @@ -362,7 +369,7 @@ list_dirs (estream_t fp, char **names, int show_config_mode) es_fflush (fp); if (show_config_mode) es_fprintf (fp, "\n" - "### Note: homedir taken from registry key %s%s\\%s:%s\n" + "Note: homedir taken from registry key %s%s\\%s:%s\n" "\n", hkcu?"HKCU":"", hklm?"HKLM":"", GNUPG_REGISTRY_DIR, "HomeDir"); @@ -380,7 +387,7 @@ list_dirs (estream_t fp, char **names, int show_config_mode) es_fflush (fp); if (show_config_mode) es_fprintf (fp, "\n" - "### Note: registry %s without value in HKCU or HKLM\n" + "Note: registry %s without value in HKCU or HKLM\n" "\n", GNUPG_REGISTRY_DIR); else log_info ("Warning: registry key (%s) without value in HKCU or HKLM\n", @@ -1185,14 +1192,14 @@ show_version_gnupg (estream_t fp, const char *prefix) gpgrt_strusage (13), BUILD_REVISION, prefix, gpgrt_strusage (17)); /* Show the GnuPG VS-Desktop version in --show-configs mode */ - if (prefix && *prefix == '#') + if (prefix && *prefix) { fname = make_filename (gnupg_bindir (), NULL); n = strlen (fname); if (n > 10 && (!ascii_strcasecmp (fname + n - 10, "/GnuPG/bin") || !ascii_strcasecmp (fname + n - 10, "\\GnuPG\\bin"))) { - /* Append VERSION to the ../../ direcory. Note that VERSION + /* Append VERSION to the ../../ directory. Note that VERSION * is only 7 bytes and thus fits. */ strcpy (fname + n - 9, "VERSION"); verfp = es_fopen (fname, "r"); @@ -1376,7 +1383,14 @@ my_copy_file (estream_t src, estream_t dst, strlist_t *listp) while ((length = es_read_line (src, &line, &line_len, NULL)) > 0) { - /* Strip newline and carriage return, if present. */ + /* Prefix each line with two spaces but use a comma if the line + * starts with a special org-mode character. */ + if (*line == '*' || (*line == '#' && line[1] == '+')) + es_fputc (',', dst); + else + es_fputc (' ', dst); + es_fputc (' ', dst); + written = gpgrt_fwrite (line, 1, length, dst); if (written != length) return gpg_error_from_syserror (); @@ -1444,21 +1458,19 @@ show_configs_one_file (const char *fname, int global, estream_t outfp, if (!fp) { err = gpg_error_from_syserror (); - es_fprintf (outfp, "###\n### %s config \"%s\": %s\n###\n", - global? "global":"local", fname, - (gpg_err_code (err) == GPG_ERR_ENOENT)? - "not installed" : gpg_strerror (err)); + if (gpg_err_code (err) != GPG_ERR_ENOENT) + es_fprintf (outfp, "** %s config \"%s\": %s\n", + global? "global":"local", fname, gpg_strerror (err)); } else { - es_fprintf (outfp, "###\n### %s config \"%s\"\n###\n", + es_fprintf (outfp, "** %s config \"%s\"\n#+begin_src\n", global? "global":"local", fname); - es_fprintf (outfp, CUTLINE_FMT, "start"); err = my_copy_file (fp, outfp, listp); + es_fprintf (outfp, "\n#+end_src\n"); if (err) - log_error ("error copying file \"%s\": %s\n", + log_error ("Error copying file \"%s\": %s\n", fname, gpg_strerror (err)); - es_fprintf (outfp, CUTLINE_FMT, "end--"); es_fclose (fp); } } @@ -1533,7 +1545,7 @@ show_other_registry_entries (estream_t outfp) if (names[idx].group != group) { group = names[idx].group; - es_fprintf (outfp, "###\n### %s related:\n", + es_fprintf (outfp, "\n%s related:\n", group == 1 ? "GnuPG Desktop" : group == 2 ? "Outlook" : group == 3 ? "\\Software\\GNU\\GpgOL" @@ -1541,16 +1553,15 @@ show_other_registry_entries (estream_t outfp) } if (group == 3) - es_fprintf (outfp, "### %s=%s%s\n", names[idx].name, value, + es_fprintf (outfp, " %s=%s%s\n", names[idx].name, value, from_hklm? " [hklm]":""); else - es_fprintf (outfp, "### %s\n### ->%s<-%s\n", name, value, + es_fprintf (outfp, " %s\n ->%s<-%s\n", name, value, from_hklm? " [hklm]":""); xfree (value); } - es_fprintf (outfp, "###\n"); xfree (namebuf); } @@ -1601,10 +1612,10 @@ show_registry_entries_from_file (estream_t outfp) if (!any) { any = 1; - es_fprintf (outfp, "### Taken from gpgconf.rnames:\n"); + es_fprintf (outfp, "Taken from gpgconf.rnames:\n"); } - es_fprintf (outfp, "### %s\n### ->%s<-%s\n", line, value, + es_fprintf (outfp, " %s\n ->%s<-%s\n", line, value, from_hklm? " [hklm]":""); } @@ -1615,8 +1626,6 @@ show_registry_entries_from_file (estream_t outfp) } leave: - if (any) - es_fprintf (outfp, "###\n"); xfree (value); xfree (line); es_fclose (fp); @@ -1643,18 +1652,21 @@ show_configs (estream_t outfp) gnupg_dir_t dir; gnupg_dirent_t dir_entry; size_t n; - int any; + int any, anywarn; strlist_t list = NULL; strlist_t sl; const char *s; int got_gpgconfconf = 0; - es_fprintf (outfp, "### Dump of all standard config files\n"); - show_version_gnupg (outfp, "### "); - es_fprintf (outfp, "### Libgcrypt %s\n", gcry_check_version (NULL)); - es_fprintf (outfp, "### GpgRT %s\n", gpg_error_check_version (NULL)); + es_fprintf (outfp, "# gpgconf -X invoked %s%*s-*- org -*-\n\n", + isotimestamp (time (NULL)), 28, ""); + es_fprintf (outfp, "* General information\n"); + es_fprintf (outfp, "** Versions\n"); + show_version_gnupg (outfp, " "); + es_fprintf (outfp, " Libgcrypt %s\n", gcry_check_version (NULL)); + es_fprintf (outfp, " GpgRT %s\n", gpg_error_check_version (NULL)); #ifdef HAVE_W32_SYSTEM - es_fprintf (outfp, "### Codepages:"); + es_fprintf (outfp, " Codepages:"); if (GetConsoleCP () != GetConsoleOutputCP ()) es_fprintf (outfp, " %u/%u", GetConsoleCP (), GetConsoleOutputCP ()); else @@ -1662,16 +1674,19 @@ show_configs (estream_t outfp) es_fprintf (outfp, " %u", GetACP ()); es_fprintf (outfp, " %u\n", GetOEMCP ()); #endif - es_fprintf (outfp, "###\n\n"); + es_fprintf (outfp, "\n\n"); + es_fprintf (outfp, "** Directories\n"); list_dirs (outfp, NULL, 1); es_fprintf (outfp, "\n"); + es_fprintf (outfp, "** Environment\n#+begin_example\n"); for (idx=0; idx < DIM(envvars); idx++) if ((s = getenv (envvars[idx]))) es_fprintf (outfp, "%s=%s\n", envvars[idx], s); - es_fprintf (outfp, "\n"); + es_fprintf (outfp, "#+end_example\n"); + es_fprintf (outfp, "* Config files\n"); fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); if (!gnupg_access (fname, F_OK)) { @@ -1693,6 +1708,7 @@ show_configs (estream_t outfp) } /* Print the encountered registry values and envvars. */ + es_fprintf (outfp, "* Other info\n"); if (list) { any = 0; @@ -1703,20 +1719,21 @@ show_configs (estream_t outfp) { any = 1; es_fprintf (outfp, - "###\n" - "### List of encountered environment variables:\n"); + "** List of encountered environment variables\n" + "#+begin_example\n"); } if ((s = getenv (sl->d))) - es_fprintf (outfp, "### %-12s ->%s<-\n", sl->d, s); + es_fprintf (outfp, " %-12s ->%s<-\n", sl->d, s); else - es_fprintf (outfp, "### %-12s [not set]\n", sl->d); + es_fprintf (outfp, " %-12s [not set]\n", sl->d); } if (any) - es_fprintf (outfp, "###\n"); + es_fprintf (outfp, "#+end_example\n"); } #ifdef HAVE_W32_SYSTEM - es_fprintf (outfp, "###\n### Registry entries:\n"); + es_fprintf (outfp, "** Registry entries\n"); + es_fprintf (outfp, "#+begin_example\n"); any = 0; if (list) { @@ -1729,33 +1746,31 @@ show_configs (estream_t outfp) if (!any) { any = 1; - es_fprintf (outfp, "###\n### Encountered in config files:\n"); + es_fprintf (outfp, "Encountered in config files:\n"); } if ((p = read_w32_reg_string (sl->d, &from_hklm))) - es_fprintf (outfp, "### %s ->%s<-%s\n", sl->d, p, + es_fprintf (outfp, " %s ->%s<-%s\n", sl->d, p, from_hklm? " [hklm]":""); else - es_fprintf (outfp, "### %s [not set]\n", sl->d); + es_fprintf (outfp, " %s [not set]\n", sl->d); xfree (p); } } - if (!any) - es_fprintf (outfp, "###\n"); show_other_registry_entries (outfp); show_registry_entries_from_file (outfp); + es_fprintf (outfp, "#+end_example\n"); #endif /*HAVE_W32_SYSTEM*/ free_strlist (list); - any = 0; - /* Additional warning. */ + anywarn = 0; if (got_gpgconfconf) { + anywarn = 1; + es_fprintf (outfp, "* Warnings\n"); es_fprintf (outfp, - "###\n" - "### Warning: legacy config file \"gpgconf.conf\" found\n"); - any = 1; + "- Legacy config file \"gpgconf.conf\" found\n"); } /* Check for uncommon files in the home directory. */ @@ -1768,6 +1783,7 @@ show_configs (estream_t outfp) return; } + any = 0; while ((dir_entry = gnupg_readdir (dir))) { for (idx = 0; idx < DIM (names); idx++) @@ -1777,19 +1793,22 @@ show_configs (estream_t outfp) && dir_entry->d_name[n] == '-' && ascii_strncasecmp (dir_entry->d_name, "gpg.conf-1", 10)) { + if (!anywarn) + { + anywarn = 1; + es_fprintf (outfp, "* Warnings\n"); + } if (!any) { any = 1; es_fprintf (outfp, - "###\n" - "### Warning: suspicious files in \"%s\":\n", + "- Suspicious files in \"%s\":\n", gnupg_homedir ()); } - es_fprintf (outfp, "### %s\n", dir_entry->d_name); + es_fprintf (outfp, " - %s\n", dir_entry->d_name); } } } - if (any) - es_fprintf (outfp, "###\n"); gnupg_closedir (dir); + es_fprintf (outfp, "# eof #\n"); } -- cgit v1.2.3 From 0b1f7427b3ca9a378f9a8290a2b1e31b71d608f6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Apr 2024 16:39:14 +0200 Subject: gpg: Do not allow to accidently set the RENC usage. * g10/keygen.c (print_key_flags): Print "RENC" if set. (ask_key_flags_with_mask): Remove RENC from the possible set of usages. Add a direct way to set it iff the key is encryption capable. -- This could be done by using "set your own capabilities" for an RSA key. In fact it was always set in this case. GnuPG-bug-id: 7072 --- g10/keygen.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/g10/keygen.c b/g10/keygen.c index b263a47de..48e5b3a40 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1982,6 +1982,9 @@ print_key_flags(int flags) if(flags&PUBKEY_USAGE_AUTH) tty_printf("%s ",_("Authenticate")); + + if(flags&PUBKEY_USAGE_RENC) + tty_printf("%s ", "RENC"); } @@ -2014,10 +2017,14 @@ ask_key_flags_with_mask (int algo, int subkey, unsigned int current, togglers = "11223300"; } + /* restrict the mask to the actual useful bits. */ + /* Mask the possible usage flags. This is for example used for a * card based key. For ECDH we need to allows additional usages if - * they are provided. */ + * they are provided. RENC is not directly poissible here but see + * below for a workaround. */ possible = (openpgp_pk_algo_usage (algo) & mask); + possible &= ~PUBKEY_USAGE_RENC; if (algo == PUBKEY_ALGO_ECDH) possible |= (current & (PUBKEY_USAGE_ENC |PUBKEY_USAGE_CERT @@ -2086,6 +2093,12 @@ ask_key_flags_with_mask (int algo, int subkey, unsigned int current, want to experiment with a cert-only primary key. */ current |= PUBKEY_USAGE_CERT; } + else if ((*s == 'r' || *s == 'R') && (possible&PUBKEY_USAGE_ENC)) + { + /* Allow to set RENC or an encryption capable key. + * This is on purpose not shown in the menu. */ + current |= PUBKEY_USAGE_RENC; + } } break; } -- cgit v1.2.3 From 548fd7bca787bfa9439c2bec4153a9311dbbea34 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 11:02:43 +0200 Subject: gpg: Don't show the "fast path listing" diagnostic with --quiet. * g10/call-agent.c (agent_probe_any_secret_key): Act on --quiet. -- When using the extra-socket this disagnostic will be printed because a listing of all secret keys is not allowed by a remote gpg. --- g10/call-agent.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index daf12fae7..69207566e 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2319,8 +2319,9 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) } if (err) { - log_info ("problem with fast path key listing: %s - ignored\n", - gpg_strerror (err)); + if (!opt.quiet) + log_info ("problem with fast path key listing: %s - ignored\n", + gpg_strerror (err)); err = 0; } /* We want to do this only once. */ -- cgit v1.2.3 From b261478c06f07d92a6a9c003316b09c5716da223 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 14:45:05 +0200 Subject: agent: Fix error handling of READKEY. * agent/command.c (cmd_readkey): Jump to leave on reading error. -- Fixes-commit: d7a3c455c5e29b19b66772f86dda925064e34896 --- agent/command.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/agent/command.c b/agent/command.c index 575456cc5..40322f385 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1418,7 +1418,9 @@ cmd_readkey (assuan_context_t ctx, char *line) goto leave; rc = agent_public_key_from_file (ctrl, grip, &s_pkey); - if (!rc) + if (rc) + goto leave; + else { if (opt_format_ssh) { -- cgit v1.2.3 From 967678d9728cdc0627ab6d7861608d0e44f02890 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Apr 2024 11:42:20 +0200 Subject: gpg: New command --quick-set-ownertrust. * g10/gpg.c (aQuickSetOwnertrust): New. (opts): Add new command. (main): Implement it. * g10/keyedit.c (keyedit_quick_set_ownertrust): New. --- doc/gpg.texi | 9 ++++++- g10/gpg.c | 13 ++++++++++ g10/keyedit.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- g10/keyedit.h | 2 ++ 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 1d1c38cd9..ae1db9f92 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1223,12 +1223,19 @@ all affected self-signatures is set one second ahead. This command updates the preference list of the key to the current default value (either built-in or set via @option{--default-preference-list}). This is the unattended version -of of using "setpref" in the @option{--key-edit} menu without giving a +of using "setpref" in the @option{--key-edit} menu without giving a list. Note that you can show the preferences in a key listing by using @option{--list-options show-pref} or @option{--list-options show-pref-verbose}. You should also re-distribute updated keys to your peers. +@item --quick-set-ownertrust @var{user-id} @var{value} +@opindex quick-set-ownertrust +This command sets the ownertrust of a key and can also be used to set +the disable flag of a key. This is the unattended version of using +"trust", "disable", or "enable" in the @option{--key-edit} menu. + + @item --change-passphrase @var{user-id} @opindex change-passphrase @itemx --passwd @var{user-id} diff --git a/g10/gpg.c b/g10/gpg.c index 80cb2f38b..29b7eb55d 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -136,6 +136,7 @@ enum cmd_and_opt_values aQuickSetExpire, aQuickSetPrimaryUid, aQuickUpdatePref, + aQuickSetOwnertrust, aListConfig, aListGcryptConfig, aGPGConfList, @@ -502,6 +503,7 @@ static gpgrt_opt_t opts[] = { N_("quickly set a new expiration date")), ARGPARSE_c (aQuickSetPrimaryUid, "quick-set-primary-uid", "@"), ARGPARSE_c (aQuickUpdatePref, "quick-update-pref", "@"), + ARGPARSE_c (aQuickSetOwnertrust, "quick-set-ownertrust", "@"), ARGPARSE_c (aFullKeygen, "full-generate-key" , N_("full featured key pair generation")), ARGPARSE_c (aFullKeygen, "full-gen-key", "@"), @@ -2717,6 +2719,7 @@ main (int argc, char **argv) case aQuickSetExpire: case aQuickSetPrimaryUid: case aQuickUpdatePref: + case aQuickSetOwnertrust: case aExportOwnerTrust: case aImportOwnerTrust: case aRebuildKeydbCaches: @@ -4393,6 +4396,7 @@ main (int argc, char **argv) case aQuickRevUid: case aQuickSetPrimaryUid: case aQuickUpdatePref: + case aQuickSetOwnertrust: case aFullKeygen: case aKeygen: case aImport: @@ -4912,6 +4916,15 @@ main (int argc, char **argv) } break; + case aQuickSetOwnertrust: + { + if (argc != 2) + wrong_args ("--quick-set-ownertrust USER-ID" + " [enable|disable|full|...]"); + keyedit_quick_set_ownertrust (ctrl, argv[0], argv[1]); + } + break; + case aFastImport: opt.import_options |= IMPORT_FAST; /* fall through */ case aImport: diff --git a/g10/keyedit.c b/g10/keyedit.c index 7523a1a62..f4f59de03 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2754,6 +2754,87 @@ keyedit_quick_update_pref (ctrl_t ctrl, const char *username) } +/* Unattended updating of the ownertrust or disable/enable state of a key + * USERNAME specifies the key. This is somewhat similar to + * gpg --edit-key trust save + * gpg --edit-key disable save + * + * VALUE is the new trust value which is one of: + * "undefined" - Ownertrust is set to undefined + * "never" - Ownertrust is set to never trust + * "marginal" - Ownertrust is set to marginal trust + * "full" - Ownertrust is set to full trust + * "ultimate" - Ownertrust is set to ultimate trust + * "enable" - The key is re-enabled. + * "disable" - The key is disabled. + * Trust settings do not change the ebable/disable state. + */ +void +keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, + const char *value) +{ + gpg_error_t err; + KEYDB_HANDLE kdbhd = NULL; + kbnode_t keyblock = NULL; + PKT_public_key *pk; + unsigned int trust, newtrust; + int x; + int maybe_update_trust = 0; + +#ifdef HAVE_W32_SYSTEM + /* See keyedit_menu for why we need this. */ + check_trustdb_stale (ctrl); +#endif + + /* Search the key; we don't want the whole getkey stuff here. Note + * that we are looking for the public key here. */ + err = quick_find_keyblock (ctrl, username, 0, &kdbhd, &keyblock); + if (err) + goto leave; + log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_SECRET_KEY); + pk = keyblock->pkt->pkt.public_key; + + trust = newtrust = get_ownertrust (ctrl, pk); + + if (!ascii_strcasecmp (value, "enable")) + newtrust &= ~TRUST_FLAG_DISABLED; + else if (!ascii_strcasecmp (value, "disable")) + newtrust |= TRUST_FLAG_DISABLED; + else if ((x = string_to_trust_value (value)) >= 0) + { + newtrust = x; + newtrust &= TRUST_MASK; + newtrust |= (trust & ~TRUST_MASK); + maybe_update_trust = 1; + } + else + { + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (trust != newtrust) + { + update_ownertrust (ctrl, pk, newtrust); + if (maybe_update_trust) + revalidation_mark (ctrl); + } + else if (opt.verbose) + log_info (_("Key not changed so no update needed.\n")); + + leave: + if (err) + { + log_error (_("setting the ownertrust to '%s' failed: %s\n"), + value, gpg_strerror (err)); + write_status_error ("keyedit.setownertrust", err); + } + release_kbnode (keyblock); + keydb_release (kdbhd); +} + + /* Find a keyblock by fingerprint because only this uniquely * identifies a key and may thus be used to select a key for * unattended subkey creation os key signing. */ @@ -2998,7 +3079,7 @@ keyedit_quick_revsig (ctrl_t ctrl, const char *username, const char *sigtorev, check_trustdb_stale (ctrl); #endif - /* Search the key; we don't want the whole getkey stuff here. Noet + /* Search the key; we don't want the whole getkey stuff here. Note * that we are looking for the public key here. */ err = quick_find_keyblock (ctrl, username, 0, &kdbhd, &keyblock); if (err) diff --git a/g10/keyedit.h b/g10/keyedit.h index abf7314af..7cb01268e 100644 --- a/g10/keyedit.h +++ b/g10/keyedit.h @@ -57,6 +57,8 @@ void keyedit_quick_set_expire (ctrl_t ctrl, void keyedit_quick_set_primary (ctrl_t ctrl, const char *username, const char *primaryuid); void keyedit_quick_update_pref (ctrl_t ctrl, const char *username); +void keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, + const char *value); void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock, int print_sec); int keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, int rc, kbnode_t keyblock, -- cgit v1.2.3 From 2a0a706eb2133bf58d78a8fefe780fe904fa2e62 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Apr 2024 12:16:20 +0200 Subject: gpg: Mark disabled keys and add show-ownertrust list option. * g10/options.h (LIST_SHOW_OWNERTRUST): New. * g10/keylist.c (print_key_line): Show wonertrust and always show whether a key is disabled. * g10/gpg.c (parse_list_options): Add "show-ownertrust". * g10/gpgv.c (get_ownertrust_string): Add stub. * g10/test-stubs.c (get_ownertrust_string): Add stub. -- Note that in a --with-colons listing the ownertrust has always been emitted and the disabled state is marked in that listing with a special 'D' usage. --- doc/gpg.texi | 5 +++++ g10/gpg.c | 2 ++ g10/gpgv.c | 8 ++++++++ g10/keylist.c | 18 ++++++++---------- g10/options.h | 1 + g10/test-stubs.c | 9 +++++++++ 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index ae1db9f92..8755b9455 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1403,6 +1403,11 @@ give the opposite meaning. The options are: key (@code{E}=encryption, @code{S}=signing, @code{C}=certification, @code{A}=authentication). Defaults to yes. + @item show-ownertrust + @opindex list-options:show-ownertrust + Show the ownertrust value for keys also in the standard key + listing. Defaults to no. + @item show-policy-urls @opindex list-options:show-policy-urls Show policy URLs in the @option{--check-signatures} diff --git a/g10/gpg.c b/g10/gpg.c index 29b7eb55d..bba486aea 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2109,6 +2109,8 @@ parse_list_options(char *str) N_("show preferences")}, {"show-pref-verbose", LIST_SHOW_PREF_VERBOSE, NULL, N_("show preferences")}, + {"show-ownertrust", LIST_SHOW_OWNERTRUST, NULL, + N_("show ownertrust")}, {"show-only-fpr-mbox",LIST_SHOW_ONLY_FPR_MBOX, NULL, NULL}, {"sort-sigs", LIST_SORT_SIGS, NULL, diff --git a/g10/gpgv.c b/g10/gpgv.c index c3b09f752..50ec3917a 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -426,6 +426,14 @@ get_ownertrust (ctrl_t ctrl, PKT_public_key *pk) return TRUST_UNKNOWN; } +const char * +get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create) +{ + (void)ctrl; + (void)pk; + (void)no_create; + return ""; +} /* Stubs: * Because we only work with trusted keys, it does not make sense to diff --git a/g10/keylist.c b/g10/keylist.c index d0ebfc86f..cc1e23d7f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -2520,6 +2520,11 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret) tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0)); } + if (pk->flags.primary && (opt.list_options & LIST_SHOW_OWNERTRUST)) + { + tty_fprintf (fp, " [%s]", get_ownertrust_string (ctrl, pk, 0)); + } + if (pk->flags.revoked) { tty_fprintf (fp, " ["); @@ -2539,21 +2544,14 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret) tty_fprintf (fp, "]"); } -#if 0 - /* I need to think about this some more. It's easy enough to - include, but it looks sort of confusing in the listing... */ - if (opt.list_options & LIST_SHOW_VALIDITY) - { - int validity = get_validity (ctrl, pk, NULL, NULL, 0); - tty_fprintf (fp, " [%s]", trust_value_to_string (validity)); - } -#endif - if (pk->pubkey_algo >= 100) tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo); tty_fprintf (fp, "\n"); + if (pk->flags.primary && pk_is_disabled (pk)) + es_fprintf (es_stdout, " *** %s\n", _("This key has been disabled")); + /* if the user hasn't explicitly asked for human-readable fingerprints, show compact fpr of primary key: */ if (pk->flags.primary && diff --git a/g10/options.h b/g10/options.h index 458180c7a..50fa4ad86 100644 --- a/g10/options.h +++ b/g10/options.h @@ -442,6 +442,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define LIST_SHOW_PREF (1<<14) #define LIST_SHOW_PREF_VERBOSE (1<<15) #define LIST_SHOW_UNUSABLE_SIGS (1<<16) +#define LIST_SHOW_OWNERTRUST (1<<19) #define VERIFY_SHOW_PHOTOS (1<<0) #define VERIFY_SHOW_POLICY_URLS (1<<1) diff --git a/g10/test-stubs.c b/g10/test-stubs.c index d9bead754..00145c12b 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -155,6 +155,15 @@ get_ownertrust_info (ctrl_t ctrl, PKT_public_key *pk, int no_create) return '?'; } +const char * +get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create) +{ + (void)ctrl; + (void)pk; + (void)no_create; + return ""; +} + unsigned int get_ownertrust (ctrl_t ctrl, PKT_public_key *pk) { -- cgit v1.2.3 From 7728a179e0b7b788fb525e4de794b92360f70e66 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Apr 2024 08:04:27 +0200 Subject: tests: Avoid new C23 keyword true. * tests/asschk.c (eval_boolean): s/true/tru/ -- GnuPG-bug-is: 7093 --- tests/asschk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/asschk.c b/tests/asschk.c index c77fd7c23..e278069bf 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -656,13 +656,13 @@ expand_line (char *buffer) static int eval_boolean (const char *cond) { - int true = 1; + int tru = 1; for ( ; *cond == '!'; cond++) - true = !true; + tru = !tru; if (!*cond || (*cond == '0' && !cond[1])) - return !true; - return true; + return !tru; + return tru; } -- cgit v1.2.3 From 3bbfcab606bf9af22f5f453d37a026936855b33d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 May 2024 12:31:33 +0200 Subject: Update NEWS -- --- NEWS | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NEWS b/NEWS index 2182bd225..690dbcf43 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,22 @@ Noteworthy changes in version 2.4.6 (unreleased) ------------------------------------------------ + * gpg: New command --quick-set-ownertrust. [rG967678d972] + + * gpg: Indicate disabled keys in key listings and add list option + "show-ownertrust". [rG2a0a706eb2] + + * gpg: Make sure a DECRYPTION_OKAY is never issued for a bad OCB + tag. [T7042] + + * gpg: Do not allow to accidently set the RENC usage. [T7072] + + * agent: Consider an empty pattern file as valid. [rGc27534de95] + + * agent: Fix error handling of READKEY. [T6012] + + * gpgconf: Check readability of some files with -X and change its + output format. [rG759adb2493] Release-info: https://dev.gnupg.org/T7030 -- cgit v1.2.3 From 0eefa08295b2d19f6f3066b925e001833934a1f0 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 9 Apr 2024 09:24:11 +0900 Subject: gpg: Allow no CRC24 checksum in armor. * g10/armor.c (radix64_read): Detect the end of armor when there is no CRC24 checksum. -- Cherry-pick master commit of: 3a344d6236521d768793e8b34a96a18ce13bab0e GnuPG-bug-id: 7071 Signed-off-by: NIIBE Yutaka --- g10/armor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g10/armor.c b/g10/armor.c index b47c04ab3..81af15339 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1031,10 +1031,10 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, checkcrc++; break; } - else if (afx->dearmor_state && c == '-' + else if (c == '-' && afx->buffer_pos + 8 < afx->buffer_len && !strncmp (afx->buffer, "-----END ", 8)) { - break; /* End in --dearmor mode. */ + break; /* End in --dearmor mode or No CRC. */ } else { log_error(_("invalid radix64 character %02X skipped\n"), c); -- cgit v1.2.3 From 6b2ebc36a932a53e137c429bc1e385054f3bb5cc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 15 Apr 2024 10:23:25 +0900 Subject: scd:openpgp: Robust Data Object handling for constructed case. * scd/app-openpgp.c (get_cached_data): When it comes with its tag and length for the constructed Data Object, remove them. -- Cherry-pick master commit of: 35ef87d8d9db42c3077996317781986a692552cc GnuPG-bug-id: 7058 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1f5d64e6a..fe0855e77 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -409,6 +409,10 @@ get_cached_data (app_t app, int tag, size_t len; struct cache_s *c; int exmode; + int do_constructed = 0; + + if ((tag < 0x0100 && (tag & 0x20)) || (tag >= 0x0100 && (tag & 0x2000))) + do_constructed = 1; *result = NULL; *resultlen = 0; @@ -451,6 +455,52 @@ get_cached_data (app_t app, int tag, err = iso7816_get_data (app_get_slot (app), exmode, tag, &p, &len); if (err) return err; + + /* When Data Object is constructed, when it comes with its tag and + length, remove them before storing it into the cache, because + it's redundant and takes space. This handling also works well + with the card implementation which doesn't include its tag and + length for the DO value returned by GET DATA. */ + if (do_constructed) + { + if (len && tag < 0x0100 && p[0] == tag) + { + if (len >= 2 && p[1] < 0x80 && p[1] == len - 2) + { + len -= 2; + memmove (p, p+2, len); + } + else if (len >= 3 && p[1] == 0x81 && p[2] == len - 3) + { + len -= 3; + memmove (p, p+3, len); + } + else if (len >= 4 && p[1] == 0x82 && ((p[2] << 8) | p[3]) == len - 4) + { + len -= 4; + memmove (p, p+4, len); + } + } + else if (len >= 2 && tag >= 0x0100 && ((p[0] << 8) | p[1]) == tag) + { + if (len >= 3 && p[2] < 0x80 && p[2] == len - 2) + { + len -= 3; + memmove (p, p+3, len); + } + else if (len >= 4 && p[2] == 0x81 && p[3] == len - 3) + { + len -= 4; + memmove (p, p+4, len); + } + else if (len >= 5 && p[2] == 0x82 && ((p[3] << 8) | p[4]) == len - 4) + { + len -= 5; + memmove (p, p+5, len); + } + } + } + if (len) *result = p; *resultlen = len; -- cgit v1.2.3 From 758cd4ccfc1174390ea72bbfc408472659def02a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 May 2024 09:23:43 +0200 Subject: po: Enable Dutch translation -- Although it is largely outdated, it does not harm too much. GnuPG-bug-id: 7120 --- po/LINGUAS | 1 + 1 file changed, 1 insertion(+) diff --git a/po/LINGUAS b/po/LINGUAS index cc9cf27ab..5e26a2c3b 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -16,6 +16,7 @@ id it ja nb +nl pl pt ro -- cgit v1.2.3 From 7f661aa129fd5d57ae5247b01143960c5a3c99a7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 May 2024 09:34:00 +0200 Subject: kbx: Use standard function to setup gcrypt logging in kbxutil. * kbx/kbxutil.c (main): Use setup_libgcrypt_logging. (my_gcry_logger): Remove. --- kbx/kbxutil.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index f5bc8bd77..935dbc735 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -132,28 +132,6 @@ my_strusage( int level ) } -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - (void)dummy; - - /* Map the log levels. */ - switch (level) - { - case GCRY_LOG_CONT: level = GPGRT_LOGLVL_CONT; break; - case GCRY_LOG_INFO: level = GPGRT_LOGLVL_INFO; break; - case GCRY_LOG_WARN: level = GPGRT_LOGLVL_WARN; break; - case GCRY_LOG_ERROR:level = GPGRT_LOGLVL_ERROR; break; - case GCRY_LOG_FATAL:level = GPGRT_LOGLVL_FATAL; break; - case GCRY_LOG_BUG: level = GPGRT_LOGLVL_BUG; break; - case GCRY_LOG_DEBUG:level = GPGRT_LOGLVL_DEBUG; break; - default: level = GPGRT_LOGLVL_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - /* static void */ /* wrong_args( const char *text ) */ @@ -480,8 +458,7 @@ main (int argc, char **argv) /* Make sure that our subsystems are ready. */ i18n_init (); init_common_subsystems (&argc, &argv); - - gcry_set_log_handler (my_gcry_logger, NULL); + setup_libgcrypt_logging (); /*create_dotlock(NULL); register locking cleanup */ -- cgit v1.2.3 From 5355d0885512211d3f9a00001ad73e3c87f54fc7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 May 2024 09:33:24 +0200 Subject: card: Fix compiler warning. * tools/gpg-card.h (opt): Make gpg_program, gpgsm_program, and agent_program const. --- tools/gpg-card.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/gpg-card.h b/tools/gpg-card.h index 8d7975ba9..5b49ef31e 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -34,9 +34,9 @@ struct unsigned int debug; int quiet; int with_colons; - char *gpg_program; - char *gpgsm_program; - char *agent_program; + const char *gpg_program; + const char *gpgsm_program; + const char *agent_program; int autostart; int no_key_lookup; /* Assume --no-key-lookup for "list". */ -- cgit v1.2.3