From 2be53b214d1c9205f5326ca663115200609d8df4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 25 Dec 2023 10:07:07 +0900 Subject: [PATCH 01/45] tools: Fix argparse table of gpgconf. * tools/gpgconf.c (opts): Use ARGPARSE macros. -- GnuPG-bug-id: 6902 Signed-off-by: NIIBE Yutaka --- tools/gpgconf.c | 70 +++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 76bdebf1a..9c4ea1193 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -86,30 +86,31 @@ enum cmd_and_opt_values /* The list of commands and options. */ static gpgrt_opt_t opts[] = { - { 300, NULL, 0, N_("@Commands:\n ") }, + ARGPARSE_group (300, N_("@Commands:\n ")), - { aListComponents, "list-components", 256, N_("list all components") }, - { aCheckPrograms, "check-programs", 256, N_("check all programs") }, - { aListOptions, "list-options", 256, N_("|COMPONENT|list options") }, - { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") }, - { aCheckOptions, "check-options", 256, N_("|COMPONENT|check options") }, - { aApplyDefaults, "apply-defaults", 256, - N_("apply global default values") }, - { aApplyProfile, "apply-profile", 256, - N_("|FILE|update configuration files using FILE") }, - { aListDirs, "list-dirs", 256, - N_("get the configuration directories for @GPGCONF@") }, - { aListConfig, "list-config", 256, - N_("list global configuration file") }, - { aCheckConfig, "check-config", 256, - N_("check global configuration file") }, - { aQuerySWDB, "query-swdb", 256, - N_("query the software version database") }, - { aReload, "reload", 256, N_("reload all or a given component")}, - { aLaunch, "launch", 256, N_("launch a given component")}, - { aKill, "kill", 256, N_("kill a given component")}, - { aCreateSocketDir, "create-socketdir", 256, "@"}, - { aRemoveSocketDir, "remove-socketdir", 256, "@"}, + ARGPARSE_c (aListComponents, "list-components", N_("list all components")), + ARGPARSE_c (aCheckPrograms, "check-programs", N_("check all programs")), + ARGPARSE_c (aListOptions, "list-options", N_("|COMPONENT|list options")), + ARGPARSE_c (aChangeOptions, "change-options", + N_("|COMPONENT|change options")), + ARGPARSE_c (aCheckOptions, "check-options", N_("|COMPONENT|check options")), + ARGPARSE_c (aApplyDefaults, "apply-defaults", + N_("apply global default values")), + ARGPARSE_c (aApplyProfile, "apply-profile", + N_("|FILE|update configuration files using FILE")), + ARGPARSE_c (aListDirs, "list-dirs", + N_("get the configuration directories for @GPGCONF@")), + ARGPARSE_c (aListConfig, "list-config", + N_("list global configuration file")), + ARGPARSE_c (aCheckConfig, "check-config", + N_("check global configuration file")), + ARGPARSE_c (aQuerySWDB, "query-swdb", + N_("query the software version database")), + ARGPARSE_c (aReload, "reload", N_("reload all or a given component")), + ARGPARSE_c (aLaunch, "launch", N_("launch a given component")), + ARGPARSE_c (aKill, "kill", N_("kill a given component")), + ARGPARSE_c (aCreateSocketDir, "create-socketdir", "@"), + ARGPARSE_c (aRemoveSocketDir, "remove-socketdir", "@"), ARGPARSE_c (aShowVersions, "show-versions", ""), ARGPARSE_c (aShowConfigs, "show-configs", ""), /* hidden commands: for debugging */ @@ -117,24 +118,25 @@ static gpgrt_opt_t opts[] = ARGPARSE_c (aDotlockLock, "lock", "@"), ARGPARSE_c (aDotlockUnlock, "unlock", "@"), - { 301, NULL, 0, N_("@\nOptions:\n ") }, + ARGPARSE_header (NULL, N_("@\nOptions:\n ")), - { oOutput, "output", 2, N_("use as output file") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, + ARGPARSE_s_s (oOutput, "output", N_("use as output file")), + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")), + ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), + ARGPARSE_s_n (oRuntime, "runtime", + N_("activate changes at runtime, if possible")), ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), /* hidden options */ - { oHomedir, "homedir", 2, "@" }, - { oBuilddir, "build-prefix", 2, "@" }, - { oNull, "null", 0, "@" }, - { oNoVerbose, "no-verbose", 0, "@"}, + ARGPARSE_s_s (oHomedir, "homedir", "@"), + ARGPARSE_s_s (oBuilddir, "build-prefix", "@"), + ARGPARSE_s_n (oNull, "null", "@"), + ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"), ARGPARSE_s_n (oShowSocket, "show-socket", "@"), ARGPARSE_s_s (oChUid, "chuid", "@"), - ARGPARSE_end(), + ARGPARSE_end () }; From 591a53d716aab90e0b9573ce4a993e4577486e3f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 29 Dec 2023 10:57:26 +0900 Subject: [PATCH 02/45] gpg: Don't call keybox_compress when KEYDB_RESOURCE_FLAG_READONLY. * g10/keydb.c (keydb_add_resource): Check the FLAGS to call keybox_compress. -- GnuPG-bug-id: 6811 Signed-off-by: NIIBE Yutaka --- g10/keydb.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/g10/keydb.c b/g10/keydb.c index d2d085291..ba61f8290 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -746,28 +746,30 @@ keydb_add_resource (const char *url, unsigned int flags) err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { - KEYBOX_HANDLE kbxhd; - if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kb = NULL; /* Not used here */ all_resources[used_resources].token = token; - /* Do a compress run if needed and no other user is - * currently using the keybox. */ - kbxhd = keybox_new_openpgp (token, 0); - if (kbxhd) + if (!(flags & KEYDB_RESOURCE_FLAG_READONLY)) { - if (!keybox_lock (kbxhd, 1, 0)) + KEYBOX_HANDLE kbxhd; + + /* Do a compress run if needed and no other user is + * currently using the keybox. */ + kbxhd = keybox_new_openpgp (token, 0); + if (kbxhd) { - keybox_compress (kbxhd); - keybox_lock (kbxhd, 0, 0); + if (!keybox_lock (kbxhd, 1, 0)) + { + keybox_compress (kbxhd); + keybox_lock (kbxhd, 0, 0); + } + + keybox_release (kbxhd); } - - keybox_release (kbxhd); } - used_resources++; } } From 4c04143d81370d1a1e6006fada1057461b3d3184 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 2 Jan 2024 10:13:16 +0100 Subject: [PATCH 03/45] gpg: Choose key from inserted card over a non-inserted card * g10/call-agent.c (agent_probe_secret_key): Do not return an error but 0. * g10/getkey.c (finish_lookup): Improve the selection of secret keys. -- GnuPG-bug-id: 6831 --- g10/call-agent.c | 13 ++++++++++--- g10/getkey.c | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index c90cdfda5..744c0fcb8 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2226,7 +2226,14 @@ keyinfo_status_cb (void *opaque, const char *line) /* Ask the agent whether a secret key for the given public key is - available. Returns 0 if not available. Bigger value is preferred. */ + * available. Returns 0 if not available. Bigger value is preferred. + * Will never return a value less than 0. Defined return values are: + * 0 := No key or error + * 1 := Key available + * 2 := Key available on a smartcard + * 3 := Key available and passphrase cached + * 4 := Key available on current smartcard + */ int agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) { @@ -2240,11 +2247,11 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) err = start_agent (ctrl, 0); if (err) - return err; + return 0; err = hexkeygrip_from_pk (pk, &hexgrip); if (err) - return err; + return 0; snprintf (line, sizeof line, "KEYINFO %s", hexgrip); xfree (hexgrip); diff --git a/g10/getkey.c b/g10/getkey.c index 21ffd5cfa..d54edcd7f 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3772,6 +3772,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, continue; } + if (secret_key_avail < last_secret_key_avail) + { + if (DBG_LOOKUP) + log_debug ("\tskipping secret key with lower avail\n"); + continue; + } + if (secret_key_avail > last_secret_key_avail) { /* Use this key. */ From 3f8cb9b33949494202fefaa8901ab252467cc1f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Jan 2024 16:29:33 +0100 Subject: [PATCH 04/45] scd: Add support for SCE 7.0 * scd/app-common.h (CARDTYPE_SCE7): New. * scd/app.c (strcardtype): Support it. (atr_to_cardtype): New. (app_new_register): Try to get the cardtype from atr_to_cardtype. * scd/app-piv.c (app_select_piv): Tweak for SCE7. Add general method to construct a S/N from the Card UUID. -- The test cards I have are rsa2048 with X.509 certificates. I don't have the entire chain but loading the certificates work. For testing I created an OpenPGP key from the keys and tested signing and decryption. GnuPG-bug-id: 6919 --- common/util.h | 2 +- scd/app-common.h | 4 ++-- scd/app-piv.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-- scd/app.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 109 insertions(+), 6 deletions(-) diff --git a/common/util.h b/common/util.h index fff2e6e83..803ab3d5c 100644 --- a/common/util.h +++ b/common/util.h @@ -392,7 +392,7 @@ int parse_compatibility_flags (const char *string, unsigned int *flagvar, /*-- Simple replacement functions. */ /* We use the gnupg_ttyname macro to be safe not to run into conflicts - which an extisting but broken ttyname. */ + with an existing but broken ttyname. */ #if !defined(HAVE_TTYNAME) || defined(HAVE_BROKEN_TTYNAME) # define gnupg_ttyname(n) _gnupg_ttyname ((n)) /* Systems without ttyname (W32) will merely return NULL. */ diff --git a/scd/app-common.h b/scd/app-common.h index 988cddf3f..f4035f766 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -56,8 +56,8 @@ typedef enum CARDTYPE_GENERIC = 0, CARDTYPE_GNUK, CARDTYPE_YUBIKEY, - CARDTYPE_ZEITCONTROL - + CARDTYPE_ZEITCONTROL, + CARDTYPE_SCE7 /* G+D SmartCafe Expert 7.0 */ } cardtype_t; /* List of supported card applications. The source code for each diff --git a/scd/app-piv.c b/scd/app-piv.c index c8ef7b43a..dc92bd2e2 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -1,5 +1,5 @@ /* app-piv.c - The OpenPGP card application. - * Copyright (C) 2019, 2020 g10 Code GmbH + * Copyright (C) 2019, 2020, 2024 g10 Code GmbH * * This file is part of GnuPG. * @@ -3642,6 +3642,7 @@ app_select_piv (app_t app) size_t aptlen; const unsigned char *s; size_t n; + void *relptr1 = NULL; /* Note that we select using the AID without the 2 octet version * number. This allows for better reporting of future specs. We @@ -3667,7 +3668,21 @@ app_select_piv (app_t app) s = find_tlv (apt, aptlen, 0x4F, &n); /* Some cards (new Yubikey) return only the PIX, while others - * (old Yubikey, PivApplet) return the RID+PIX. */ + * (old Yubikey, PivApplet) return the RID+PIX. + * Sample APTs: + * Yubikey 5.4.3: 6111 4f06 000010000100 7907 4f05 a000000308 + * SCE7.0-G-F-P : 610f 4f06 001000010000 7905 a000000308 + */ + if (app->card->cardtype == CARDTYPE_SCE7 + && s && apt && aptlen == 17 + && !memcmp (apt, ("\x61\x0f\x4f\x06\x00\x10\x00\x01" + "\x00\x00\x79\x05\xa0\x00\x00\x03\x08"), aptlen)) + { + if (opt.verbose) + log_info ("piv: assuming G&D SCE7.0-G-F-P\n"); + app->appversion = 0x0100; /* Let's assume this. */ + goto apt_checked; + } if (!s || !((n == 6 && !memcmp (s, piv_aid+5, 4)) || (n == 11 && !memcmp (s, piv_aid, 9)))) { @@ -3702,6 +3717,7 @@ app_select_piv (app_t app) goto leave; } + apt_checked: app->app_local = xtrycalloc (1, sizeof *app->app_local); if (!app->app_local) { @@ -3712,6 +3728,41 @@ app_select_piv (app_t app) if (app->card->cardtype == CARDTYPE_YUBIKEY) app->app_local->flags.yubikey = 1; + /* If we don't have a s/n construct it from the CHUID. */ + if (!APP_CARD(app)->serialno) + { + unsigned char *chuid; + size_t chuidlen; + + relptr1 = get_one_do (app, 0x5FC102, &chuid, &chuidlen, NULL); + if (!relptr1) + log_error ("piv: CHUID not found\n"); + else + { + s = find_tlv (chuid, chuidlen, 0x34, &n); + if (!s || n != 16) + { + log_error ("piv: Card UUID %s in CHUID\n", + s? "invalid":"missing"); + if (opt.debug && s) + log_printhex (s, n, "got"); + } + else + { + APP_CARD(app)->serialno = xtrymalloc (n); + if (!APP_CARD(app)->serialno) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (APP_CARD(app)->serialno, s, n); + APP_CARD(app)->serialnolen = n; + err = app_munge_serialno (APP_CARD(app)); + if (err) + goto leave; + } + } + } /* FIXME: Parse the optional and conditional DOs in the APT. */ @@ -3739,6 +3790,7 @@ app_select_piv (app_t app) leave: + xfree (relptr1); xfree (apt); if (err) do_deinit (app); diff --git a/scd/app.c b/scd/app.c index 3686c0f6c..2c92201cf 100644 --- a/scd/app.c +++ b/scd/app.c @@ -112,6 +112,7 @@ strcardtype (cardtype_t t) case CARDTYPE_GNUK: return "gnuk"; case CARDTYPE_YUBIKEY: return "yubikey"; case CARDTYPE_ZEITCONTROL: return "zeitcontrol"; + case CARDTYPE_SCE7: return "smartcafe"; } return "?"; } @@ -549,6 +550,51 @@ card_reset (card_t card) return err; } + +/* Return the card type from (ATR,ATRLEN) or CARDTYPE_GENERIC in case + * of error or if the ATR was not found. If ATR is NULL, SLOT is used + * to retrieve the ATR from the reader. */ +static cardtype_t +atr_to_cardtype (int slot, const unsigned char *atr, size_t atrlen) +{ +#define X(a) ((unsigned char const *)(a)) + static struct + { + size_t atrlen; + unsigned char const *atr; + cardtype_t type; + } atrlist[] = { + { 19, X("\x3b\xf9\x96\x00\x00\x80\x31\xfe" + "\x45\x53\x43\x45\x37\x20\x0f\x00\x20\x46\x4e"), + CARDTYPE_SCE7 }, + { 0 } + }; +#undef X + unsigned char *atrbuf = NULL; + cardtype_t cardtype = 0; + int i; + + if (atr) + { + atrbuf = apdu_get_atr (slot, &atrlen); + if (!atrbuf) + return 0; + atr = atrbuf; + } + + for (i=0; atrlist[i].atrlen; i++) + if (atrlist[i].atrlen == atrlen + && !memcmp (atrlist[i].atr, atr, atrlen)) + { + cardtype = atrlist[i].type; + break; + } + xfree (atrbuf); + return cardtype; +} + + + static gpg_error_t app_new_register (int slot, ctrl_t ctrl, const char *name, int periodical_check_needed) @@ -666,13 +712,16 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, } xfree (buf); } + else + card->cardtype = atr_to_cardtype (slot, NULL, 0); } - else + else /* Got 3F00 */ { unsigned char *atr; size_t atrlen; /* This is heuristics to identify different implementations. */ + /* FIXME: The first two checks are pretty OpenPGP card specific. */ atr = apdu_get_atr (slot, &atrlen); if (atr) { @@ -680,6 +729,8 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, card->cardtype = CARDTYPE_GNUK; else if (atrlen == 21 && atr[7] == 0x75) card->cardtype = CARDTYPE_ZEITCONTROL; + else + card->cardtype = atr_to_cardtype (slot, atr, atrlen); xfree (atr); } } From 2cb97713e9b6590db05894e8015c6cb3d04f4a6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Jan 2024 11:33:51 +0100 Subject: [PATCH 05/45] gpg: Improve error return for --quick-add-subkey and -add-adsk. * g10/keyedit.c (keyedit_quick_addkey): Emit a ERROR status line. (keyedit_quick_addadsk): Ditto. -- GnuPG-bug-id: 6880 --- g10/keyedit.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/g10/keyedit.c b/g10/keyedit.c index 1f614fb7e..a12546f71 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3212,7 +3212,7 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, /* We require a fingerprint because only this uniquely identifies a * key and may thus be used to select a key for unattended subkey * creation. */ - if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd)) + if ((err=find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))) goto leave; if (fix_keyblock (ctrl, &keyblock)) @@ -3224,6 +3224,7 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, if (!opt.verbose) show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); log_error ("%s%s", _("Key is revoked."), "\n"); + err = gpg_error (GPG_ERR_CERT_REVOKED); goto leave; } @@ -3247,6 +3248,8 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, log_info (_("Key not changed so no update needed.\n")); leave: + if (err) + write_status_error ("keyedit.addkey", err); release_kbnode (keyblock); keydb_release (kdbhd); } @@ -3274,7 +3277,7 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) /* We require a fingerprint because only this uniquely identifies a * key and may thus be used to select a key for unattended adsk * adding. */ - if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd)) + if ((err = find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))) goto leave; if (fix_keyblock (ctrl, &keyblock)) @@ -3286,6 +3289,7 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) if (!opt.verbose) show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); log_error ("%s%s", _("Key is revoked."), "\n"); + err = gpg_error (GPG_ERR_CERT_REVOKED); goto leave; } @@ -3310,6 +3314,8 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) } leave: + if (err) + write_status_error ("keyedit.addadsk", err); release_kbnode (keyblock); keydb_release (kdbhd); } From 45f6357881459dcb6b2b78e475d1c136bcb6f606 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 10:09:36 +0100 Subject: [PATCH 06/45] common,w32: Remove duplicated backslashes when setting the homedir. * common/homedir.c (copy_dir_with_fixup) [W32]: Fold double backslashes. -- This is in general no problem but when we hash or compare the directory to test whether tit is the standard home directory, we may use a different socket file and thus a second instance of a daemon. GnuPG-bug-id: 6833 --- NEWS | 3 +++ common/homedir.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/NEWS b/NEWS index 889aff8e1..7b99deeab 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ Noteworthy changes in version 2.4.4 (unreleased) * gpgsm: Support ECDSA in de-vs compliance mode. [T6802] + * dirmngr: Avoid starting a second instance on Windows via GPGME + based launching. [T6833] + * Fix garbled time output in non-English Windows. [T6741] Release-info: https://dev.gnupg.org/T6578 diff --git a/common/homedir.c b/common/homedir.c index 2b99c9bdc..6f99f3eab 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -222,6 +222,10 @@ copy_dir_with_fixup (const char *newdir) { char *result = NULL; char *p; +#ifdef HAVE_W32_SYSTEM + char *p0; + const char *s; +#endif if (!*newdir) return NULL; @@ -253,6 +257,29 @@ copy_dir_with_fixup (const char *newdir) *p-- = 0; } + /* Hack to mitigate badly doubled backslashes. */ + s = result? result : newdir; + if (s[0] == '\\' && s[1] == '\\' && s[2] != '\\') + { + /* UNC (\\Servername\file) or Long UNC (\\?\Servername\file) + * Does not seem to be double quoted. */ + } + else if (strstr (s, "\\\\")) + { + /* Double quotes detected. Fold them into one because that is + * what what Windows does. This way we get a unique hash + * regardless of the number of doubled backslashes. */ + if (!result) + result = xstrdup (newdir); + for (p0=p=result; *p; p++) + { + *p0++ = *p; + while (*p == '\\' && p[1] == '\\') + p++; + } + *p0 = 0; + } + #else /*!HAVE_W32_SYSTEM*/ if (newdir[strlen (newdir)-1] == '/') From 35fd89b168b622966019c07aa619b99c2912534c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 12:51:34 +0100 Subject: [PATCH 07/45] gpgconf: Adjust -X command for the new VERSION file format * tools/gpgconf.c (show_version_gnupg): Read and parse the entire VERSION file. -- GnuPG-bug-id: 6918 --- tools/gpgconf.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 9c4ea1193..b528e329c 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1153,10 +1153,12 @@ get_revision_from_blurb (const char *blurb, int *r_len) static void show_version_gnupg (estream_t fp, const char *prefix) { - char *fname, *p; + char *fname, *p, *p0; size_t n; estream_t verfp; - char line[100]; + char *line = NULL; + size_t line_len = 0; + ssize_t length; es_fprintf (fp, "%s%sGnuPG %s (%s)\n%s%s\n", prefix, *prefix?"":"* ", gpgrt_strusage (13), BUILD_REVISION, prefix, gpgrt_strusage (17)); @@ -1175,20 +1177,46 @@ show_version_gnupg (estream_t fp, const char *prefix) verfp = es_fopen (fname, "r"); if (!verfp) es_fprintf (fp, "%s[VERSION file not found]\n", prefix); - else if (!es_fgets (line, sizeof line, verfp)) - es_fprintf (fp, "%s[VERSION file is empty]\n", prefix); else { - trim_spaces (line); - for (p=line; *p; p++) - if (*p < ' ' || *p > '~' || *p == '[') - *p = '?'; - es_fprintf (fp, "%s%s\n", prefix, line); + int lnr = 0; + + p0 = NULL; + while ((length = es_read_line (verfp, &line, &line_len, NULL))>0) + { + lnr++; + trim_spaces (line); + if (lnr == 1 && *line != '[') + { + /* Old file format where we look only at the + * first line. */ + p0 = line; + break; + } + else if (!strncmp (line, "version=", 8)) + { + p0 = line + 8; + break; + } + } + if (length < 0 || es_ferror (verfp)) + es_fprintf (fp, "%s[VERSION file read error]\n", prefix); + else if (p0) + { + for (p=p0; *p; p++) + if (*p < ' ' || *p > '~' || *p == '[') + *p = '?'; + es_fprintf (fp, "%s%s\n", prefix, p0); + } + else + es_fprintf (fp, "%s[VERSION file is empty]\n", prefix); + + es_fclose (verfp); } - es_fclose (verfp); } xfree (fname); } + xfree (line); #ifdef HAVE_W32_SYSTEM { From 880dde8e5bafb1efc6b3b1b64ccc8fd43a46f775 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 15:26:47 +0100 Subject: [PATCH 08/45] scd:p15: Allow PIN verification and decryption for CVISION cards. * scd/app-p15.c (CARD_PRODUCT_CVISION): New. (IS_STARCOS_3): New. (read_p15_info): Detect this product. (prepare_verify_pin): Add special handling for this product. (do_decipher): Use dedicated MSE for Starcos 3 cards. -- To check the verification run gpg-card verify User_PIN For our test cards the "Benutzer-PIN" must be given. For decryption tests gpgsm can be used; --always-trust helps to avoid chain issues. --- scd/app-p15.c | 70 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 8edd737a6..e5edc5308 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -91,7 +91,8 @@ typedef enum CARD_PRODUCT_DTRUST3, /* D-Trust GmbH (bundesdruckerei.de) */ CARD_PRODUCT_DTRUST4, CARD_PRODUCT_GENUA, /* GeNUA mbH */ - CARD_PRODUCT_NEXUS /* Technology Nexus */ + CARD_PRODUCT_NEXUS, /* Technology Nexus */ + CARD_PRODUCT_CVISION /* Cryptovision GmbH */ } card_product_t; @@ -143,6 +144,8 @@ static struct #define IS_CARDOS_5(a) ((a)->app_local->card_type == CARD_TYPE_CARDOS_50 \ || (a)->app_local->card_type == CARD_TYPE_CARDOS_53 \ || (a)->app_local->card_type == CARD_TYPE_CARDOS_54) +#define IS_STARCOS_3(a) ((a)->app_local->card_type == CARD_TYPE_STARCOS_32) + /* The default PKCS-15 home DF */ #define DEFAULT_HOME_DF 0x5015 @@ -532,8 +535,6 @@ struct app_local_s /*** Local prototypes. ***/ static gpg_error_t select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen); -static gpg_error_t select_df_by_path (app_t app, const unsigned short *path, - size_t pathlen); static gpg_error_t keygrip_from_prkdf (app_t app, prkdf_object_t prkdf); static gpg_error_t readcert_by_cdf (app_t app, cdf_object_t cdf, unsigned char **r_cert, size_t *r_certlen); @@ -571,6 +572,7 @@ cardproduct2str (card_product_t cardproduct) case CARD_PRODUCT_DTRUST4: return "D-Trust 4.1/4.4"; case CARD_PRODUCT_GENUA: return "GeNUA"; case CARD_PRODUCT_NEXUS: return "Nexus"; + case CARD_PRODUCT_CVISION: return "Cryptovison"; } return ""; } @@ -803,7 +805,7 @@ select_by_path (app_t app, const unsigned short *path, size_t pathlen, log_debug ("%s: path=", __func__); for (j=0; j < pathlen; j++) log_printf ("%s%04hX", j? "/":"", path[j]); - log_printf ("%s\n",expect_df?" (DF requested)":""); + log_printf ("%s", expect_df?" (DF requested)":""); log_printf ("%s\n",app->app_local->direct_path_selection?" (direct)":""); } @@ -867,11 +869,13 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) } +#if 0 /* Currently not used. */ static gpg_error_t select_df_by_path (app_t app, const unsigned short *path, size_t pathlen) { return select_by_path (app, path, pathlen, 1); } +#endif /* Parse a cert Id string (or a key Id string) and return the binary @@ -3611,6 +3615,7 @@ read_p15_info (app_t app) gpg_error_t err; prkdf_object_t prkdf; unsigned int flag; + const char *manu; err = read_ef_tokeninfo (app); if (err) @@ -3631,18 +3636,22 @@ read_p15_info (app_t app) release_lists (app); /* Set a product type from the manufacturer_id. */ - if (IS_CARDOS_5 (app) && app->app_local->manufacturer_id) + if (!(manu = app->app_local->manufacturer_id) || !*manu) + ; /* No manufacturer_id. */ + else if (app->app_local->card_product) + ; /* Already set. */ + else if (IS_CARDOS_5 (app)) { - const char *manu = app->app_local->manufacturer_id; - - if (app->app_local->card_product) - ; /* Already set. */ - else if (!ascii_strcasecmp (manu, "GeNUA mbH")) + if (!ascii_strcasecmp (manu, "GeNUA mbH")) app->app_local->card_product = CARD_PRODUCT_GENUA; else if (!ascii_strcasecmp (manu, "Technology Nexus")) app->app_local->card_product = CARD_PRODUCT_NEXUS; } - + else if (app->app_local->card_type == CARD_TYPE_STARCOS_32) + { + if (strstr (manu, "cryptovision")) + app->app_local->card_product = CARD_PRODUCT_CVISION; + } /* Read the ODF so that we know the location of all directory files. */ @@ -5053,11 +5062,18 @@ prepare_verify_pin (app_t app, const char *keyref, log_error ("p15: error selecting D-TRUST's AID for key %s: %s\n", keyref, gpg_strerror (err)); } - else if (prkdf && app->app_local->card_type == CARD_TYPE_STARCOS_32) + else if (app->app_local->card_product == CARD_PRODUCT_CVISION) { - err = select_df_by_path (app, prkdf->path, prkdf->pathlen); + /* According to our protocol analysis we need to select the + * PKCS#15 AID here. The traces actually show that this is done + * two times but that looks more like a bug. Before that the + * master file needs to be selected. */ + err = iso7816_select_mf (app_get_slot (app)); + if (!err) + err = iso7816_select_application (app_get_slot (app), + pkcs15_aid, sizeof pkcs15_aid, 0); if (err) - log_error ("p15: error selecting file for key %s: %s\n", + log_error ("p15: error selecting PKCS#15 AID for key %s: %s\n", keyref, gpg_strerror (err)); } else if (prkdf) @@ -5862,6 +5878,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, prkdf_object_t prkdf; /* The private key object. */ aodf_object_t aodf; /* The associated authentication object. */ int exmode, le_value, padind; + int i; (void)ctrl; (void)r_info; @@ -5960,10 +5977,33 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, 0xF3, 0x31, NULL, 0); } } + else if (prkdf->key_reference_valid && IS_STARCOS_3 (app)) + { + unsigned char mse[9]; + + i = 0; + if (prkdf->is_ecc) + { + log_info ("Note: ECC is not yet implemented for Starcos 3 cards\n"); + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } + else + { + mse[i++] = 0x84; /* Key reference. */ + mse[i++] = 1; + mse[i++] = prkdf->key_reference; + mse[i++] = 0x89; /* Algorithm reference (BCD encoded). */ + mse[i++] = 2; + mse[i++] = 0x11; /* RSA no padding (1 1 3 0). */ + mse[i++] = 0x30; + log_assert (i <= DIM(mse)); + err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB8, + mse, i); + } + } else if (prkdf->key_reference_valid) { unsigned char mse[9]; - int i; /* Note: This works with CardOS but the D-Trust card has the * problem that the next created signature would be broken. */ From 4ca017e43bb296b937c792c28cd500baa1f8dc14 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 17:25:34 +0100 Subject: [PATCH 09/45] gpg: Print a useful error id SKI algo 253 is found. * g10/parse-packet.c (parse_key): Detect the SKI algo 253. -- As long as we have not yet implemented this we should at least be able to detect this case. --- g10/parse-packet.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index a033732ec..aa6bac9da 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -2684,7 +2684,16 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { ski->is_protected = 1; ski->s2k.count = 0; - if (ski->algo == 254 || ski->algo == 255) + if (ski->algo == 253) + { + if (list_mode) + es_fprintf (listfp, + "\tS2K pseudo algo %d is not yet supported\n", + ski->algo); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + else if (ski->algo == 254 || ski->algo == 255) { if (pktlen < 3) { From 6233a17ac99deb8d246458380813b621df2609bf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 19:52:04 +0100 Subject: [PATCH 10/45] g13: New option --no-mount. * g13/g13.c (oNoMount): New. (opts): Add --no-mount. (main): Implement this. * g13/g13-common.h (opt): Add field no_mount. * common/status.h (STATUS_PLAINDEV): New. * g13/sh-cmd.c (has_option): Uncomment. (cmd_mount): Add option --no-mount and pass down. * g13/sh-dmcrypt.c (sh_dmcrypt_mount_container): Add arg nomount and emit PLAINDEV status line. (sh_dmcrypt_umount_container): Rund findmnt before umount. -- This option can be used to decrypt a device but not to mount it. For example to run fsck first. A command or option to run fsck before a mount will eventually be added. The use of findmnt is needed so that we can easily remove a device which has not been mounted. --- common/status.h | 1 + g13/call-syshelp.c | 14 +++++++--- g13/g13-common.h | 2 ++ g13/g13-syshelp.c | 2 +- g13/g13-syshelp.h | 2 +- g13/g13.c | 4 +++ g13/sh-cmd.c | 30 ++++++++++++---------- g13/sh-dmcrypt.c | 64 ++++++++++++++++++++++++++++------------------ 8 files changed, 76 insertions(+), 43 deletions(-) diff --git a/common/status.h b/common/status.h index e4cf23ee1..d249174d1 100644 --- a/common/status.h +++ b/common/status.h @@ -152,6 +152,7 @@ enum STATUS_TRUNCATED, STATUS_MOUNTPOINT, STATUS_BLOCKDEV, + STATUS_PLAINDEV, /* The decrypted virtual device. */ STATUS_PINENTRY_LAUNCHED, diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index 54dca04ec..c4bc48172 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -433,10 +433,15 @@ static gpg_error_t mount_status_cb (void *opaque, const char *line) { struct mount_parm_s *parm = opaque; + const char *s; - /* Nothing right now. */ (void)parm; - (void)line; + + if ((s=has_leading_keyword (line, "PLAINDEV"))) + { + if (opt.verbose || opt.no_mount) + log_info ("Device: %s\n", s); + } return 0; } @@ -497,7 +502,10 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, { ref_tupledesc (tuples); parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen); - err = assuan_transact (ctx, "MOUNT dm-crypt", + err = assuan_transact (ctx, + (opt.no_mount + ? "MOUNT --no-mount dm-crypt" + : "MOUNT dm-crypt"), NULL, NULL, mount_inq_cb, &parm, mount_status_cb, &parm); diff --git a/g13/g13-common.h b/g13/g13-common.h index 42b8deebd..539c091aa 100644 --- a/g13/g13-common.h +++ b/g13/g13-common.h @@ -81,6 +81,8 @@ struct /* Name of the output file - FIXME: what is this? */ const char *outfile; + int no_mount; /* Stop right before mounting a device. */ + } opt; diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index 6a4d3a446..0de1cf15d 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -584,7 +584,7 @@ g13_syshelp_i_know_what_i_am_doing (void) if (gnupg_access (fname, F_OK)) { log_info ("*******************************************************\n"); - log_info ("* The G13 support for DM-Crypt is new and not matured.\n"); + log_info ("* The G13 support for DM-Crypt is not yet widely used.\n"); log_info ("* Bugs or improper use may delete all your disks!\n"); log_info ("* To confirm that you are ware of this risk, create\n"); log_info ("* the file '%s'.\n", fname); diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h index 0243166ba..10b529fb1 100644 --- a/g13/g13-syshelp.h +++ b/g13/g13-syshelp.h @@ -85,7 +85,7 @@ gpg_error_t sh_is_empty_partition (const char *name); gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp); gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, - tupledesc_t keyblob); + tupledesc_t keyblob, int nomount); gpg_error_t sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname); gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname); gpg_error_t sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname, diff --git a/g13/g13.c b/g13/g13.c index 2bbb453eb..cb1880f80 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -103,6 +103,7 @@ enum cmd_and_opt_values { oWithColons, oDryRun, oNoDetach, + oNoMount, oNoRandomSeedFile, oFakedSystemTime @@ -137,6 +138,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write log output to FILE")), ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_n (oNoMount, "no-mount", N_("stop right before running mount")), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), @@ -518,6 +520,8 @@ main (int argc, char **argv) case oNoDetach: /*nodetach = 1; */break; + case oNoMount: opt.no_mount = 1; break; + case oDebug: if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags)) { diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index 791e3b7f4..1d21f6cc4 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -83,17 +83,17 @@ skip_options (const char *line) /* Check whether the option NAME appears in LINE. */ -/* static int */ -/* has_option (const char *line, const char *name) */ -/* { */ -/* const char *s; */ -/* int n = strlen (name); */ +static int +has_option (const char *line, const char *name) +{ + const char *s; + int n = strlen (name); -/* s = strstr (line, name); */ -/* if (s && s >= skip_options (line)) */ -/* return 0; */ -/* return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */ -/* } */ + s = strstr (line, name); + if (s && s >= skip_options (line)) + return 0; + return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); +} /* Helper to print a message while leaving a command. */ @@ -431,10 +431,11 @@ cmd_getkeyblob (assuan_context_t ctx, char *line) static const char hlp_mount[] = - "MOUNT \n" + "MOUNT [--no-mount] \n" "\n" "Mount an encrypted partition on the current device.\n" - " must be \"dm-crypt\" for now."; + " must be \"dm-crypt\" for now. Option --no-mount\n" + "stops right before calling the mount command.\n"; static gpg_error_t cmd_mount (assuan_context_t ctx, char *line) { @@ -443,6 +444,9 @@ cmd_mount (assuan_context_t ctx, char *line) unsigned char *keyblob = NULL; size_t keybloblen; tupledesc_t tuples = NULL; + int nomount; + + nomount = has_option (line, "--no-mount"); line = skip_options (line); @@ -493,7 +497,7 @@ cmd_mount (assuan_context_t ctx, char *line) err = sh_dmcrypt_mount_container (ctrl, ctrl->server_local->devicename, - tuples); + tuples, nomount); leave: destroy_tupledesc (tuples); diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index 6f7173ec5..c3b5a6d77 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -220,7 +220,7 @@ mk_setup_area_prefix (size_t *r_length) } -/* Create a new g13 styloe DM-Crypt container on devoce DEVNAME. */ +/* Create a new g13 style DM-Crypt container on device DEVNAME. */ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) { @@ -538,10 +538,11 @@ sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) /* Mount a DM-Crypt container on device DEVNAME taking keys and other - * meta data from KEYBLOB. */ + * meta data from KEYBLOB. If NOMOUNT is set the actual mount command + * is not run. */ gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, - tupledesc_t keyblob) + tupledesc_t keyblob, int nomount) { gpg_error_t err; char *targetname_abs = NULL; @@ -696,8 +697,10 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, xfree (result); result = NULL; + g13_status (ctrl, STATUS_PLAINDEV, targetname_abs, NULL); + /* Mount if a mountpoint has been given. */ - if (ctrl->devti->mountpoint) + if (!nomount && ctrl->devti->mountpoint) { const char *argv[3]; @@ -766,32 +769,43 @@ sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname) goto leave; } - /* Run the regular umount command. */ + /* Run the regular umount command but first test with findmnt. */ { - const char *argv[2]; + const char *argv[3]; argv[0] = targetname_abs; argv[1] = NULL; - log_debug ("now running \"umount %s\"\n", targetname_abs); - err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); - } - if (err) - { - log_error ("error running umount: %s\n", gpg_strerror (err)); - if (1) - { - /* Try to show some info about processes using the partition. */ - const char *argv[3]; + log_debug ("now running \"findmnt %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/findmnt", argv, NULL, &result, NULL); - argv[0] = "-mv"; - argv[1] = targetname_abs; - argv[2] = NULL; - gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); - } - goto leave; - } - if (result && *result) /* (We should not see output to stdout). */ - log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + if (err) + log_info ("Note: device was not mounted\n"); + else + { + xfree (result); + result = NULL; + + argv[0] = targetname_abs; + argv[1] = NULL; + log_debug ("now running \"umount %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); + if (err) + { + log_error ("error running umount: %s\n", gpg_strerror (err)); + if (1) + { + /* Try to show some info about processes using the partition. */ + argv[0] = "-mv"; + argv[1] = targetname_abs; + argv[2] = NULL; + gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); + } + goto leave; + } + if (result && *result) /* (We should not see output to stdout). */ + log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + } + } xfree (result); result = NULL; From 275ced5067dabba3028192e50896f2a0e4a4d13c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 10 Jan 2024 14:35:26 +0100 Subject: [PATCH 11/45] scd:p15: Allow signing for CVISION cards * scd/app-p15.c (do_sign): Add code for Starcos 3.2 and the CVISION product. -- The code for the Starcos cards has been implemented according to the 3.52 manual However, this does not work with my test cards. Protocol analysis shows that decryption can be used for the cryptovision product. Thus we do it the same for now. --- scd/app-p15.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index e5edc5308..2bb90beaa 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -5513,6 +5513,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, unsigned char oidbuf[64]; size_t oidbuflen; size_t n; + int i; unsigned char *indata_buffer = NULL; /* Malloced helper. */ (void)ctrl; @@ -5610,7 +5611,6 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, { unsigned int framelen; unsigned char *frame; - int i; framelen = (prkdf->keynbits+7) / 8; if (!framelen) @@ -5685,6 +5685,23 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, memcpy (frame, indata, indatalen); framelen = indatalen; } + else if (hashalgo && IS_STARCOS_3 (app) + && app->app_local->card_product != CARD_PRODUCT_CVISION) + { + /* For Starcos we need the plain hash w/o the prefix. */ + /* Note: This has never been tested because the cvision + * sample cards seem not to work this way. */ + if (indatalen != oidbuflen + digestlen + || memcmp (indata, oidbuf, oidbuflen)) + { + log_error ("p15: non-matching input data for Starcos:" + " hash=%d len=%zu\n", hashalgo, indatalen); + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + framelen = indatalen - oidbuflen; + memcpy (frame, (const char*)indata + oidbuflen, framelen); + } else { n = 0; @@ -5774,7 +5791,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, else { /* The D-TRUST Card 4.x doesn't support setting a security - * environment, at least as specified in the specs. Insted a + * environment, at least as specified in the specs. Instead a * predefined security environment has to be loaded depending on the * cipher and message digest used. The spec states SE-ID 0x25 for * SHA256, 0x26 for SHA384 and 0x27 for SHA512, when using PKCS#1 @@ -5788,6 +5805,61 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, 0xf3, 0x25, NULL, 0); } } + else if (app->app_local->card_product == CARD_PRODUCT_CVISION) + { + /* I can't make the Starcos 3.2 work the correct way, so let's + * make them work in the same way the cryptovision product seems + * to do it: Use the plain RSA decryption instead. */ + unsigned char mse[9]; + + i = 0; + mse[i++] = 0x84; /* Key reference. */ + mse[i++] = 1; + mse[i++] = prkdf->key_reference; + mse[i++] = 0x89; /* Algorithm reference (BCD encoded). */ + mse[i++] = 2; + mse[i++] = 0x11; /* RSA no padding (1 1 3 0). */ + mse[i++] = 0x30; + log_assert (i <= DIM(mse)); + err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB8, + mse, i); + } + else if (prkdf->key_reference_valid && IS_STARCOS_3 (app)) + { + unsigned char mse[9]; + + i = 0; + if (prkdf->is_ecc) + { + log_info ("Note: ECC is not yet implemented for Starcos 3 cards\n"); + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } + else + { + err = 0; + mse[i++] = 0x84; /* Key reference. */ + mse[i++] = 1; + mse[i++] = prkdf->key_reference; + mse[i++] = 0x89; /* Algorithm reference (BCD encoded). */ + mse[i++] = 3; + mse[i++] = 0x13; /* RSA PKCS#1 (standard) (1 3 2 3). */ + mse[i++] = 0x23; + switch (hashalgo) + { + case GCRY_MD_SHA1: mse[i++] = 0x10; break; + case GCRY_MD_RMD160: mse[i++] = 0x20; break; + case GCRY_MD_SHA256: mse[i++] = 0x30; break; + case GCRY_MD_SHA384: mse[i++] = 0x40; break; + case GCRY_MD_SHA512: mse[i++] = 0x50; break; + case GCRY_MD_SHA224: mse[i++] = 0x60; break; + default: err = gpg_error (GPG_ERR_DIGEST_ALGO); break; + } + log_assert (i <= DIM(mse)); + if (!err) + err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB6, + mse, i); + } + } else if (prkdf->key_reference_valid) { unsigned char mse[3]; @@ -5817,9 +5889,14 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, le_value = 0; } - err = iso7816_compute_ds (app_get_slot (app), + if (app->app_local->card_product == CARD_PRODUCT_CVISION) + err = iso7816_decipher (app_get_slot (app), exmode, indata, indatalen, - le_value, outdata, outdatalen); + le_value, 0, outdata, outdatalen); + else + err = iso7816_compute_ds (app_get_slot (app), + exmode, indata, indatalen, + le_value, outdata, outdatalen); leave: xfree (indata_buffer); From b7f45ee6adbc1a2d22b596aada2e8ca8b1e1c82b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 10 Jan 2024 17:18:34 +0100 Subject: [PATCH 12/45] gpg: Allow to create revocations even with non-compliant algos. * g10/sign.c (do_sign): Skip compliance check for revocation certs. -- It just does not make sense to inhibit the creation of revocations depending on the compliance mode. We do this only for key revocation but not for another kind of revocation because the rationale for uid or subkey revocation is more complicated to explain. --- g10/sign.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/g10/sign.c b/g10/sign.c index d6ab396af..b00bdfefd 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -444,8 +444,9 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig, goto leave; } - /* Check compliance. */ - if (! gnupg_digest_is_allowed (opt.compliance, 1, mdalgo)) + /* Check compliance but always allow for key revocations. */ + if (!IS_KEY_REV (sig) + && ! gnupg_digest_is_allowed (opt.compliance, 1, mdalgo)) { log_error (_("digest algorithm '%s' may not be used in %s mode\n"), gcry_md_algo_name (mdalgo), @@ -454,9 +455,10 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig, goto leave; } - if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, - pksk->pubkey_algo, 0, - pksk->pkey, nbits_from_pk (pksk), NULL)) + if (!IS_KEY_REV (sig) + && ! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, + pksk->pubkey_algo, 0, + pksk->pkey, nbits_from_pk (pksk), NULL)) { log_error (_("key %s may not be used for signing in %s mode\n"), keystr_from_pk (pksk), From 8dfbad0c416ebeaf838d06d50708b8b21f7a8e4a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Jan 2024 09:08:54 +0100 Subject: [PATCH 13/45] gpg: Fix regression in the Revoker keyword of the parmeter file. * g10/keygen.c (parse_revocation_key): Actually allow for v4 fingerprints. -- Note that the use of the parameter file is deprecated. GnuPG-bug-id: 6923 --- doc/gpg.texi | 7 ++++--- g10/keygen.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index b666a72bc..7e51aff6f 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -4638,9 +4638,10 @@ in the @option{--edit-key} menu. @item Revoker: @var{algo}:@var{fpr} [sensitive] Add a designated revoker to the generated key. Algo is the public key algorithm of the designated revoker (i.e. RSA=1, DSA=17, etc.) -@var{fpr} is the fingerprint of the designated revoker. The optional -@samp{sensitive} flag marks the designated revoker as sensitive -information. Only v4 keys may be designated revokers. +@var{fpr} is the fingerprint of the designated revoker. @var{fpr} may +not contain spaces or colons. The optional @samp{sensitive} flag +marks the designated revoker as sensitive information. Only v4 and v5 +keys may be designated revokers. @item Keyserver: @var{string} This is an optional parameter that specifies the preferred keyserver diff --git a/g10/keygen.c b/g10/keygen.c index 2f8528278..3efdf94a3 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -4079,7 +4079,7 @@ parse_revocation_key (const char *fname, pn++; - for(i=0;i Date: Thu, 11 Jan 2024 15:28:33 +0100 Subject: [PATCH 14/45] doc: Document the gpgconf --unlock command. * tools/gpgconf.c (main): Fix usage message. -- GnuPG-bug-id: 6838 --- doc/tools.texi | 13 ++++++++++++- tools/gpgconf.c | 8 ++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/tools.texi b/doc/tools.texi index a1c161c3a..80ec7c6fe 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -387,12 +387,23 @@ daemons. Note that as of now reload and kill have the same effect for Create a directory for sockets below /run/user or /var/run/user. This is command is only required if a non default home directory is used and the /run based sockets shall be used. For the default home -directory GnUPG creates a directory on the fly. +directory GnuPG creates a directory on the fly. @item --remove-socketdir @opindex remove-socketdir Remove a directory created with command @option{--create-socketdir}. +@item --unlock @var{name} +@itemx --lock @var{name} +Remove a stale lock file hold for @file{file}. The file is +expected in the current GnuPG home directory. This command is usually +not required because GnuPG is able to detect and remove stale lock +files. Before using the command make sure that the file protected by +the lock file is actually not in use. The lock command may be used to +lock an accidently removed lock file. Note that the commands have no +effect on Windows because the mere existence of a lock file does not +mean that the lock is active. + @end table diff --git a/tools/gpgconf.c b/tools/gpgconf.c index b528e329c..6a5add42b 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1074,12 +1074,12 @@ main (int argc, char **argv) #if !defined(HAVE_W32_SYSTEM) if (!fname) { - es_fprintf (es_stderr, "usage: %s [options] lock|unlock NAME", - GPGCONF_NAME); + es_fprintf (es_stderr, "usage: %s --%slock NAME", + GPGCONF_NAME, cmd==aDotlockUnlock?"un":""); es_putc ('\n', es_stderr); - es_fputs (_("Need one NAME argument"), es_stderr); + es_fputs ("Need name of file protected by the lock", es_stderr); es_putc ('\n', es_stderr); - gpgconf_failure (GPG_ERR_USER_2); + gpgconf_failure (GPG_ERR_SYNTAX); } else { From bbad0a2644d18c2d7867c7862006c0d011fbdea7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Jan 2024 15:54:27 +0100 Subject: [PATCH 15/45] gpg: Improve error message for expired default keys. * g10/getkey.c (parse_def_secret_key): Track reason for skipping keys. -- GnuPG-bug-id: 4704 --- g10/getkey.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/g10/getkey.c b/g10/getkey.c index d54edcd7f..b959d77c7 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2009,8 +2009,9 @@ parse_def_secret_key (ctrl_t ctrl) { gpg_error_t err; KEYDB_SEARCH_DESC desc; - KBNODE kb; - KBNODE node; + kbnode_t kb; + kbnode_t node; + int any_revoked, any_expired, any_disabled; err = classify_user_id (t->d, &desc, 1); if (err) @@ -2053,6 +2054,7 @@ parse_def_secret_key (ctrl_t ctrl) merge_selfsigs (ctrl, kb); + any_revoked = any_expired = any_disabled = 0; err = gpg_error (GPG_ERR_NO_SECKEY); node = kb; do @@ -2062,6 +2064,7 @@ parse_def_secret_key (ctrl_t ctrl) /* Check if the key is valid. */ if (pk->flags.revoked) { + any_revoked = 1; if (DBG_LOOKUP) log_debug ("not using %s as default key, %s", keystr_from_pk (pk), "revoked"); @@ -2069,6 +2072,7 @@ parse_def_secret_key (ctrl_t ctrl) } if (pk->has_expired) { + any_expired = 1; if (DBG_LOOKUP) log_debug ("not using %s as default key, %s", keystr_from_pk (pk), "expired"); @@ -2076,6 +2080,7 @@ parse_def_secret_key (ctrl_t ctrl) } if (pk_is_disabled (pk)) { + any_disabled = 1; if (DBG_LOOKUP) log_debug ("not using %s as default key, %s", keystr_from_pk (pk), "disabled"); @@ -2096,9 +2101,22 @@ parse_def_secret_key (ctrl_t ctrl) { if (! warned && ! opt.quiet) { + gpg_err_code_t ec; + + /* Try to get a better error than no secret key if we + * only know that the public key is not usable. */ + if (any_revoked) + ec = GPG_ERR_CERT_REVOKED; + else if (any_expired) + ec = GPG_ERR_KEY_EXPIRED; + else if (any_disabled) + ec = GPG_ERR_KEY_DISABLED; + else + ec = GPG_ERR_NO_SECKEY; + log_info (_("Warning: not using '%s' as default key: %s\n"), - t->d, gpg_strerror (GPG_ERR_NO_SECKEY)); - print_reported_error (err, GPG_ERR_NO_SECKEY); + t->d, gpg_strerror (ec)); + print_reported_error (err, ec); } } else From 5a6df94a9a4b2a2c16c5184c37e215302574b90b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Jan 2024 10:42:05 +0100 Subject: [PATCH 16/45] speedo: Patch ELF binaries to use built libraries * build-aux/speedo.mk: Remove GUI stuff. Add patchelf feature. * Makefile.am (speedo): New target. -- GnuPG-bug-id: 6710 --- AUTHORS | 2 +- Makefile.am | 7 +- README | 17 +-- build-aux/speedo.mk | 251 ++++++++--------------------------------- common/w32info-rc.h.in | 2 +- configure.ac | 2 +- tests/cms/Makefile.am | 1 + 7 files changed, 66 insertions(+), 216 deletions(-) diff --git a/AUTHORS b/AUTHORS index bd1d528e3..44a755333 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,7 +16,7 @@ List of Copyright holders ========================= Copyright (C) 1997-2019 Werner Koch - Copyright (C) 2003-2023 g10 Code GmbH + Copyright (C) 2003-2024 g10 Code GmbH Copyright (C) 1994-2021 Free Software Foundation, Inc. Copyright (C) 2002 Klarälvdalens Datakonsult AB Copyright (C) 1995-1997, 2000-2007 Ulrich Drepper diff --git a/Makefile.am b/Makefile.am index 1cd009811..67ee98e20 100644 --- a/Makefile.am +++ b/Makefile.am @@ -191,7 +191,7 @@ endif gen_start_date = 2011-12-01T06:00:00 -.PHONY: gen-ChangeLog +.PHONY: gen-ChangeLog stowinstall speedo gen-ChangeLog: if test -e $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ @@ -207,6 +207,11 @@ gen-ChangeLog: stowinstall: $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/gnupg + +speedo: + $(MAKE) -f $(top_srcdir)/build-aux/speedo.mk native SELFCHECK=0 + + TESTS_ENVIRONMENT = \ LC_ALL=C \ EXEEXT=$(EXEEXT) \ diff --git a/README b/README index 8fc906bb5..02e0fedd4 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ Copyright 1997-2019 Werner Koch Copyright 1998-2021 Free Software Foundation, Inc. - Copyright 2003-2023 g10 Code GmbH + Copyright 2003-2024 g10 Code GmbH * INTRODUCTION @@ -40,7 +40,7 @@ Several other standard libraries are also required. The configure script prints diagnostic messages if one of these libraries is not - available and a feature will not be available.. + available and a feature will not be available. You also need the Pinentry package for most functions of GnuPG; however it is not a build requirement. Pinentry is available at @@ -80,15 +80,16 @@ to view the directories used by GnuPG. +** Quick build method on Unix + To quickly build all required software without installing it, the - Speedo method may be used: + Speedo target may be used: - cd build - make -f ../build-aux/speedo.mk native + make speedo - This method downloads all required libraries and does a native build - of GnuPG to PLAY/inst/. GNU make is required and you need to set - LD_LIBRARY_PATH to $(pwd)/PLAY/inst/lib to test the binaries. + This target downloads all required libraries and does a native build + of GnuPG to PLAY/inst/. GNU make and the patchelf tool are + required. Follow the instructions give at the end of the make run. ** Specific build problems on some machines: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 7777411e2..0cefebed9 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -94,16 +94,15 @@ # We need to know our own name. SPEEDO_MK := $(realpath $(lastword $(MAKEFILE_LIST))) -.PHONY : help native native-gui w32-installer w32-source w32-wixlib -.PHONY : git-native git-native-gui git-w32-installer git-w32-source -.PHONY : this-native this-native-gui this-w32-installer this-w32-source +.PHONY : help native w32-installer w32-source w32-wixlib +.PHONY : git-native git-w32-installer git-w32-source +.PHONY : this-native this-w32-installer this-w32-source help: @echo 'usage: make -f speedo.mk TARGET' @echo ' with TARGET being one of:' @echo ' help This help' @echo ' native Native build of the GnuPG core' - @echo ' native-gui Ditto but with pinentry and GPA' @echo ' w32-installer Build a Windows installer' @echo ' w32-source Pack a source archive' @echo ' w32-release Build a Windows release' @@ -148,66 +147,54 @@ help-wixlib: SPEEDOMAKE := $(MAKE) -f $(SPEEDO_MK) UPD_SWDB=1 native: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=release WITH_GUI=0 all + $(SPEEDOMAKE) TARGETOS=native WHAT=release all git-native: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=git WITH_GUI=0 all + $(SPEEDOMAKE) TARGETOS=native WHAT=git all this-native: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=this WITH_GUI=0 all - -native-gui: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=release WITH_GUI=1 all - -git-native-gui: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=git WITH_GUI=1 all - -this-native-gui: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=this WITH_GUI=1 all + $(SPEEDOMAKE) TARGETOS=native WHAT=this all w32-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release installer git-w32-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=git WITH_GUI=0 installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=git installer this-w32-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=this WITH_GUI=0 \ - CUSTOM_SWDB=1 installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 installer w32-wixlib: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 wixlib + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release wixlib git-w32-wixlib: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=git WITH_GUI=0 wixlib + $(SPEEDOMAKE) TARGETOS=w32 WHAT=git wixlib this-w32-wixlib: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=this WITH_GUI=0 \ - CUSTOM_SWDB=1 wixlib + $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 wixlib w32-source: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 dist-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release dist-source git-w32-source: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=git WITH_GUI=0 dist-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=git dist-source this-w32-source: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=this WITH_GUI=0 \ - CUSTOM_SWDB=1 dist-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 dist-source w32-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ installer-from-source w32-msi-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ WITH_WIXLIB=1 installer-from-source w32-sign-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ sign-installer w32-release-offline: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ CUSTOM_SWDB=1 pkgrep=${HOME}/b pkg10rep=${HOME}/b \ installer-from-source @@ -220,9 +207,6 @@ WHAT=git # Set target to "native" or "w32" TARGETOS= -# Set to 1 to build the GUI tools -WITH_GUI=0 - # Set to 1 to use a pre-installed swdb.lst instead of the online version. CUSTOM_SWDB=0 @@ -240,7 +224,7 @@ STATIC=0 TARBALLS=$(shell pwd)/../tarballs # Number of parallel make jobs for each package -MAKE_J=3 +MAKE_J=6 # Name to use for the w32 installer and sources INST_NAME=gnupg-w32 @@ -251,6 +235,9 @@ INSTALL_PREFIX=none # Set this to the location of wixtools WIXPREFIX=$(shell readlink -f ~/w32root/wixtools) +# If patchelf(1) is not availale disable the command. +PATCHELF := $(shell patchelf --version 2>/dev/null >/dev/null || echo "echo please run: ")patchelf + # Read signing information from ~/.gnupg-autogen.rc define READ_AUTOGEN_template $(1) = $$(shell grep '^$(1)=' $$$$HOME/.gnupg-autogen.rc|cut -d= -f2) @@ -324,55 +311,16 @@ speedo_spkgs = \ ifeq ($(TARGETOS),w32) speedo_spkgs += \ zlib bzip2 sqlite -ifeq ($(WITH_GUI),1) -speedo_spkgs += gettext libiconv -endif endif -speedo_spkgs += \ - libassuan libksba - -ifeq ($(TARGETOS),w32) -speedo_spkgs += \ - ntbtls -endif - -speedo_spkgs += \ - gnupg - -ifeq ($(TARGETOS),w32) -ifeq ($(WITH_GUI),1) -speedo_spkgs += \ - libffi glib pkg-config -endif -endif +speedo_spkgs += libassuan libksba ntbtls gnupg ifeq ($(STATIC),0) -speedo_spkgs += \ - gpgme +speedo_spkgs += gpgme endif ifeq ($(TARGETOS),w32) -ifeq ($(WITH_GUI),1) -speedo_spkgs += \ - libpng \ - gdk-pixbuf atk pixman cairo pango gtk+ -endif -endif - -ifeq ($(TARGETOS),w32) - speedo_spkgs += pinentry -ifeq ($(WITH_GUI),1) -speedo_spkgs += gpa gpgex -endif - -else - -ifeq ($(WITH_GUI),1) -speedo_spkgs += pinentry gpa -endif - endif @@ -383,15 +331,12 @@ endif # only used for gpgex and thus we need to build them only if we want # a full installer. speedo_w64_spkgs = -ifeq ($(WITH_GUI),1) -speedo_w64_spkgs += libgpg-error libiconv gettext libassuan gpgex -endif # Packages which use the gnupg autogen.sh build style speedo_gnupg_style = \ libgpg-error npth libgcrypt \ libassuan libksba ntbtls gnupg gpgme \ - pinentry gpa gpgex + pinentry # Packages which use only make and no build directory speedo_make_only_style = \ @@ -451,14 +396,6 @@ pinentry_ver := $(shell awk '$$1=="pinentry_ver" {print $$2}' swdb.lst) pinentry_sha1 := $(shell awk '$$1=="pinentry_sha1" {print $$2}' swdb.lst) pinentry_sha2 := $(shell awk '$$1=="pinentry_sha2" {print $$2}' swdb.lst) -gpa_ver := $(shell awk '$$1=="gpa_ver" {print $$2}' swdb.lst) -gpa_sha1 := $(shell awk '$$1=="gpa_sha1" {print $$2}' swdb.lst) -gpa_sha2 := $(shell awk '$$1=="gpa_sha2" {print $$2}' swdb.lst) - -gpgex_ver := $(shell awk '$$1=="gpgex_ver" {print $$2}' swdb.lst) -gpgex_sha1 := $(shell awk '$$1=="gpgex_sha1" {print $$2}' swdb.lst) -gpgex_sha2 := $(shell awk '$$1=="gpgex_sha2" {print $$2}' swdb.lst) - zlib_ver := $(shell awk '$$1=="zlib_ver" {print $$2}' swdb.lst) zlib_sha1 := $(shell awk '$$1=="zlib_sha1_gz" {print $$2}' swdb.lst) zlib_sha2 := $(shell awk '$$1=="zlib_sha2_gz" {print $$2}' swdb.lst) @@ -474,7 +411,7 @@ sqlite_sha2 := $(shell awk '$$1=="sqlite_sha2_gz" {print $$2}' swdb.lst) $(info Information from the version database) $(info GnuPG ..........: $(gnupg_ver) (building $(gnupg_ver_this))) -$(info Libgpg-error ...: $(libgpg_error_ver)) +$(info GpgRT ..........: $(libgpg_error_ver)) $(info Npth ...........: $(npth_ver)) $(info Libgcrypt ......: $(libgcrypt_ver)) $(info Libassuan ......: $(libassuan_ver)) @@ -485,23 +422,13 @@ $(info SQLite .........: $(sqlite_ver)) $(info NtbTLS .. ......: $(ntbtls_ver)) $(info GPGME ..........: $(gpgme_ver)) $(info Pinentry .......: $(pinentry_ver)) -$(info GPA ............: $(gpa_ver)) -$(info GpgEX.... ......: $(gpgex_ver)) endif # Version number for external packages pkg_config_ver = 0.23 libiconv_ver = 1.14 gettext_ver = 0.18.2.1 -libffi_ver = 3.0.13 -glib_ver = 2.34.3 -libpng_ver = 1.4.12 -gdk_pixbuf_ver = 2.26.5 -atk_ver = 1.32.0 -pango_ver = 1.29.4 -pixman_ver = 0.32.4 -cairo_ver = 1.12.16 -gtk__ver = 2.24.17 + # The GIT repository. Using a local repo is much faster. #gitrep = git://git.gnupg.org @@ -552,10 +479,6 @@ else ifeq ($(WHAT),git) speedo_pkg_gpgme_gitref = master speedo_pkg_pinentry_git = $(gitrep)/pinentry speedo_pkg_pinentry_gitref = master - speedo_pkg_gpa_git = $(gitrep)/gpa - speedo_pkg_gpa_gitref = master - speedo_pkg_gpgex_git = $(gitrep)/gpgex - speedo_pkg_gpgex_gitref = master else ifeq ($(WHAT),release) speedo_pkg_libgpg_error_tar = \ $(pkgrep)/libgpg-error/libgpg-error-$(libgpg_error_ver).tar.bz2 @@ -573,10 +496,6 @@ else ifeq ($(WHAT),release) $(pkgrep)/gpgme/gpgme-$(gpgme_ver).tar.bz2 speedo_pkg_pinentry_tar = \ $(pkgrep)/pinentry/pinentry-$(pinentry_ver).tar.bz2 - speedo_pkg_gpa_tar = \ - $(pkgrep)/gpa/gpa-$(gpa_ver).tar.bz2 - speedo_pkg_gpgex_tar = \ - $(pkg10rep)/gpgex/gpgex-$(gpgex_ver).tar.bz2 else $(error invalid value for WHAT (use on of: git release this)) endif @@ -587,15 +506,6 @@ speedo_pkg_bzip2_tar = $(pkgrep)/bzip2/bzip2-$(bzip2_ver).tar.gz speedo_pkg_sqlite_tar = $(pkgrep)/sqlite/sqlite-autoconf-$(sqlite_ver).tar.gz speedo_pkg_libiconv_tar = $(pkg2rep)/libiconv-$(libiconv_ver).tar.gz speedo_pkg_gettext_tar = $(pkg2rep)/gettext-$(gettext_ver).tar.gz -speedo_pkg_libffi_tar = $(pkg2rep)/libffi-$(libffi_ver).tar.gz -speedo_pkg_glib_tar = $(pkg2rep)/glib-$(glib_ver).tar.xz -speedo_pkg_libpng_tar = $(pkg2rep)/libpng-$(libpng_ver).tar.bz2 -speedo_pkg_gdk_pixbuf_tar = $(pkg2rep)/gdk-pixbuf-$(gdk_pixbuf_ver).tar.xz -speedo_pkg_atk_tar = $(pkg2rep)/atk-$(atk_ver).tar.bz2 -speedo_pkg_pango_tar = $(pkg2rep)/pango-$(pango_ver).tar.bz2 -speedo_pkg_pixman_tar = $(pkg2rep)/pixman-$(pixman_ver).tar.gz -speedo_pkg_cairo_tar = $(pkg2rep)/cairo-$(cairo_ver).tar.xz -speedo_pkg_gtk__tar = $(pkg2rep)/gtk+-$(gtk__ver).tar.xz # @@ -651,25 +561,13 @@ define speedo_pkg_gnupg_post_install endef endif -# The LDFLAGS is needed for -lintl for glib. -ifeq ($(WITH_GUI),1) -speedo_pkg_gpgme_configure = \ - --enable-static --enable-w32-glib \ - --with-gpg-error-prefix=$(idir) \ - LDFLAGS=-L$(idir)/lib -else +# The LDFLAGS was needed for -lintl for glib. speedo_pkg_gpgme_configure = \ --disable-static --disable-w32-glib \ --with-gpg-error-prefix=$(idir) \ LDFLAGS=-L$(idir)/lib -endif -ifeq ($(TARGETOS),w32) -speedo_pkg_pinentry_configure = --disable-pinentry-gtk2 -else -speedo_pkg_pinentry_configure = --enable-pinentry-gtk2 -endif speedo_pkg_pinentry_configure += \ --disable-pinentry-qt5 \ --disable-pinentry-qt \ @@ -680,22 +578,6 @@ speedo_pkg_pinentry_configure += \ CXXFLAGS=-static-libstdc++ -speedo_pkg_gpa_configure = \ - --with-libiconv-prefix=$(idir) --with-libintl-prefix=$(idir) \ - --with-gpgme-prefix=$(idir) --with-zlib=$(idir) \ - --with-libassuan-prefix=$(idir) --with-gpg-error-prefix=$(idir) - -speedo_pkg_gpgex_configure = \ - --with-gpg-error-prefix=$(idir) \ - --with-libassuan-prefix=$(idir) \ - --enable-gpa-only - -speedo_pkg_w64_gpgex_configure = \ - --with-gpg-error-prefix=$(idir6) \ - --with-libassuan-prefix=$(idir6) \ - --enable-gpa-only - - # # External packages # @@ -759,60 +641,6 @@ speedo_pkg_gettext_extracflags = -O2 speedo_pkg_gettext_make_dir = gettext-runtime -speedo_pkg_glib_configure = \ - --disable-modular-tests \ - --with-libiconv=gnu \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib \ - CCC=$(host)-g++ \ - LIBFFI_CFLAGS=-I$(idir)/lib/libffi-$(libffi_ver)/include \ - LIBFFI_LIBS=\"-L$(idir)/lib -lffi\" -ifeq ($(TARGETOS),w32) -speedo_pkg_glib_extracflags = -march=i486 -endif - -ifeq ($(TARGETOS),w32) -speedo_pkg_libpng_configure = \ - CPPFLAGS=\"-I$(idir)/include -DPNG_BUILD_DLL\" \ - LDFLAGS=\"-L$(idir)/lib\" LIBPNG_DEFINES=\"-DPNG_BUILD_DLL\" -else -speedo_pkg_libpng_configure = \ - CPPFLAGS=\"-I$(idir)/include\" \ - LDFLAGS=\"-L$(idir)/lib\" -endif - -ifneq ($(TARGETOS),w32) -speedo_pkg_gdk_pixbuf_configure = --without-libtiff --without-libjpeg -endif - -speedo_pkg_pixman_configure = \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib - -ifeq ($(TARGETOS),w32) -speedo_pkg_cairo_configure = \ - --disable-qt --disable-ft --disable-fc \ - --enable-win32 --enable-win32-font \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib -else -speedo_pkg_cairo_configure = \ - --disable-qt \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib -endif - -speedo_pkg_pango_configure = \ - --disable-gtk-doc \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib - -speedo_pkg_gtk__configure = \ - --disable-cups \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib - - # --------- all: all-speedo @@ -1286,6 +1114,24 @@ clean-pkg-versions: @: >$(bdir)/pkg-versions.txt all-speedo: $(stampdir)/stamp-final +ifneq ($(TARGETOS),w32) + @(set -e;\ + cd "$(idir)"; \ + echo "speedo: Making RPATH relative";\ + for d in bin sbin libexec lib; do \ + for f in $$(find $$d -type f); do \ + if file $$f | grep ELF >/dev/null; then \ + $(PATCHELF) --set-rpath '$$ORIGIN/../lib' $$f; \ + fi; \ + done; \ + done; \ + echo "sysconfdir = /etc" >bin/gpgconf.ctl ;\ + echo "rootdir = $(idir)" >>bin/gpgconf.ctl ;\ + echo "speedo: /*" ;\ + echo "speedo: * Now copy $(idir)/ to the final location and" ;\ + echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly." ;\ + echo "speedo: */") +endif report-speedo: $(addprefix report-,$(speedo_build_list)) @@ -1357,9 +1203,6 @@ $(bdir)/inst-options.ini: $(w32src)/inst-options.ini cat $(w32src)/inst-options.ini >$(bdir)/inst-options.ini extra_installer_options = -ifeq ($(WITH_GUI),1) -extra_installer_options += -DWITH_GUI=1 -endif # Note that we sign only when doing the final installer. installer: all w32_insthelpers $(w32src)/inst-options.ini $(bdir)/README.txt diff --git a/common/w32info-rc.h.in b/common/w32info-rc.h.in index 1e76b58a9..bec152eb2 100644 --- a/common/w32info-rc.h.in +++ b/common/w32info-rc.h.in @@ -29,4 +29,4 @@ built on @BUILD_HOSTNAME@ at @BUILD_TIMESTAMP@\0" #define W32INFO_PRODUCTVERSION "@VERSION@\0" #define W32INFO_LEGALCOPYRIGHT "Copyright \xa9 \ -2023 g10 Code GmbH\0" +2024 g10 Code GmbH\0" diff --git a/configure.ac b/configure.ac index fc0590c14..26d7f7b55 100644 --- a/configure.ac +++ b/configure.ac @@ -525,7 +525,7 @@ AH_BOTTOM([ #define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d" #define GNUPG_CACHE_DIR "cache.d" -#define GNUPG_DEF_COPYRIGHT_LINE "Copyright (C) 2023 g10 Code GmbH" +#define GNUPG_DEF_COPYRIGHT_LINE "Copyright (C) 2024 g10 Code GmbH" /* For some systems (DOS currently), we hardcode the path here. For POSIX systems the values are constructed by the Makefiles, so that diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index b43fb1c91..557729770 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -99,6 +99,7 @@ EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ samplekeys/opensc-test.p12 \ samplekeys/t5793-openssl.pfx \ samplekeys/t5793-test.pfx \ + samplekeys/t6752-ov-user-ff.p12 \ samplekeys/edward.tester@demo.gnupg.com.p12 \ samplekeys/nistp256-openssl-self-signed.p12 \ samplemsgs/pwri-sample.cbc.p7m \ From 3f12e3dacbe65b4847eb2ba3b19ae6ee82c6217d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Jan 2024 13:25:06 +0100 Subject: [PATCH 17/45] speedo: Add install target for Unix. * build-aux/speedo.mk: Default to SELFCHECK=0. (install, install-speedo): New targets. -- GnuPG-bug-id: 6710 --- README | 11 ++++++-- build-aux/speedo.mk | 67 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/README b/README index 02e0fedd4..13205c275 100644 --- a/README +++ b/README @@ -85,11 +85,18 @@ To quickly build all required software without installing it, the Speedo target may be used: - make speedo + make -f build-aux/speedo.mk native This target downloads all required libraries and does a native build of GnuPG to PLAY/inst/. GNU make and the patchelf tool are - required. Follow the instructions give at the end of the make run. + required. After the build the entire software including all + libraries can be installed into an arbitrary location using for + example: + + make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg-foo + + and adding the directory to PATH. + ** Specific build problems on some machines: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 0cefebed9..be400c37a 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -113,7 +113,7 @@ help: @echo 'Prepend TARGET with "git-" to build from GIT repos.' @echo 'Prepend TARGET with "this-" to build from the source tarball.' @echo 'Use STATIC=1 to build with statically linked libraries.' - @echo 'Use SELFCHECK=0 for a non-released version.' + @echo 'Use SELFCHECK=1 for additional check of the gnupg version.' @echo 'Use CUSTOM_SWDB=1 for an already downloaded swdb.lst.' @echo 'Use WIXPREFIX to provide the WIX binaries for the MSI package.' @echo ' Using WIX also requires wine with installed wine mono.' @@ -182,19 +182,17 @@ this-w32-source: check-tools $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 dist-source w32-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ - installer-from-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release installer-from-source w32-msi-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release \ WITH_WIXLIB=1 installer-from-source w32-sign-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ - sign-installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release sign-installer w32-release-offline: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release \ CUSTOM_SWDB=1 pkgrep=${HOME}/b pkg10rep=${HOME}/b \ installer-from-source @@ -213,8 +211,8 @@ CUSTOM_SWDB=0 # Set to 1 to really download the swdb. UPD_SWDB=0 -# Set to 0 to skip the GnuPG version self-check -SELFCHECK=1 +# Set to 1 to run an additional GnuPG version check +SELFCHECK=0 # Set to 1 to build with statically linked libraries. STATIC=0 @@ -645,6 +643,8 @@ speedo_pkg_gettext_make_dir = gettext-runtime all: all-speedo +install: install-speedo + report: report-speedo clean: clean-speedo @@ -1129,10 +1129,55 @@ ifneq ($(TARGETOS),w32) echo "rootdir = $(idir)" >>bin/gpgconf.ctl ;\ echo "speedo: /*" ;\ echo "speedo: * Now copy $(idir)/ to the final location and" ;\ - echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly." ;\ + echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ + echo "speedo: * Or run:" ;\ + echo "speedo: * make -f build-aux/speedo.mk install SYSROOT=/somewhere" ;\ echo "speedo: */") endif +# No dependencies for the install target; instead we test whether +# some of the to be installed files are available. This avoids +# accidental rebuilds under a wrong account. +install-speedo: +ifneq ($(TARGETOS),w32) + @(set -e; \ + cd "$(idir)"; \ + if [ x"$$SYSROOT" = x ]; then \ + echo "speedo: ERROR: SYSROOT has not been given";\ + echo "speedo: Set SYSROOT to the desired install directory";\ + echo "speedo: Example:";\ + echo "speedo: make -f build-aux/speedo.mk install SYSROOT=/usr/local";\ + exit 1;\ + fi;\ + if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ + echo "speedo: error creating target directory";\ + exit 1;\ + fi; fi;\ + if ! touch "$$SYSROOT"/bin/gpgconf.ctl; then \ + echo "speedo: Error writing $$SYSROOT/bin/gpgconf.ctl";\ + echo "speedo: Please check the permissions";\ + exit 1;\ + fi;\ + if [ ! -f bin/gpgconf.ctl ]; then \ + echo "speedo: ERROR: Nothing to install";\ + echo "speedo: Please run a build first";\ + echo "speedo: Example:";\ + echo "speedo: make -f build-aux/speedo.mk native";\ + exit 1;\ + fi;\ + echo "speedo: Installing files to $$SYSROOT";\ + find . -type f -executable \ + -exec install -Dm 755 "{}" "$$SYSROOT/{}" \; ;\ + find . -type f \! -executable \ + -exec install -Dm 644 "{}" "$$SYSROOT/{}" \; ;\ + echo "sysconfdir = /etc" > "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo "rootdir = $$SYSROOT" >> "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo '/*' ;\ + echo " * Installation to $$SYSROOT done" ;\ + echo ' */' ) +endif + + report-speedo: $(addprefix report-,$(speedo_build_list)) # Just to check if we caught all stamps. @@ -1408,4 +1453,4 @@ check-tools: $(stampdir)/stamp-directories # Mark phony targets # .PHONY: all all-speedo report-speedo clean-stamps clean-speedo installer \ - w32_insthelpers check-tools clean-pkg-versions + w32_insthelpers check-tools clean-pkg-versions install-speedo install From b97a36f52d8045faeb769ea7a52caedf1f460098 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Jan 2024 16:53:53 +0100 Subject: [PATCH 18/45] Prepare the NEWS -- --- NEWS | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 7b99deeab..4e2d84d67 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,97 @@ Noteworthy changes in version 2.4.4 (unreleased) ------------------------------------------------ - * gpgsm: Support ECDSA in de-vs compliance mode. [T6802] + * gpg: Allow to specify seconds since Epoch beyond 2038 on 32-bit + platforms. [T6736] + + * gpg: Fix expiration time when Creation-Date is specified. [T5252] + + * gpg: Add support for Subkey-Expire-Date. [rG96b69c1866] + + * gpg: Add option --with-v5-fingerprint. [T6705] + + * gpg: Fix validity of re-imported keys. [T6399] + + * gpg: Add --list-filter properties sig_expires/sig_expires_d. + [rGbf662d0f93af] + + * gpg: Report BEGIN_ status before examining the input. [T6481] + + * gpg: Don't try to compress a read-only keybox. [T6811] + + * gpg: Choose key from inserted card over a non-inserted + card. [T6831] + + * gpg: Allow to create revocations even with non-compliant algos. + [T6929] + + * gpg: Fix regression in the Revoker keyword of the parameter file. + [T6923] + + * gpg: Improve error message for expired default keys. [T4704] + + * gpgsm: Add --always-trust feature. [T6559] + + * gpgsm: Support ECC certificates in de-vs mode. [T6802] + + * gpgsm: Major rewrite of the PKCS#12 parser. [T6536] + + * gpgsm: No not show the pkcs#12 passphrase in debug output. [T6654] + + * keyboxd: Timeout on failure to get the database lock. [T6838] + + * agent: Update the key stubs only if really modified. [T6829] + + * scd: Add support for certain Starcos 3.2 cards. [rG5304c9b080] + + * scd: Add support for CardOS 5.4 cards. [rG812f988059] + + * scd: Add support for D-Trust 4.1/4.4 cards. [rG0b85a9ac09] + + * scd: Add support for Smartcafe Expert 7.0 cards. [T6919] + + * scd: Add a length check for a new PIN. [T6843] + + * tpm: Fix keytotpm handling in the agent. [rG9909f622f6] + + * tpm: Fixes for the TPM test suite. [T6052] * dirmngr: Avoid starting a second instance on Windows via GPGME based launching. [T6833] - * Fix garbled time output in non-English Windows. [T6741] + * dirmngr: New option --ignore-crl-extensions. [T6545] + + * dirmngr: Support config value "none" to disable the default + keyserver. [T6708] + + * dirmngr: Implement automatic proxy detection on Windows. [T5768] + + * dirmngr: Fix handling of the HTTP Content-Length. [rGa5e33618f4] + + * dirmngr: Add code to support proxy authentication using the + Negotiation method on Windows. [T6719] + + * gpgconf: Add commands --lock and --unlock. [rG93b5ba38dc] + + * gpgconf: Add keyword socketdir to gpgconf.ctl. [rG239c1fdc28] + + * gpgconf: Adjust the -X command for the new VERSION file format. + [T6918] + + * wkd: Use export-clean for gpg-wks-client's --mirror and --create + commands. [rG2c7f7a5a278c] + + * wkd: Make --add-revocs the default in gpg-wks-client. New option + --no-add-revocs. [rG10c937ee68] + + * Remove duplicated backslashes when setting the homedir. [T6833] + + * Ignore attempts to remove the /dev/null device. [T6556] + + * Improve advisory file lock retry strategy. [T3380] + + * Improve the speedo build system for Unix. [T6710] + Release-info: https://dev.gnupg.org/T6578 @@ -26,6 +111,8 @@ Noteworthy changes in version 2.4.3 (2023-07-04) * gpg: New option --no-compress as alias for -z0. + * gpg: Show better error messages for blocked PINs. [T6425] + * gpgsm: Print PROGRESS status lines. Add new --input-size-hint. [T6534] @@ -57,6 +144,8 @@ Noteworthy changes in version 2.4.3 (2023-07-04) * scd: Fix authentication with Administration Key for PIV. [rG25b59cf6ce] + * Fix garbled time output in non-English Windows. [T6741] + See-also: gnupg-announce/2023q3/000480.html Release-info: https://dev.gnupg.org/T6509 @@ -1681,6 +1770,8 @@ Noteworthy changes in version 2.3.0 (2021-04-07) Release dates of 2.2 versions ----------------------------- +Version 2.2.42 (2023-11-28) https://dev.gnupg.org/T6307 +Version 2.2.41 (2022-12-09) https://dev.gnupg.org/T6280 Version 2.2.40 (2022-10-10) https://dev.gnupg.org/T6181 Version 2.2.39 (2022-09-02) https://dev.gnupg.org/T6175 Version 2.2.38 (2022-09-01) https://dev.gnupg.org/T6159 From 3d60ad5c8c435890d08ae4afa9efccd5bfd4ea58 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 15 Jan 2024 08:26:57 +0100 Subject: [PATCH 19/45] po: Fix indentation for key generation options -- --- po/ca.po | 10 +++++----- po/da.po | 10 +++++----- po/de.po | 6 +++--- po/el.po | 12 ++++++------ po/eo.po | 12 ++++++------ po/es.po | 8 ++++---- po/et.po | 12 ++++++------ po/fi.po | 12 ++++++------ po/fr.po | 2 +- po/gl.po | 12 ++++++------ po/hu.po | 12 ++++++------ po/id.po | 36 ++++++++++++++++++------------------ po/it.po | 6 +++--- po/nb.po | 2 +- po/pl.po | 8 ++++---- po/ro.po | 6 +++--- po/sk.po | 12 ++++++------ po/sv.po | 10 +++++----- po/uk.po | 4 ++-- po/zh_TW.po | 10 +++++----- 20 files changed, 101 insertions(+), 101 deletions(-) diff --git a/po/ca.po b/po/ca.po index d6840dbc1..9b7cd8d1c 100644 --- a/po/ca.po +++ b/po/ca.po @@ -4535,24 +4535,24 @@ msgstr " (predeterminat)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (només signar)\n" +msgstr " (%d) DSA (només signar)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (només signar)\n" +msgstr " (%d) DSA (només signar)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (només xifrar)\n" +msgstr " (%d) RSA (només xifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (només xifrar)\n" +msgstr " (%d) RSA (només xifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (només xifrar)\n" +msgstr " (%d) RSA (només xifrar)\n" #, fuzzy msgid "Enter the keygrip: " diff --git a/po/da.po b/po/da.po index 011ea7d0d..a2b7ef163 100644 --- a/po/da.po +++ b/po/da.po @@ -4553,27 +4553,27 @@ msgstr "" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (kun underskriv)\n" +msgstr " (%d) DSA (kun underskriv)\n" #, fuzzy, c-format #| msgid " (%d) DSA (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (angiv dine egne evner)\n" +msgstr " (%d) DSA (angiv dine egne evner)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (kun krypter)\n" +msgstr " (%d) RSA (kun krypter)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Eksisterende nøgle\n" +msgstr " (%d) Eksisterende nøgle\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Eksisterende nøgle fra kort\n" +msgstr " (%d) Eksisterende nøgle fra kort\n" # key grip # chiefly ( US ) See also grip the person in charge of moving and setting up camera diff --git a/po/de.po b/po/de.po index 04ed2a697..7afa2d086 100644 --- a/po/de.po +++ b/po/de.po @@ -4245,11 +4245,11 @@ msgstr " (%d) ECC (nur verschlüsseln)%s\n" #, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) Vorhandener Schlüssel%s\n" +msgstr " (%d) Vorhandener Schlüssel%s\n" #, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Vorhandener Schlüssel auf der Karte%s\n" +msgstr " (%d) Vorhandener Schlüssel auf der Karte%s\n" msgid "Enter the keygrip: " msgstr "Geben Sie den \"Keygrip\" ein: " @@ -9406,7 +9406,7 @@ msgstr "Verwaltung der Kommandohistorie" #~ msgstr "Werte das Vertrauen zu Signaturen durch gültige PKA-Daten auf" #~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) ECC und ECC\n" +#~ msgstr " (%d) ECC und ECC\n" #~ msgid "honor the PKA record set on a key when retrieving keys" #~ msgstr "Die im Schlüssel enthaltenen PKA-Daten beim Schlüsselholen beachten" diff --git a/po/el.po b/po/el.po index 7d4e8e738..08f85c82c 100644 --- a/po/el.po +++ b/po/el.po @@ -4431,24 +4431,24 @@ msgstr " (προκαθορισμένο)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (για υπογραφή μόνο)\n" +msgstr " (%d) DSA (για υπογραφή μόνο)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11225,7 +11225,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (υπογραφή και κρυπτογράφηση)\n" +#~ msgstr " (%d) RSA (υπογραφή και κρυπτογράφηση)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: αδυναμία πρόσβασης του: %s\n" diff --git a/po/eo.po b/po/eo.po index a142ce1aa..d77143896 100644 --- a/po/eo.po +++ b/po/eo.po @@ -4395,24 +4395,24 @@ msgstr "malĉifri datenojn (implicita elekto)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (nur subskribi)\n" +msgstr " (%d) DSA (nur subskribi)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy msgid "Enter the keygrip: " @@ -10993,7 +10993,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (subskribi kaj ĉifri)\n" +#~ msgstr " (%d) RSA (subskribi kaj ĉifri)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: ne povas malfermi: %s\n" diff --git a/po/es.po b/po/es.po index 4409ce443..635084915 100644 --- a/po/es.po +++ b/po/es.po @@ -4297,22 +4297,22 @@ msgstr " (%d) ECC (sólo firmar)\n" #, fuzzy, c-format #| msgid " (%d) ECC (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (permite elegir capacidades)\n" +msgstr " (%d) ECC (permite elegir capacidades)\n" #, fuzzy, c-format #| msgid " (%d) ECC (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (sólo cifrar)\n" +msgstr " (%d) ECC (sólo cifrar)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Clave existente\n" +msgstr " (%d) Clave existente\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Clave existente de la tarjeta\n" +msgstr " (%d) Clave existente de la tarjeta\n" msgid "Enter the keygrip: " msgstr "Introduzca keygrip: " diff --git a/po/et.po b/po/et.po index 5e106d6f5..1f07b58fc 100644 --- a/po/et.po +++ b/po/et.po @@ -4391,24 +4391,24 @@ msgstr " (vaikimisi)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (ainult allkirjastamiseks)\n" +msgstr " (%d) DSA (ainult allkirjastamiseks)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11089,7 +11089,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (allkirjastamiseks ja krüptimiseks)\n" +#~ msgstr " (%d) RSA (allkirjastamiseks ja krüptimiseks)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: ei õnnestu avada: %s\n" diff --git a/po/fi.po b/po/fi.po index 3af8e811e..4248372d3 100644 --- a/po/fi.po +++ b/po/fi.po @@ -4420,24 +4420,24 @@ msgstr " (oletusarvo)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (vain allekirjoitus)\n" +msgstr " (%d) DSA (vain allekirjoitus)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11195,7 +11195,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (salaus ja allekirjoitus)\n" +#~ msgstr " (%d) RSA (salaus ja allekirjoitus)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: ei voida avata kohdetta: %s\n" diff --git a/po/fr.po b/po/fr.po index 6530e7768..e7ea9ffc2 100644 --- a/po/fr.po +++ b/po/fr.po @@ -4465,7 +4465,7 @@ msgstr " (%d) Clef existante\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Clef existante sur la carte\n" +msgstr " (%d) Clef existante sur la carte\n" msgid "Enter the keygrip: " msgstr "Entrez le keygrip : " diff --git a/po/gl.po b/po/gl.po index d6972580a..73e3ff463 100644 --- a/po/gl.po +++ b/po/gl.po @@ -4427,24 +4427,24 @@ msgstr " (por defecto)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (só asinar)\n" +msgstr " (%d) DSA (só asinar)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11216,7 +11216,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (asinar e cifrar)\n" +#~ msgstr " (%d) RSA (asinar e cifrar)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: non se pode abrir: %s\n" diff --git a/po/hu.po b/po/hu.po index e875d074b..a0e96c94d 100644 --- a/po/hu.po +++ b/po/hu.po @@ -4396,24 +4396,24 @@ msgstr " (alapértelmezés)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (csak aláírás)\n" +msgstr " (%d) DSA (csak aláírás)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11148,7 +11148,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (aláírás és titkosítás)\n" +#~ msgstr " (%d) RSA (aláírás és titkosítás)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s-t nem tudom megnyitni: %s.\n" diff --git a/po/id.po b/po/id.po index 363bad315..259fe9937 100644 --- a/po/id.po +++ b/po/id.po @@ -1585,11 +1585,11 @@ msgstr "Silakan pilih kunci yang anda inginkan:\n" #, fuzzy, c-format msgid " (%d) RSA\n" -msgstr " (%d) RSA (hanya menandai)\n" +msgstr " (%d) RSA (hanya menandai)\n" #, fuzzy, c-format msgid " (%d) ECC\n" -msgstr " (%d) DSA dan ElGamal (baku)\n" +msgstr " (%d) DSA dan ElGamal (baku)\n" msgid "Invalid selection.\n" msgstr "Pilihan tidak valid.\n" @@ -4360,43 +4360,43 @@ msgstr "" #, fuzzy, c-format msgid " (%d) RSA and RSA%s\n" -msgstr " (%d) DSA dan ElGamal (baku)\n" +msgstr " (%d) DSA dan ElGamal (baku)\n" #, fuzzy, c-format msgid " (%d) DSA and Elgamal%s\n" -msgstr " (%d) DSA dan ElGamal (baku)\n" +msgstr " (%d) DSA dan ElGamal (baku)\n" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) DSA (sign only)%s\n" -msgstr " (%d) DSA (hanya menandai)\n" +msgstr " (%d) DSA (hanya menandai)\n" #, fuzzy, c-format #| msgid " (%d) RSA (sign only)\n" msgid " (%d) RSA (sign only)%s\n" -msgstr " (%d) RSA (hanya menandai)\n" +msgstr " (%d) RSA (hanya menandai)\n" #, fuzzy, c-format msgid " (%d) Elgamal (encrypt only)%s\n" -msgstr " (%d) ElGamal (hanya enkripsi)\n" +msgstr " (%d) ElGamal (hanya enkripsi)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) RSA (encrypt only)%s\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy, c-format msgid " (%d) DSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy, c-format msgid " (%d) RSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy, c-format #| msgid " (%d) ElGamal (sign and encrypt)\n" msgid " (%d) ECC (sign and encrypt)%s\n" -msgstr " (%d) ElGamal (tandai dan enkripsi)\n" +msgstr " (%d) ElGamal (tandai dan enkripsi)\n" #, fuzzy #| msgid " (default)" @@ -7461,7 +7461,7 @@ msgstr "" #, fuzzy, c-format msgid " (%d) Existing key\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, c-format msgid " (%d) Existing key from card\n" @@ -7477,11 +7477,11 @@ msgstr " (%d) RSA (tandai dan enkripsi)\n" #, fuzzy, c-format msgid " (%d) sign\n" -msgstr " (%d) DSA (hanya menandai)\n" +msgstr " (%d) DSA (hanya menandai)\n" #, fuzzy, c-format msgid " (%d) encrypt\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" msgid "Enter the X.509 subject name: " msgstr "" @@ -9502,7 +9502,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) DSA dan ElGamal (baku)\n" +#~ msgstr " (%d) DSA dan ElGamal (baku)\n" #, fuzzy #~ msgid "run without asking a user" @@ -11140,7 +11140,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (auth only)\n" -#~ msgstr " (%d) RSA (hanya menandai)\n" +#~ msgstr " (%d) RSA (hanya menandai)\n" #, fuzzy #~ msgid " (%d) RSA (sign and auth)\n" @@ -11148,11 +11148,11 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (encrypt and auth)\n" -#~ msgstr " (%d) RSA (hanya enkripsi)\n" +#~ msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (tandai dan enkripsi)\n" +#~ msgstr " (%d) RSA (tandai dan enkripsi)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: tidak dapat membuka: %s\n" diff --git a/po/it.po b/po/it.po index 8f04c7afa..f301780da 100644 --- a/po/it.po +++ b/po/it.po @@ -4228,7 +4228,7 @@ msgstr " *predefinito*" #, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (firma solo)\n" +msgstr " (%d) DSA (firma solo)\n" #, c-format msgid " (%d) ECC (set your own capabilities)%s\n" @@ -7286,7 +7286,7 @@ msgstr "" #, c-format msgid " (%d) Existing key\n" -msgstr " (%d) Chiave esistente\n" +msgstr " (%d) Chiave esistente\n" #, c-format msgid " (%d) Existing key from card\n" @@ -7298,7 +7298,7 @@ msgstr "Azioni possibili per una chiave %s: \n" #, c-format msgid " (%d) sign, encrypt\n" -msgstr " (%d) segno, cifra\n" +msgstr " (%d) segno, cifra\n" #, c-format msgid " (%d) sign\n" diff --git a/po/nb.po b/po/nb.po index 922cb4957..dcbd64efa 100644 --- a/po/nb.po +++ b/po/nb.po @@ -4282,7 +4282,7 @@ msgstr " (%d) Nøkkel\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Nøkkel fra kort\n" +msgstr " (%d) Nøkkel fra kort\n" msgid "Enter the keygrip: " msgstr "Skriv inn nøkkelgrep: " diff --git a/po/pl.po b/po/pl.po index dcbab2240..459d3160c 100644 --- a/po/pl.po +++ b/po/pl.po @@ -4273,22 +4273,22 @@ msgstr "" #, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) ECC (tylko do podpisywania)\n" +msgstr " (%d) ECC (tylko do podpisywania)\n" #, fuzzy, c-format #| msgid " (%d) ECC (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (możliwości do ustawienia)\n" +msgstr " (%d) ECC (możliwości do ustawienia)\n" #, fuzzy, c-format #| msgid " (%d) ECC (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (tylko do szyfrowania)\n" +msgstr " (%d) ECC (tylko do szyfrowania)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Istniejący klucz\n" +msgstr " (%d) Istniejący klucz\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" diff --git a/po/ro.po b/po/ro.po index b32a1dcd5..ab6fe8396 100644 --- a/po/ro.po +++ b/po/ro.po @@ -4464,17 +4464,17 @@ msgstr "(implicit)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (numai semnare)\n" +msgstr " (%d) DSA (numai semnare)\n" #, fuzzy, c-format #| msgid " (%d) DSA (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (setează singur capabilităţile)\n" +msgstr " (%d) DSA (setează singur capabilităţile)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (numai cifrare)\n" +msgstr " (%d) RSA (numai cifrare)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" diff --git a/po/sk.po b/po/sk.po index 743ce6b0a..e730decf0 100644 --- a/po/sk.po +++ b/po/sk.po @@ -4417,24 +4417,24 @@ msgstr "dešifrovať dáta (implicitne)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (len na podpis)\n" +msgstr " (%d) DSA (len na podpis)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11179,7 +11179,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (pro šifrování a podpis)\n" +#~ msgstr " (%d) RSA (pro šifrování a podpis)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: nemôžem otvoriť: %s\n" diff --git a/po/sv.po b/po/sv.po index 2a62fe1d7..5fcf6532c 100644 --- a/po/sv.po +++ b/po/sv.po @@ -4623,27 +4623,27 @@ msgstr "" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (endast signering)\n" +msgstr " (%d) DSA (endast signering)\n" #, fuzzy, c-format #| msgid " (%d) DSA (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (ställ in dina egna förmågor)\n" +msgstr " (%d) DSA (ställ in dina egna förmågor)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (endast kryptering)\n" +msgstr " (%d) RSA (endast kryptering)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Befintlig nyckel\n" +msgstr " (%d) Befintlig nyckel\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Befintlig nyckel från kort\n" +msgstr " (%d) Befintlig nyckel från kort\n" msgid "Enter the keygrip: " msgstr "Ange nyckelhashen: " diff --git a/po/uk.po b/po/uk.po index 730e9e135..c3e927947 100644 --- a/po/uk.po +++ b/po/uk.po @@ -4335,12 +4335,12 @@ msgstr " (%d) ECC (лише шифрування)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Вже записаний ключ\n" +msgstr " (%d) Вже записаний ключ\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Вже записаний ключ з картки\n" +msgstr " (%d) Вже записаний ключ з картки\n" msgid "Enter the keygrip: " msgstr "Вкажіть keygrip: " diff --git a/po/zh_TW.po b/po/zh_TW.po index f14cce879..4cb6f64bb 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -4293,27 +4293,27 @@ msgstr "" #, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) ECC (僅能用於簽署)\n" +msgstr " (%d) ECC (僅能用於簽署)\n" #, fuzzy, c-format #| msgid " (%d) ECC (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (你能自己設定性能)\n" +msgstr " (%d) ECC (你能自己設定性能)\n" #, fuzzy, c-format #| msgid " (%d) ECC (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (僅能用於加密)\n" +msgstr " (%d) ECC (僅能用於加密)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) 現有的金鑰\n" +msgstr " (%d) 現有的金鑰\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) 卡片上現存的金鑰\n" +msgstr " (%d) 卡片上現存的金鑰\n" msgid "Enter the keygrip: " msgstr "請輸入金鑰鑰柄: " From 092154e17e885616340d7b1f7ecaf5cab4b2baa8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Jan 2024 09:13:46 +0100 Subject: [PATCH 20/45] gpgsm: Improve the status line for --verify errors. * sm/verify.c (gpgsm_verify): Improve verify.leave status line. -- Suggested-by: Jakob Bohm --- sm/verify.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sm/verify.c b/sm/verify.c index e83a24f44..f5d7341ef 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -756,7 +756,12 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) char numbuf[50]; sprintf (numbuf, "%d", rc ); gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave", - numbuf, NULL); + numbuf, + gpg_err_code (rc) == GPG_ERR_EPIPE? + "-- (Broken pipe on input or output)": + gpg_err_code (rc) == GPG_ERR_EOF? + "-- (End of file)" : NULL, + NULL); } return rc; From 0cb622d632f732c24a5d312baf2c6e453775eb10 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Jan 2024 09:55:55 +0100 Subject: [PATCH 21/45] gpgsm: Allow parsing of PKCS#12 files with two private keys. * sm/minip12.c (struct p12_parse_ctx_s): Add privatekey2. (parse_shrouded_key_bag): Handle a second private key. (p12_parse_free_kparms): New. * sm/import.c (parse_p12): Factor some code out to ... (p12_to_skey): this. (parse_p12): Use p12_parse_free_kparms. -- Take care: We allow parsing of a second private key but we are not yet able to import the second private key. The whole things is required to at least import the certificates of current pkcs#12 files as created by the German Elster tax system. No test data, sorry. --- sm/import.c | 157 +++++++++++++++++++++++++------------------------ sm/minip12.c | 58 +++++++++++++++--- sm/minip12.h | 1 + sm/t-minip12.c | 8 +-- 4 files changed, 133 insertions(+), 91 deletions(-) diff --git a/sm/import.c b/sm/import.c index 5a193ef52..cbf8fa627 100644 --- a/sm/import.c +++ b/sm/import.c @@ -692,6 +692,85 @@ store_cert_cb (void *opaque, } +/* Helper for parse_p12. */ +static gpg_error_t +p12_to_skey (gcry_mpi_t *kparms, const char *curve, gcry_sexp_t *r_skey) +{ + gpg_error_t err = 0; + struct rsa_secret_key_s sk; + gcry_ctx_t ecctx = NULL; + + if (curve) + { + /* log_debug ("curve: %s\n", curve); */ + /* gcry_log_debugmpi ("MPI[0]", kparms[0]); */ + + /* We need to get the public key. */ + err = gcry_mpi_ec_new (&ecctx, NULL, curve); + if (err) + { + log_error ("error creating context for curve '%s': %s\n", + curve, gpg_strerror (err)); + goto leave; + } + err = gcry_mpi_ec_set_mpi ("d", kparms[0], ecctx); + if (err) + { + log_error ("error setting 'd' into context of curve '%s': %s\n", + curve, gpg_strerror (err)); + goto leave; + } + + kparms[1] = gcry_mpi_ec_get_mpi ("q", ecctx, 1); + if (!kparms[1]) + { + log_error ("error computing 'q' from 'd' for curve '%s'\n", curve); + goto leave; + } + + err = gcry_sexp_build (r_skey, NULL, + "(private-key(ecc(curve %s)(q%m)(d%m)))", + curve, kparms[1], kparms[0], NULL); + } + else /* RSA */ + { + /* print_mpi (" n", kparms[0]); */ + /* print_mpi (" e", kparms[1]); */ + /* print_mpi (" d", kparms[2]); */ + /* print_mpi (" p", kparms[3]); */ + /* print_mpi (" q", kparms[4]); */ + /* print_mpi ("dmp1", kparms[5]); */ + /* print_mpi ("dmq1", kparms[6]); */ + /* print_mpi (" u", kparms[7]); */ + + sk.n = kparms[0]; + sk.e = kparms[1]; + sk.d = kparms[2]; + sk.q = kparms[3]; + sk.p = kparms[4]; + sk.u = kparms[7]; + err = rsa_key_check (&sk); + if (err) + goto leave; + /* print_mpi (" n", sk.n); */ + /* print_mpi (" e", sk.e); */ + /* print_mpi (" d", sk.d); */ + /* print_mpi (" p", sk.p); */ + /* print_mpi (" q", sk.q); */ + /* print_mpi (" u", sk.u); */ + + /* Create an S-expression from the parameters. */ + err = gcry_sexp_build (r_skey, NULL, + "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", + sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL); + } + + leave: + gcry_ctx_release (ecctx); + return err; +} + + /* Assume that the reader is at a pkcs#12 message and try to import certificates from that stupid format. We will transfer secret keys to the agent. */ @@ -706,7 +785,6 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats) size_t p12buflen; size_t p12bufoff; gcry_mpi_t *kparms = NULL; - struct rsa_secret_key_s sk; char *passphrase = NULL; unsigned char *key = NULL; size_t keylen; @@ -792,82 +870,9 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats) goto leave; } - if (curve) - { - gcry_ctx_t ecctx = NULL; - /* log_debug ("curve: %s\n", curve); */ - /* gcry_log_debugmpi ("MPI[0]", kparms[0]); */ - - /* We need to get the public key. */ - err = gcry_mpi_ec_new (&ecctx, NULL, curve); - if (err) - { - log_error ("error creating context for curve '%s': %s\n", - curve, gpg_strerror (err)); - goto leave; - } - err = gcry_mpi_ec_set_mpi ("d", kparms[0], ecctx); - if (err) - { - log_error ("error setting 'd' into context of curve '%s': %s\n", - curve, gpg_strerror (err)); - gcry_ctx_release (ecctx); - goto leave; - } - - kparms[1] = gcry_mpi_ec_get_mpi ("q", ecctx, 1); - if (!kparms[1]) - { - log_error ("error computing 'q' from 'd' for curve '%s'\n", curve); - gcry_ctx_release (ecctx); - goto leave; - } - - gcry_ctx_release (ecctx); - - err = gcry_sexp_build (&s_key, NULL, - "(private-key(ecc(curve %s)(q%m)(d%m)))", - curve, kparms[1], kparms[0], NULL); - } - else /* RSA */ - { - /* print_mpi (" n", kparms[0]); */ - /* print_mpi (" e", kparms[1]); */ - /* print_mpi (" d", kparms[2]); */ - /* print_mpi (" p", kparms[3]); */ - /* print_mpi (" q", kparms[4]); */ - /* print_mpi ("dmp1", kparms[5]); */ - /* print_mpi ("dmq1", kparms[6]); */ - /* print_mpi (" u", kparms[7]); */ - - sk.n = kparms[0]; - sk.e = kparms[1]; - sk.d = kparms[2]; - sk.q = kparms[3]; - sk.p = kparms[4]; - sk.u = kparms[7]; - err = rsa_key_check (&sk); - if (err) - goto leave; - /* print_mpi (" n", sk.n); */ - /* print_mpi (" e", sk.e); */ - /* print_mpi (" d", sk.d); */ - /* print_mpi (" p", sk.p); */ - /* print_mpi (" q", sk.q); */ - /* print_mpi (" u", sk.u); */ - - /* Create an S-expression from the parameters. */ - err = gcry_sexp_build (&s_key, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL); - } - - /* The next is very ugly - we really should not rely on our - * knowledge of p12_parse internals. */ - for (i=0; i < 8; i++) - gcry_mpi_release (kparms[i]); - gcry_free (kparms); + err = p12_to_skey (kparms, curve, &s_key); + p12_parse_free_kparms (kparms); kparms = NULL; if (err) { diff --git a/sm/minip12.c b/sm/minip12.c index 1bbe126ae..2e7b50e1c 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -168,6 +168,9 @@ struct p12_parse_ctx_s /* The private key as an MPI array. */ gcry_mpi_t *privatekey; + + /* A second private key as an MPI array. */ + gcry_mpi_t *privatekey2; }; @@ -1248,6 +1251,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) int is_pbes2 = 0; int is_aes256 = 0; int digest_algo = GCRY_MD_SHA1; + gcry_mpi_t *privatekey; where = "shrouded_key_bag"; if (opt_verbose) @@ -1565,19 +1569,26 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) if (tlv_expect_sequence (tlv)) goto bailout; - if (ctx->privatekey) + if (ctx->privatekey2) { err = gpg_error (GPG_ERR_DUP_VALUE); - log_error ("a private key has already been received\n"); + log_error ("two private kesy have already been received\n"); goto bailout; } - ctx->privatekey = gcry_calloc (10, sizeof *ctx->privatekey); - if (!ctx->privatekey) + privatekey = gcry_calloc (10, sizeof *privatekey); + if (!privatekey) { err = gpg_error_from_syserror (); log_error ("error allocating privatekey element array\n"); goto bailout; } + if (ctx->privatekey) + { + log_info ("a private key has already been received - reading second\n"); + ctx->privatekey2 = privatekey; + } + else + ctx->privatekey = privatekey; where = "shrouded_key_bag.reading.key-parameters"; if (ctx->curve) /* ECC case. */ @@ -1600,7 +1611,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) goto bailout; if (opt_verbose > 1) log_printhex (data, datalen, "ecc q="); - err = gcry_mpi_scan (ctx->privatekey, GCRYMPI_FMT_USG, + err = gcry_mpi_scan (privatekey, GCRYMPI_FMT_USG, data, datalen, NULL); if (err) { @@ -1623,7 +1634,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) } err = tlv_expect_mpinteger (tlv, firstparam, - ctx->privatekey+keyelem_count); + privatekey+keyelem_count); if (firstparam && gpg_err_code (err) == GPG_ERR_FALSE) ; /* Ignore the first value iff it is zero. */ else if (err) @@ -1918,6 +1929,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, size_t oidlen; int intval; unsigned int startlevel; + int i; *r_badpass = 0; @@ -2037,6 +2049,15 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, else gcry_free (ctx.curve); + /* We have no way yet to return the second private key. */ + if (ctx.privatekey2) + { + for (i=0; ctx.privatekey2[i]; i++) + gcry_mpi_release (ctx.privatekey2[i]); + gcry_free (ctx.privatekey2); + ctx.privatekey2 = NULL; + } + return ctx.privatekey; bailout: @@ -2050,13 +2071,18 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, gpg_strerror (err)); if (ctx.privatekey) { - int i; - for (i=0; ctx.privatekey[i]; i++) gcry_mpi_release (ctx.privatekey[i]); gcry_free (ctx.privatekey); ctx.privatekey = NULL; } + if (ctx.privatekey2) + { + for (i=0; ctx.privatekey2[i]; i++) + gcry_mpi_release (ctx.privatekey2[i]); + gcry_free (ctx.privatekey2); + ctx.privatekey2 = NULL; + } tlv_parser_release (tlv); gcry_free (ctx.curve); if (r_curve) @@ -2065,6 +2091,22 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, } +/* Free the parameters as returned by p12_parse. */ +void +p12_parse_free_kparms (gcry_mpi_t *kparms) +{ + int i; + + if (kparms) + { + for (i=0; i < 8; i++) + gcry_mpi_release (kparms[i]); + gcry_free (kparms); + } +} + + + static size_t compute_tag_length (size_t n) diff --git a/sm/minip12.h b/sm/minip12.h index 654cab0e6..00569cd86 100644 --- a/sm/minip12.h +++ b/sm/minip12.h @@ -29,6 +29,7 @@ gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length, const char *pw, void (*certcb)(void*, const unsigned char*, size_t), void *certcbarg, int *r_badpass, char **r_curve); +void p12_parse_free_kparms (gcry_mpi_t *kparms); unsigned char *p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen, diff --git a/sm/t-minip12.c b/sm/t-minip12.c index bf3177ea0..75c1545d6 100644 --- a/sm/t-minip12.c +++ b/sm/t-minip12.c @@ -580,13 +580,7 @@ run_one_test (const char *name, const char *desc, const char *pass, ret = 0; } - if (result) - { - int i; - for (i=0; result[i]; i++) - gcry_mpi_release (result[i]); - gcry_free (result); - } + p12_parse_free_kparms (result); xfree (certstr); xfree (resulthash); xfree (curve); From 4cdfc1d0d903855f28b891485aa3a08a7d0c64d3 Mon Sep 17 00:00:00 2001 From: Jakub Bogusz Date: Mon, 15 Jan 2024 11:28:00 +0100 Subject: [PATCH 22/45] po: Update parts of the Polish translation -- Jakub provided the translation in October but at this time it did cleanly apply anymore due to string changes. Thus only parts of his changes are here. -wk --- po/pl.po | 395 ++++++++++++++++++++----------------------------------- 1 file changed, 139 insertions(+), 256 deletions(-) diff --git a/po/pl.po b/po/pl.po index 459d3160c..d9d98e9d2 100644 --- a/po/pl.po +++ b/po/pl.po @@ -2,13 +2,13 @@ # Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2007 Free Software Foundation, Inc. # Janusz A. Urbanowicz , 1999, 2000, 2001, 2002, 2003-2004 -# Jakub Bogusz , 2003-2020. +# Jakub Bogusz , 2003-2023. # msgid "" msgstr "" -"Project-Id-Version: gnupg-2.2.24\n" +"Project-Id-Version: gnupg-2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2020-11-18 17:35+0100\n" +"PO-Revision-Date: 2023-10-20 21:29+0200\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -56,12 +56,12 @@ msgid "|pinentry-tt|Hide passphrase" msgstr "|pinentry-tt|Ukrycie hasła" msgid "Caps Lock is on" -msgstr "" +msgstr "Caps Lock jest włączony" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for generating a passphrase. msgid "Suggest" -msgstr "" +msgstr "Propozycja" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the generate button. Please use an appropriate @@ -70,26 +70,20 @@ msgstr "" #. translate this entry, a default English text (see source) #. will be used. The strcmp thingy is there to detect a #. non-translated string. -#, fuzzy -#| msgid "pinentry.qualitybar.tooltip" msgid "pinentry.genpin.tooltip" -msgstr "" -"Jakość wpisanego wyżej tekstu.\n" -"Kryteria jakości można uzyskać od administratora." +msgstr "Propozycja losowego hasła." #. TRANSLATORS: This is a text shown by pinentry if the option #. for formatted passphrase is enabled. The length is #. limited to about 900 characters. msgid "Note: The blanks are not part of the passphrase." -msgstr "" +msgstr "Uwaga: odstępy nie są częścią hasła." #. TRANSLATORS: This is a text shown by pinentry as title of a dialog #. telling the user that the entered new passphrase does not satisfy #. the passphrase constraints. Please keep it short. -#, fuzzy -#| msgid "Passphrase too long" msgid "Passphrase Not Allowed" -msgstr "Hasło zbyt długie" +msgstr "Hasło niedozwolone" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for the quality bar. @@ -127,10 +121,8 @@ msgstr "Hasło:" msgid "does not match - try again" msgstr "nie pasują - proszę spróbować jeszcze raz" -#, fuzzy -#| msgid "Passphrase Entry" msgid "Passphrases match." -msgstr "Wpisywanie hasła" +msgstr "Hasła się zgadzają." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the @@ -161,10 +153,10 @@ msgid "Bad Passphrase" msgstr "Niepoprawne hasło" msgid "Note: Request from the web browser." -msgstr "" +msgstr "Uwaga: żądanie z przeglądarki WWW." msgid "Note: Request from a remote site." -msgstr "" +msgstr "Uwaga: żądanie z maszyny zdalnej." #, c-format msgid "error getting serial number of card: %s\n" @@ -173,20 +165,19 @@ msgstr "błąd pobierania numeru seryjnego karty: %s\n" msgid "Please re-enter this passphrase" msgstr "Proszę ponownie wprowadzić to hasło" -#, fuzzy, c-format -#| msgid "" -#| "Please enter the passphrase to protect the imported object within the " -#| "GnuPG system." +#, c-format msgid "" "Please enter the passphrase to protect the imported object within the %s " "system." msgstr "" -"Proszę wprowadzić hasło do zabezpieczenia ważnego obiektu w systemie GnuPG." +"Proszę wprowadzić hasło do zabezpieczenia importowanego obiektu w systemie %s." msgid "" "This key (or subkey) is not protected with a passphrase. Please enter a new " "passphrase to export it." msgstr "" +"Ten klucz (lub podklucz) nie jest zabezpieczony hasłem. Proszę wprowadzić nowe " +"hasło, aby go wyeksportować." #, c-format msgid "ssh keys greater than %d bits are not supported\n" @@ -276,10 +267,9 @@ msgstr "PIN nie powtórzony poprawnie; spróbuj jeszcze raz" msgid "Please enter the PIN%s%s%s to unlock the card" msgstr "Proszę wprowadzić PIN%s%s%s aby odblokować kartę" -#, fuzzy, c-format -#| msgid "error writing to %s: %s\n" +#, c-format msgid "error writing to pipe: %s\n" -msgstr "błąd zapisu do %s: %s\n" +msgstr "błąd zapisu do potoku: %s\n" msgid "Enter new passphrase" msgstr "Wprowadź nowe hasło" @@ -334,10 +324,8 @@ msgstr "Proszę wprowadzić hasło do%0Azabezpieczenia swojego nowego klucza" msgid "Please enter the new passphrase" msgstr "Proszę wprowadzić nowe hasło" -#, fuzzy -#| msgid "Options useful for debugging" msgid "Options used for startup" -msgstr "Opcje przydatne do diagnostyki" +msgstr "Opcje używane przy uruchamianiu" msgid "run in daemon mode (background)" msgstr "uruchomienie w trybie demona (w tle)" @@ -378,10 +366,8 @@ msgstr "nieużywanie SCdaemona" msgid "|PGM|use PGM as the SCdaemon program" msgstr "|PGM|użycie PGM jako programu SCdaemon" -#, fuzzy -#| msgid "|PGM|use PGM as the SCdaemon program" msgid "|PGM|use PGM as the tpm2daemon program" -msgstr "|PGM|użycie PGM jako programu SCdaemon" +msgstr "|PGM|użycie PGM jako programu tpm2daemon" msgid "|NAME|accept some commands via NAME" msgstr "|NAZWA|przyjęcie poleceń poprzez NAZWĘ" @@ -401,10 +387,8 @@ msgstr "|ALGO|użycie ALGO do wyświetlania odcisków ssh" msgid "enable putty support" msgstr "włączenie obsługi putty" -#, fuzzy -#| msgid "enable putty support" msgid "enable Win32-OpenSSH support" -msgstr "włączenie obsługi putty" +msgstr "włączenie obsługi Win32-OpenSSH" msgid "Options controlling the security" msgstr "Opcje sterujące bezpieczeństwem" @@ -455,19 +439,17 @@ msgstr "|N|przedawnianie haseł po N dniach" msgid "do not allow the reuse of old passphrases" msgstr "niezezwalanie na ponowne użycie starych haseł" -#, fuzzy -#| msgid "Options controlling the security" msgid "Options controlling the PIN-Entry" -msgstr "Opcje sterujące bezpieczeństwem" +msgstr "Opcje sterujące PIN-Entry" msgid "never use the PIN-entry" -msgstr "" +msgstr "bez używania PIN-entry" msgid "disallow caller to override the pinentry" msgstr "niezezwalanie wywołującym na nadpisywanie pinentry" msgid "let PIN-Entry grab keyboard and mouse" -msgstr "" +msgstr "zezwolenie PIN-Entry na przechwycenie klawiatury i myszy" msgid "|PGM|use PGM as the PIN-Entry program" msgstr "|PGM|użycie PGM jako programu do wprowadzania PIN-u" @@ -524,7 +506,7 @@ msgstr "nazwa gniazda „%s” zbyt długa\n" #, c-format msgid "trying to steal socket from running %s\n" -msgstr "" +msgstr "próba kradzieży gniazda od działającego %s\n" #, c-format msgid "a gpg-agent is already running - not starting a new one\n" @@ -764,13 +746,9 @@ msgstr "Zmienię je później" msgid "Please insert the card with serial number" msgstr "Proszę włożyć kartę z numerem seryjnym" -#, fuzzy, c-format -#| msgid "" -#| "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want " -#| "to allow this?" +#, c-format msgid "Requested the use of key%%0A %s%%0A %s%%0ADo you want to allow this?" -msgstr "" -"Proces ssh zarządał użycia klucza%%0a %s%%0A (%s)%%0ACzy zezwolić na to?" +msgstr "Zażądano użycia klucza%%0A %s%%0A %s%%0ACzy zezwolić na to?" #, c-format msgid "" @@ -1154,19 +1132,19 @@ msgstr "niewłaściwy znak formatu radix64 %02x został pominięty\n" #, c-format msgid "Sorry, we are in batchmode - can't get input\n" -msgstr "" +msgstr "Niestety pracujemy w trybie wsadowym - nie można uzyskać wejścia\n" #, c-format msgid "Sorry, no terminal at all requested - can't get input\n" -msgstr "" +msgstr "Niestety nie żądano terminala - nie można uzyskać wejścia\n" #, c-format msgid "too many errors; giving up\n" -msgstr "" +msgstr "zbyt dużo błędów; poddaję się\n" #, c-format msgid "Control-D detected\n" -msgstr "" +msgstr "wykryto Control-D\n" #, c-format msgid "conversion from '%s' to '%s' not available\n" @@ -1341,10 +1319,9 @@ msgstr "Hasło: " msgid "%s is not compliant with %s mode\n" msgstr "%s nie jest zgodny z trybem %s\n" -#, fuzzy, c-format -#| msgid "error reading from %s: %s\n" +#, c-format msgid "error from TPM: %s\n" -msgstr "błąd odczytu z %s: %s\n" +msgstr "błąd z TPM: %s\n" #, c-format msgid "problem with the agent: %s\n" @@ -1424,7 +1401,7 @@ msgstr "wymuszono" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "" +msgstr "Proszę spróbować polecenia ,,%s'', jeśli lista nie wygląda poprawnie\n" msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Błąd: aktualnie dopuszczalne jest tylko czyste ASCII.\n" @@ -1500,20 +1477,16 @@ msgstr "błąd podczas odczytu aktualnych informacji o kluczu: %s\n" msgid "Replace existing key? (y/N) " msgstr "Zastąpić istniejący klucz? (t/N) " -#, fuzzy -#| msgid "" -#| "Note: There is no guarantee that the card supports the requested size.\n" -#| " If the key generation does not succeed, please check the\n" -#| " documentation of your card to see what sizes are allowed.\n" msgid "" "Note: There is no guarantee that the card supports the requested\n" " key type or size. If the key generation does not succeed,\n" " please check the documentation of your card to see which\n" " key types and sizes are supported.\n" msgstr "" -"Uwaga: Nie ma gwarancji, że karta obsługuje żądany rozmiar.\n" -" Jeśli tworzenie klucza nie powiedzie się, proszę sprawdzić\n" -" dokumentację karty, aby poznać dozwolone rozmiary.\n" +"Uwaga: Nie ma gwarancji, że karta obsługuje żądany typ lub rozmiar\n" +" klucza. Jeśli tworzenie klucza nie powiedzie się, proszę\n" +" sprawdzić dokumentację karty, aby poznać dozwolone typy\n" +" i rozmiary kluczy.\n" #, c-format msgid "What keysize do you want? (%u) " @@ -1626,10 +1599,9 @@ msgstr "Naprawdę przywrócić stan fabryczny? (proszę wpisać „yes”) " msgid "error for setup KDF: %s\n" msgstr "błąd przy ustawianiu KDF: %s\n" -#, fuzzy, c-format -#| msgid "error for setup KDF: %s\n" +#, c-format msgid "error for setup UIF: %s\n" -msgstr "błąd przy ustawianiu KDF: %s\n" +msgstr "błąd przy ustawianiu UIF: %s\n" msgid "quit this menu" msgstr "wyjście z tego menu" @@ -1682,21 +1654,17 @@ msgstr "odblokowanie PIN-u przy użyciu kodu resetującego" msgid "destroy all keys and data" msgstr "zniszczenie wszystkich kluczy i danych" -#, fuzzy -#| msgid "setup KDF for PIN authentication" msgid "setup KDF for PIN authentication (on/single/off)" -msgstr "ustawienie KDF do uwierzytelniania PIN-em" +msgstr "ustawienie KDF do uwierzytelniania PIN-em (on/single/off)" msgid "change the key attribute" msgstr "zmiana atrybutu klucza" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the User Interaction Flag" -msgstr "zmiana zaufania właściciela" +msgstr "zmiana flagi interakcji użytkownika (UIF)" msgid "switch to the OpenPGP app" -msgstr "" +msgstr "przełączenie na aplikację OpenPGP" msgid "gpg/card> " msgstr "gpg/karta> " @@ -1820,16 +1788,13 @@ msgstr "OSTRZEŻENIE: klucz %s nie nadaje się do szyfrowania w trybie %s\n" msgid "error creating passphrase: %s\n" msgstr "błąd podczas tworzenia hasła: %s\n" -#, fuzzy, c-format -#| msgid "can't use a symmetric ESK packet due to the S2K mode\n" +#, c-format msgid "can't use a SKESK packet due to the S2K mode\n" -msgstr "" -"ustawiony tryb S2K nie pozwala użyć pakietu ESK dla szyfru symetrycznego\n" +msgstr "nie można użyć pakietu SKESK ze względu na tryb S2K\n" -#, fuzzy, c-format -#| msgid "using cipher %s\n" +#, c-format msgid "using cipher %s.%s\n" -msgstr "szyfrem %s\n" +msgstr "szyfrem %s.%s\n" #, c-format msgid "'%s' already compressed\n" @@ -1898,18 +1863,14 @@ msgstr "usunięcie bezużytecznych części z klucza przy eksporcie" msgid "remove as much as possible from key during export" msgstr "usunięcie jak największej części klucza przy eksporcie" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "export only revocation certificates" -msgstr "tworzenie certyfikatu unieważnienia klucza" +msgstr "eksport tylko certyfikatów unieważnienia" msgid "use the GnuPG key backup format" msgstr "użycie formatu kopii zapasowej klucza GnuPG" -#, fuzzy -#| msgid "exporting secret keys not allowed\n" msgid "export secret keys using the GnuPG format" -msgstr "eksport kluczy tajnych nie jest dozwolony\n" +msgstr "eksport kluczy tajnych przy użyciu formatu GnuPG" msgid " - skipped" msgstr " - pominięty" @@ -2127,15 +2088,11 @@ msgstr "pozostawienie bez zmian" msgid "prompt before overwriting" msgstr "pytanie przed nadpisaniem plików" -#, fuzzy -#| msgid "Options controlling the security" msgid "Options controlling the input" -msgstr "Opcje sterujące bezpieczeństwem" +msgstr "Opcje sterujące wejściem" -#, fuzzy -#| msgid "Options controlling the diagnostic output" msgid "Options controlling the output" -msgstr "Opcje sterujące wyjściem diagnostycznym" +msgstr "Opcje sterujące wyjściem" msgid "create ascii armored output" msgstr "opakowanie ASCII pliku wynikowego" @@ -2149,10 +2106,8 @@ msgstr "kanoniczny format tekstowy" msgid "|N|set compress level to N (0 disables)" msgstr "|N|ustawienie poziomu kompresji N (0 - bez)" -#, fuzzy -#| msgid "Options controlling the interactivity and enforcement" msgid "Options controlling key import and export" -msgstr "Opcje sterujące interaktywnością i wymuszaniem" +msgstr "Opcje sterujące importem i eksportem" msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address" msgstr "" @@ -2168,15 +2123,11 @@ msgstr "włączanie klucza publicznego do podpisów" msgid "disable all access to the dirmngr" msgstr "zablokuj dostęp do dirmngr" -#, fuzzy -#| msgid "Options controlling the configuration" msgid "Options controlling key listings" -msgstr "Opcje sterujące konfiguracją" +msgstr "Opcje sterujące listami kluczy" -#, fuzzy -#| msgid "list secret keys" msgid "Options to specify keys" -msgstr "lista kluczy prywatnych" +msgstr "Opcje określające klucze" msgid "|USER-ID|encrypt for USER-ID" msgstr "|UŻYTKOWNIK|szyfrowanie dla odbiorcy o tym identyfikatorze" @@ -2187,10 +2138,10 @@ msgstr "" "odszyfrowania" msgid "Options for unattended use" -msgstr "" +msgstr "Opcje użycia nieinteraktywnego" msgid "Other options" -msgstr "" +msgstr "Pozostałe opcje" msgid "" "@\n" @@ -2364,10 +2315,8 @@ msgstr "" msgid "show revoked and expired subkeys in key listings" msgstr "pokazywanie unieważnionych i wygasłych podkluczy na listach kluczy" -#, fuzzy -#| msgid "show expiration dates during signature listings" msgid "show signatures with invalid algorithms during signature listings" -msgstr "pokazywanie dat wygaśnięcia przy wypisywaniu podpisów" +msgstr "pokazywanie podpisów z niepoprawnymi algorytmami przy wypisywaniu podpisów" msgid "show the keyring name in key listings" msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy" @@ -2375,10 +2324,8 @@ msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy" msgid "show expiration dates during signature listings" msgstr "pokazywanie dat wygaśnięcia przy wypisywaniu podpisów" -#, fuzzy -#| msgid "list preferences (expert)" msgid "show preferences" -msgstr "ustawienia (zaawansowane)" +msgstr "pokazanie ustawień" #, c-format msgid "unknown TOFU policy '%s'\n" @@ -2592,10 +2539,9 @@ msgstr "niewłaściwe ustawienia skrótów\n" msgid "invalid personal compress preferences\n" msgstr "niewłaściwe ustawienia algorytmów kompresji\n" -#, fuzzy, c-format -#| msgid "keysize invalid; using %u bits\n" +#, c-format msgid "chunk size invalid - using %d\n" -msgstr "niewłaściwa długość klucza; wykorzystano %u bitów\n" +msgstr "nieprawidłowy rozmiar porcji - użycie %d\n" #, c-format msgid "%s does not yet work with %s\n" @@ -2739,18 +2685,14 @@ msgstr "nieczyszczenie wartości zaufania podczas importu" msgid "do not update the trustdb after import" msgstr "nieuaktualnianie bazy zaufania po imporcie" -#, fuzzy -#| msgid "enable putty support" msgid "enable bulk import mode" -msgstr "włączenie obsługi putty" +msgstr "włączenie trybu importu masowego" msgid "show key during import" msgstr "okazanie klucza podczas importu" -#, fuzzy -#| msgid "show key during import" msgid "show key but do not actually import" -msgstr "okazanie klucza podczas importu" +msgstr "okazanie klucza bez importowania go" msgid "only accept updates to existing keys" msgstr "przyjmowanie tylko uaktualnień istniejących kluczy" @@ -2992,7 +2934,7 @@ msgstr "klucz %s: błąd wysyłania do agenta: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" -msgstr "" +msgstr "klucz %s: odwołanie do karty nadpisane przez materiał klucza\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data @@ -3140,12 +3082,11 @@ msgstr "klucz %s: pominięto - nieoczekiwana klasa podpisu (0x%02X)\n" #, c-format msgid "key %s: duplicated user ID detected - merged\n" -msgstr "key %s: dołączono powtórzony identyfikator użytkownika\n" +msgstr "klucz %s: dołączono powtórzony identyfikator użytkownika\n" -#, fuzzy, c-format -#| msgid "key %s: duplicated user ID detected - merged\n" +#, c-format msgid "key %s: duplicated subkeys detected - merged\n" -msgstr "key %s: dołączono powtórzony identyfikator użytkownika\n" +msgstr "klucz %s: wykryto powtórzone podklucze - połączono\n" #, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" @@ -3513,7 +3454,7 @@ msgid "move a key to a smartcard" msgstr "przeniesienie klucza na kartę procesorową" msgid "convert a key to TPM form using the local TPM" -msgstr "" +msgstr "przekształcenie klucza do postaci TPM przy użyciu lokalnego TPM" msgid "move a backup key to a smartcard" msgstr "przeniesienie klucza zapasowego na kartę procesorową" @@ -3524,10 +3465,8 @@ msgstr "usunięcie wybranych podkluczy" msgid "add a revocation key" msgstr "dodanie klucza unieważniającego" -#, fuzzy -#| msgid "Data decryption succeeded" msgid "add an additional decryption subkey" -msgstr "Odszyfrowywanie danych zakończone" +msgstr "dodanie dodatkowego podklucza do odszyfrowywania" msgid "delete signatures from the selected user IDs" msgstr "usunięcie podpisów z wybranych identyfikatorów użytkownika" @@ -3595,11 +3534,9 @@ msgstr "Dostępny jest klucz tajny.\n" msgid "Secret subkeys are available.\n" msgstr "Dostępne są podklucze tajne.\n" -#, fuzzy -#| msgid "Note: Only the secret part of the shown subkey will be deleted.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "Uwaga: usunięta zostanie tylko tajna część pokazanego podklucza.\n" +msgstr "Uwaga: kopia lokalna klucza tajnego będzie usunięta tylko z \"save\".\n" msgid "Need the secret key to do this.\n" msgstr "Do wykonania tej operacji potrzebny jest klucz tajny.\n" @@ -3715,10 +3652,9 @@ msgstr "Zapisać zmiany? (t/N) " msgid "Quit without saving? (y/N) " msgstr "Wyjść bez zapisania zmian? (t/N) " -#, fuzzy, c-format -#| msgid "deleting secret %s failed: %s\n" +#, c-format msgid "deleting copy of secret key failed: %s\n" -msgstr "usunięcie %s tajnego nie powiodło się: %s\n" +msgstr "usunięcie kopii klucza tajnego nie powiodło się: %s\n" #, c-format msgid "Key not changed so no update needed.\n" @@ -3858,10 +3794,9 @@ msgstr "OSTRZEŻENIE: podklucz do szyfrowania wkrótce wygaśnie.\n" msgid "You may want to change its expiration date too.\n" msgstr "Może warto także zmienić jego datę ważności.\n" -#, fuzzy, c-format -#| msgid "WARNING: Your encryption subkey expires soon.\n" +#, c-format msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "OSTRZEŻENIE: podklucz do szyfrowania wkrótce wygaśnie.\n" +msgstr "OSTRZEŻENIE: nie pozostawiono poprawnego podklucza do szyfrowania.\n" msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " @@ -3877,10 +3812,8 @@ msgstr "Czy dalej chcesz je dodać? (t/N) " msgid "You may not add a photo ID to a PGP2-style key.\n" msgstr "Do klucza dla PGP 2.x nie można dodać zdjęcia.\n" -#, fuzzy -#| msgid "Such a user ID already exists on this key!\n" msgid "Such a user ID already exists on this key!" -msgstr "Taki identyfikator użytkownika już istnieje na tym kluczu!\n" +msgstr "Taki identyfikator użytkownika już istnieje na tym kluczu!" msgid "Delete this good signature? (y/N/q)" msgstr "Usunąć ten poprawny podpis? (t/N/w) " @@ -3962,17 +3895,15 @@ msgid "" msgstr "Czy na pewno chcesz wyznaczyć ten klucz jako unieważniający? (t/N) " msgid "Enter the fingerprint of the additional decryption subkey: " -msgstr "" +msgstr "Wprowadź odcisk klucza dodatkowego podklucza do odszyfrowywania: " -#, fuzzy, c-format -#| msgid "(unless you specify the key by fingerprint)\n" +#, c-format msgid "Did you specify the fingerprint of a subkey?\n" -msgstr "(chyba, że klucz zostaje wybrany przez podanie odcisku)\n" +msgstr "Czy podano odcisk podklucza?\n" -#, fuzzy, c-format -#| msgid "Subkey %s is already revoked.\n" +#, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "Podklucz %s jest już unieważniony.\n" +msgstr "klucz ,,%s'' jest już w tym bloku kluczy\n" msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" @@ -4138,10 +4069,9 @@ msgstr "zbyt wiele ustawień funkcji skrótu\n" msgid "too many compression preferences\n" msgstr "zbyt wiele ustawień kompresji\n" -#, fuzzy, c-format -#| msgid "too many cipher preferences\n" +#, c-format msgid "too many AEAD preferences\n" -msgstr "zbyt wiele ustawień szyfru\n" +msgstr "zbyt dużo ustawień AEAD\n" #, c-format msgid "invalid item '%s' in preference string\n" @@ -4199,10 +4129,9 @@ msgstr "Uwierzytelnianie" msgid "SsEeAaQq" msgstr "PpSsUuZz" -#, fuzzy, c-format -#| msgid "Possible actions for a %s key: " +#, c-format msgid "Possible actions for this %s key: " -msgstr "Możliwe akcje dla klucza %s: " +msgstr "Możliwe akcje dla tego klucza %s: " msgid "Current allowed actions: " msgstr "Aktualnie dopuszczalne akcje: " @@ -4521,11 +4450,11 @@ msgstr "" #, c-format msgid "WARNING: v4 is specified, but overridden by v5.\n" -msgstr "" +msgstr "UWAGA: określono wersję 4, ale została nadpisana przez 5.\n" #, c-format msgid "Key generation failed: %s\n" -msgstr "Generacja klucza nie powiodła się: %s\n" +msgstr "Generowanie klucza nie powiodło się: %s\n" #, c-format msgid "" @@ -4559,7 +4488,7 @@ msgstr "" #, c-format msgid "Key generation canceled.\n" -msgstr "Procedura generacji klucza została anulowana.\n" +msgstr "Procedura generowania klucza została anulowana.\n" #, c-format msgid "can't create backup file '%s': %s\n" @@ -4803,20 +4732,17 @@ msgstr "OSTRZEŻENIE: nie można pobrać URI %s: %s\n" msgid "weird size for an encrypted session key (%d)\n" msgstr "dziwny rozmiar jak na zaszyfrowany klucz sesyjny (%d)\n" -#, fuzzy, c-format -#| msgid "%s encrypted session key\n" +#, c-format msgid "%s.%s encrypted session key\n" -msgstr "klucz sesyjny zaszyfrowany %s\n" +msgstr "klucz sesyjny zaszyfrowany %s.%s\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s.%s encrypted data\n" -msgstr "dane zaszyfrowano za pomocą %s\n" +msgstr "dane zaszyfrowano za pomocą %s.%s\n" -#, fuzzy, c-format -#| msgid "encrypted with unknown algorithm %d\n" +#, c-format msgid "encrypted with unknown algorithm %d.%s\n" -msgstr "dane zaszyfrowano nieznanym algorytmem numer %d\n" +msgstr "zaszyfrowano nieznanym algorytmem %d.%s\n" #, c-format msgid "passphrase generated with unknown digest algorithm %d\n" @@ -4826,11 +4752,9 @@ msgstr "hasło wygenerowane nieznanym algorytmem skrótu %d\n" msgid "public key is %s\n" msgstr "klucz publiczny to %s\n" -#, fuzzy, c-format -#| msgid "encrypted with %u-bit %s key, ID %s, created %s\n" +#, c-format msgid "encrypted with %s key, ID %s, created %s\n" -msgstr "" -"zaszyfrowano %u-bitowym kluczem %s o identyfikatorze %s, stworzonym %s\n" +msgstr "zaszyfrowano kluczem %s o identyfikatorze %s, stworzonym %s\n" #, c-format msgid " \"%s\"\n" @@ -4903,7 +4827,7 @@ msgstr "błąd odszyfrowywania: %s\n" #, c-format msgid "operation forced to fail due to unfulfilled compliance rules\n" -msgstr "" +msgstr "wymuszono niepowodzenie operacji ze względu na niespełnione zasady zgodności\n" #, c-format msgid "Note: sender requested \"for-your-eyes-only\"\n" @@ -5174,10 +5098,8 @@ msgstr "Nieznane krytyczne adnotacje podpisu: " msgid "subpacket of type %d has critical bit set\n" msgstr "podpakiet typu %d ma ustawiony krytyczny bit\n" -#, fuzzy -#| msgid "Please enter the new passphrase" msgid "Please enter the passphrase for decryption." -msgstr "Proszę wprowadzić nowe hasło" +msgstr "Proszę wprowadzić hasło w celu odszyfrowania." msgid "Enter passphrase\n" msgstr "Hasło\n" @@ -5209,10 +5131,8 @@ msgstr "Czy na pewno trwale usunąć podklucz prywatny OpenPGP:" msgid "Do you really want to permanently delete the OpenPGP secret key:" msgstr "Czy na pewno trwale usunąć klucz prywatny OpenPGP:" -#, fuzzy -#| msgid "Please enter the passphrase to export the OpenPGP secret key:" msgid "Please enter the passphrase to export the secret key with keygrip:" -msgstr "Proszę wprowadzić hasło do wyeksportowania klucza prywatnego OpenPGP:" +msgstr "Proszę wprowadzić hasło do wyeksportowania klucza prywatnego z uchwytem:" #, c-format msgid "" @@ -5459,10 +5379,9 @@ msgstr "Uwaga: Ten klucz został wyłączony z użytku.\n" msgid "Note: This key has expired!\n" msgstr "Uwaga: Data ważności tego klucza upłynęła!\n" -#, fuzzy, c-format -#| msgid "WARNING: This key is not certified with a trusted signature!\n" +#, c-format msgid "WARNING: The key's User ID is not certified with a trusted signature!\n" -msgstr "OSTRZEŻENIE: Ten klucz nie jest poświadczony zaufanym podpisem!\n" +msgstr "OSTRZEŻENIE: Identyfikator użytkownika tego klucza nie jest poświadczony zaufanym podpisem!\n" #, c-format msgid "WARNING: This key is not certified with a trusted signature!\n" @@ -5482,14 +5401,13 @@ msgstr "OSTRZEŻENIE: NIE UFAMY temu kluczowi!\n" msgid " The signature is probably a FORGERY.\n" msgstr " Ten podpis prawdopodobnie jest FAŁSZYWY.\n" -#, fuzzy, c-format -#| msgid "" -#| "WARNING: This key is not certified with sufficiently trusted signatures!\n" +#, c-format msgid "" "WARNING: The key's User ID is not certified with sufficiently trusted " "signatures!\n" msgstr "" -"OSTRZEŻENIE: Tego klucza nie poświadczają wystarczająco zaufane podpisy!\n" +"OSTRZEŻENIE: Identyfikatora użytkownika tego klucza nie poświadczają " +"wystarczająco zaufane podpisy!\n" #, c-format msgid "" @@ -5605,10 +5523,9 @@ msgstr "klucz %s nie nadaje się do odszyfrowywania w trybie %s\n" msgid "anonymous recipient; trying secret key %s ...\n" msgstr "adresat anonimowy; sprawdzanie klucza tajnego %s...\n" -#, fuzzy, c-format -#| msgid "key %s is not suitable for decryption in %s mode\n" +#, c-format msgid "used key is not marked for encryption use.\n" -msgstr "klucz %s nie nadaje się do odszyfrowywania w trybie %s\n" +msgstr "używany klucz nie jest oznaczony jako przeznaczony do szyfrowania.\n" #, c-format msgid "okay, we are the anonymous recipient.\n" @@ -5779,7 +5696,7 @@ msgstr "wygenerowano słaby klucz - operacja zostaje powtórzona\n" #, c-format msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n" msgstr "" -"brak możliwości generacji dobrego klucza dla szyfru symetrycznego;\n" +"brak możliwości wygenerowania dobrego klucza dla szyfru symetrycznego;\n" "operacja była powtarzana %d razy!\n" #, c-format @@ -5920,10 +5837,9 @@ msgstr "" msgid "signing:" msgstr "podpis:" -#, fuzzy, c-format -#| msgid "%s encryption will be used\n" +#, c-format msgid "%s.%s encryption will be used\n" -msgstr "zostanie użyty szyfr %s\n" +msgstr "zostanie użyty szyfr %s.%s\n" #, c-format msgid "key is not flagged as insecure - can't use it with the faked RNG!\n" @@ -6645,53 +6561,39 @@ msgstr "%sNumer: %s%%0AWłaściciel: %s%s" msgid "Remaining attempts: %d" msgstr "Pozostało prób: %d" -#, fuzzy -#| msgid "||Please enter the PIN" msgid "|N|Please enter the new Global-PIN" -msgstr "||Proszę wpisać PIN" +msgstr "|N|Proszę wprowadzić nowy Global-PIN" -#, fuzzy -#| msgid "||Please enter the Reset Code for the card" msgid "||Please enter the Global-PIN of your PIV card" -msgstr "||Proszę wprowadzić kod resetujący dla karty" +msgstr "||Proszę wprowadzić Global-PIN karty PIV" -#, fuzzy -#| msgid "||Please enter the PIN" msgid "|N|Please enter the new PIN" -msgstr "||Proszę wpisać PIN" +msgstr "|N|Proszę wprowadzić nowy PIN" -#, fuzzy -#| msgid "||Please enter the Reset Code for the card" msgid "||Please enter the PIN of your PIV card" -msgstr "||Proszę wprowadzić kod resetujący dla karty" +msgstr "||Proszę wprowadzić PIN karty PIV" -#, fuzzy -#| msgid "|A|Please enter the Admin PIN" msgid "|N|Please enter the new Unblocking Key" -msgstr "|A|Proszę wprowadzić PIN administracyjny" +msgstr "|N|Proszę wprowadzić nowy klucz odblokowujący" -#, fuzzy -#| msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys." msgid "||Please enter the Unblocking Key of your PIV card" -msgstr "|P|Proszę wprowadzić kod odblokowujący PIN (PUK) dla zwykłych kluczy." +msgstr "||Proszę wprowadzić klucz odblokowujący karty PIV" #, c-format msgid "PIN callback returned error: %s\n" msgstr "Zapytanie zwrotne o PIN zwróciło błąd: %s\n" -#, fuzzy, c-format -#| msgid "PIN for CHV%d is too short; minimum length is %d\n" +#, c-format msgid "PIN is too short; minimum length is %d\n" -msgstr "PIN dla CHV%d jest zbyt krótki; minimalna długość to %d\n" +msgstr "PIN zbyt krótki; minimalna długość to %d\n" -#, fuzzy, c-format -#| msgid "PIN for CHV%d is too short; minimum length is %d\n" +#, c-format msgid "PIN is too long; maximum length is %d\n" -msgstr "PIN dla CHV%d jest zbyt krótki; minimalna długość to %d\n" +msgstr "PIN zbyt długi; maksymalna długość to %d\n" #, c-format msgid "PIN has invalid characters; only digits are allowed\n" -msgstr "" +msgstr "PIN ma nieprawidłowe znaki; dozwolone są tylko cyfry\n" #, c-format msgid "key already exists\n" @@ -6767,10 +6669,8 @@ msgstr "reszta RSA brakująca lub o rozmiarze innym niż %d bity\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "publiczny wykładnik RSA brakujący lub większy niż %d bity\n" -#, fuzzy -#| msgid "the NullPIN has not yet been changed\n" msgid "Note: PIN has not yet been enabled." -msgstr "NullPIN nie został jeszcze zmieniony\n" +msgstr "Uwaga: PIN nie został jeszcze włączony." #, c-format msgid "the NullPIN has not yet been changed\n" @@ -6984,7 +6884,7 @@ msgid "use variable length input for pinpad" msgstr "użycie wejścia z klawiatury czytnika o zmiennej długości" msgid "|LIST|change the application priority to LIST" -msgstr "" +msgstr "|LISTA|zmiana priorytetów aplikacji na LISTĘ" msgid "deny the use of admin card commands" msgstr "zabronienie używania poleceń karty administratora" @@ -7016,7 +6916,7 @@ msgid "error getting key usage information: %s\n" msgstr "błąd pobierania informacji o zastosowaniu klucza: %s\n" msgid "Tor might be in use - network access is limited" -msgstr "" +msgstr "Tor może być w użyciu - dostep do sieci jest ograniczony" #, c-format msgid "validation model requested by certificate: %s" @@ -7294,10 +7194,9 @@ msgstr "certyfikat nie nadaje się do szyfrowania\n" msgid "certificate is not usable for signing\n" msgstr "certyfikat nie nadaje się do podpisywania\n" -#, fuzzy, c-format -#| msgid "lookup a certificate" +#, c-format msgid "looking for another certificate\n" -msgstr "wyszukanie certyfikatu" +msgstr "wyszukanie innego certyfikatu\n" #, c-format msgid "line %d: invalid algorithm\n" @@ -7477,10 +7376,9 @@ msgstr "(to jest algorytm RC2)\n" msgid "(this does not seem to be an encrypted message)\n" msgstr "(to nie wygląda na zaszyfrowaną wiadomość)\n" -#, fuzzy, c-format -#| msgid "encrypted with %s key, ID %s\n" +#, c-format msgid "encrypted to %s key %s\n" -msgstr "zaszyfrowano kluczem %s o identyfikatorze %s\n" +msgstr "zaszyfrowano do %s kluczem %s\n" #, c-format msgid "certificate '%s' not found: %s\n" @@ -7648,10 +7546,9 @@ msgstr "błąd importu certyfikatu: %s\n" msgid "error reading input: %s\n" msgstr "błąd odczytu wejścia: %s\n" -#, fuzzy, c-format -#| msgid "no dirmngr running in this session\n" +#, c-format msgid "no keyboxd running in this session\n" -msgstr "brak działającego dirmngr w tej sesji\n" +msgstr "brak działającego keyboxd w tej sesji\n" #, c-format msgid "error opening key DB: %s\n" @@ -7740,10 +7637,9 @@ msgstr "algorytm skrótu użyty dla podpisującego %d: %s (%s)\n" msgid "checking for qualified certificate failed: %s\n" msgstr "sprawdzenie certyfikatu kwalifikowanego nie powiodło się: %s\n" -#, fuzzy, c-format -#| msgid "Signature made %s using %s key ID %s\n" +#, c-format msgid "%s/%s signature using %s key %s\n" -msgstr "Podpisano w %s kluczem %s o numerze %s\n" +msgstr "Podpis %s/%s kluczem %s %s\n" #, c-format msgid "Signature made " @@ -8269,10 +8165,8 @@ msgstr "crl_cache_insert po wystawcy nie powiodło się: %s\n" msgid "reader to file mapping table full - waiting\n" msgstr "tabela przypisań czytelników do plików pełna - oczekiwanie\n" -#, fuzzy -#| msgid "CRL access not possible due to Tor mode\n" msgid "CRL access not possible due to Tor mode" -msgstr "dostęp do CRL niemożliwy z powodu trybu Tor\n" +msgstr "dostęp do CRL niemożliwy z powodu trybu Tor" #, c-format msgid "CRL access not possible due to disabled %s\n" @@ -8425,7 +8319,7 @@ msgid "|N|do not return more than N items in one query" msgstr "|N|bez zwracania więcej niż N elementów w jednym zapytaniu" msgid "Network related options" -msgstr "" +msgstr "Opcje związane z siecią" msgid "route all network traffic via Tor" msgstr "trasowanie całego ruchu sieciowego przez Tora" @@ -8445,10 +8339,8 @@ msgstr "|URL|przekierowanie wszystkich żądań HTTP na URL" msgid "use system's HTTP proxy setting" msgstr "użycie systemowego ustawienia proxy HTTP" -#, fuzzy -#| msgid "Configuration for HTTP servers" msgid "Configuration for OpenPGP servers" -msgstr "Konfiguracja dla serwerów HTTP" +msgstr "Konfiguracja dla serwerów OpenPGP" msgid "|URL|use keyserver at URL" msgstr "|URL|używaj serwera kluczy URL" @@ -8456,10 +8348,8 @@ msgstr "|URL|używaj serwera kluczy URL" msgid "|FILE|use the CA certificates in FILE for HKP over TLS" msgstr "|PLIK|użycie certyfikatów CA w PLIKU dla HKP po TLS" -#, fuzzy -#| msgid "Configuration for HTTP servers" msgid "Configuration for X.509 servers" -msgstr "Konfiguracja dla serwerów HTTP" +msgstr "Konfiguracja dla serwerów X.509" msgid "inhibit the use of LDAP" msgstr "powstrzymanie od użycia LDAP" @@ -8662,7 +8552,7 @@ msgstr "%s:%u: podano hasło bez użytkownika\n" #, c-format msgid "%s:%u: ignoring unknown flag '%s'\n" -msgstr "" +msgstr "%s:%u: zignorowano nieznaną flagę ,,%s''\n" #, c-format msgid "%s:%u: skipping this line\n" @@ -8692,10 +8582,8 @@ msgstr "błąd odczytu z respondera: %s\n" msgid "response from server too large; limit is %d bytes\n" msgstr "odpowiedź z serwera zbyt długa; limit to %d bajtów\n" -#, fuzzy -#| msgid "OCSP request not possible due to Tor mode\n" msgid "OCSP request not possible due to Tor mode" -msgstr "żądanie OCSP niemożliwe z powodu trybu Tor\n" +msgstr "żądanie OCSP niemożliwe z powodu trybu Tor" #, c-format msgid "OCSP request not possible due to disabled HTTP\n" @@ -8902,10 +8790,8 @@ msgstr "dekodowanie otrzymanych linii danych" msgid "connect to the dirmngr" msgstr "połączenie z dirmngr" -#, fuzzy -#| msgid "connect to the dirmngr" msgid "connect to the keyboxd" -msgstr "połączenie z dirmngr" +msgstr "połączenie z keyboxd" msgid "|NAME|connect to Assuan socket NAME" msgstr "|NAZWA|połączenie z gniazdem Assuan o tej nazwie" @@ -8963,10 +8849,9 @@ msgstr "nieznane polecenie „%s”\n" msgid "sending line failed: %s\n" msgstr "wysyłanie linii nie powiodło się: %s\n" -#, fuzzy, c-format -#| msgid "no dirmngr running in this session\n" +#, c-format msgid "no keybox daemon running in this session\n" -msgstr "brak działającego dirmngr w tej sesji\n" +msgstr "brak działającego demona keybox w tej sesji\n" #, c-format msgid "error sending standard options: %s\n" @@ -8978,10 +8863,8 @@ msgstr "OpenPGP" msgid "S/MIME" msgstr "S/MIME" -#, fuzzy -#| msgid "public key is %s\n" msgid "Public Keys" -msgstr "klucz publiczny to %s\n" +msgstr "Klucze publiczne" msgid "Private Keys" msgstr "Klucze prywatne" @@ -8990,7 +8873,7 @@ msgid "Smartcards" msgstr "Karty procesorowe" msgid "TPM" -msgstr "" +msgstr "TPM" msgid "Network" msgstr "Sieć" From daedb3c96549427ed84fba5c9ab3f9475a412243 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Jan 2024 17:21:24 +0100 Subject: [PATCH 23/45] doc: Describe the ssh-agent protocol options for Windows. -- Also fix a typo in a macro. --- agent/gpg-agent.c | 4 ++-- doc/gpg-agent.texi | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 1db422737..b0150031d 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -366,7 +366,7 @@ static int putty_support; /* Path to the pipe, which handles requests from Win32-OpenSSH. */ static const char *win32_openssh_support; -#define W32_DEFAILT_AGENT_PIPE_NAME "\\\\.\\pipe\\openssh-ssh-agent" +#define W32_DEFAULT_AGENT_PIPE_NAME "\\\\.\\pipe\\openssh-ssh-agent" #endif /*HAVE_W32_SYSTEM*/ /* The list of open file descriptors at startup. Note that this list @@ -1295,7 +1295,7 @@ main (int argc, char **argv) if (pargs.r_type) win32_openssh_support = pargs.r.ret_str; else - win32_openssh_support = W32_DEFAILT_AGENT_PIPE_NAME; + win32_openssh_support = W32_DEFAULT_AGENT_PIPE_NAME; # endif break; diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 902de56f4..49cf16e39 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -623,19 +623,30 @@ are touched. @anchor{option --enable-ssh-support} @item --enable-ssh-support +@itemx --enable-win32-openssh-support @itemx --enable-putty-support @opindex enable-ssh-support +@opindex enable-win32-openssh-support @opindex enable-putty-support -The OpenSSH Agent protocol is always enabled, but @command{gpg-agent} -will only set the @code{SSH_AUTH_SOCK} variable if this flag is given. +On Unix platforms the OpenSSH Agent protocol is always enabled, but +@command{gpg-agent} will only set the @code{SSH_AUTH_SOCK} variable if +the option @option{enable-ssh-support} is given. Some Linux +distributions use the presence of this option to decide whether the +old ssh-agent shall be started. + +On Windows support for the native ssh implementation must be enabled +using the the option @option{enable-win32-openssh-support}. For using +gpg-agent as a replacement for PuTTY's Pageant, the option +@option{enable-putty-support} must be enabled. In this mode of operation, the agent does not only implement the gpg-agent protocol, but also the agent protocol used by OpenSSH -(through a separate socket). Consequently, it should be possible to use -the gpg-agent as a drop-in replacement for the well known ssh-agent. +(through a separate socket or via Named Pipes) or the protocol used by +PuTTY. Consequently, this allows to use the gpg-agent as a drop-in +replacement for the ssh-agent. -SSH Keys, which are to be used through the agent, need to be added to +SSH keys, which are to be used through the agent, need to be added to the gpg-agent initially through the ssh-add utility. When a key is added, ssh-add will ask for the password of the provided key file and send the unprotected key material to the agent; this causes the From 1a2c8267f54ba0a55fa2f87fdc19068b0088510f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Jan 2024 14:02:42 +0100 Subject: [PATCH 24/45] gpg: When using a parm file w/o usage don't set the RENC usage. * g10/keygen.c (proc_parameter_file): Don't include RENC in the default usage. -- Testplan: $ gpg --gen-key --batch <key = pSUBKEYUSAGE; r->u.usage = (is_default ? PUBKEY_USAGE_ENC - : openpgp_pk_algo_usage (algo)); + : (openpgp_pk_algo_usage (algo) + & ~PUBKEY_USAGE_RENC) ); append_to_parameter (para, r); } else if (err == -1) From 5402e6fb936d25243bf546a560b20b9e5f7b2b24 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Jan 2024 14:32:04 +0100 Subject: [PATCH 25/45] gpg: For v5 key generation for X448 also in parm file mode. * g10/keygen.c (curve_is_448): New. (do_create_from_keygrip): Pass arg keygen_flags byref so that it can be updated. Set v5 flag for X448. (gen_ecc): Ditto. (do_create): Change keygen_flags as above. For robustness change checking for Ed448. (do_generate_keypair): Change keygen_flags as above (generate_subkeypair): Ditto. (gen_card_key): Ditto. Support v5 keys. -- GnuPG-bug-id: 6942 --- g10/keygen.c | 170 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 56 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 10b81d1ee..8e50a795e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -159,7 +159,7 @@ static void do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, static int write_keyblock (iobuf_t out, kbnode_t node); static gpg_error_t gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, u32 *timestamp, - u32 expireval, int keygen_flags); + u32 expireval, int *keygen_flags); static unsigned int get_keysize_range (int algo, unsigned int *min, unsigned int *max); @@ -1266,6 +1266,39 @@ write_keybinding (ctrl_t ctrl, kbnode_t root, } +/* Returns true if SEXP specified the curve ED448 or X448. */ +static int +curve_is_448 (gcry_sexp_t sexp) +{ + gcry_sexp_t list, l2; + char *curve; + int result; + + list = gcry_sexp_find_token (sexp, "public-key", 0); + if (!list) + return 0; /* Not a public key. */ + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + if (!list) + return 0; /* Bad public key. */ + + l2 = gcry_sexp_find_token (list, "curve", 0); + gcry_sexp_release (list); + if (!l2) + return 0; /* No curve parameter. */ + curve = gcry_sexp_nth_string (l2, 1); + gcry_sexp_release (l2); + if (!curve) + return 0; /* Bad curve parameter. */ + result = (!ascii_strcasecmp (curve, "X448") + || !ascii_strcasecmp (curve, "Ed448") + || !ascii_strcasecmp (curve, "cv448")); + xfree (curve); + return result; +} + + static gpg_error_t ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) { @@ -1404,7 +1437,7 @@ static int do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip, int cardkey, kbnode_t pub_root, u32 timestamp, u32 expireval, - int is_subkey, int keygen_flags) + int is_subkey, int *keygen_flags) { int err; PACKET *pkt; @@ -1448,6 +1481,10 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, return err; } + /* For X448 we force the use of v5 packets. */ + if (curve_is_448 (s_key)) + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + /* Build a public key packet. */ pk = xtrycalloc (1, sizeof *pk); if (!pk) @@ -1458,7 +1495,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, } pk->timestamp = timestamp; - pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; + pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; if (expireval) pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; @@ -1709,12 +1746,14 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, /* - * Generate an ECC key + * Generate an ECC key. + * Note that KEYGEN_FLAGS might be updated by this function to + * indicate the forced creation of a v5 key. */ static gpg_error_t gen_ecc (int algo, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, - int keygen_flags, const char *passphrase, + int *keygen_flags, const char *passphrase, char **cache_nonce_addr, char **passwd_nonce_addr) { gpg_error_t err; @@ -1741,40 +1780,52 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, /* Note that we use the "comp" flag with EdDSA to request the use of a 0x40 compression prefix octet. */ if (algo == PUBKEY_ALGO_EDDSA && !strcmp (curve, "Ed25519")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags eddsa comp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags eddsa comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else if (algo == PUBKEY_ALGO_EDDSA && !strcmp (curve, "Ed448")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else if (algo == PUBKEY_ALGO_ECDH && !strcmp (curve, "Curve25519")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))", + { + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))", strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else if (algo == PUBKEY_ALGO_ECDH && !strcmp (curve, "X448")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } if (!keyparms) err = gpg_error_from_syserror (); @@ -1782,7 +1833,7 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, { err = common_gen (keyparms, algo, "", pub_root, timestamp, expireval, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); xfree (keyparms); } @@ -3200,11 +3251,12 @@ ask_user_id (int mode, int full, KBNODE keyblock) /* Basic key generation. Here we divert to the actual generation - routines based on the requested algorithm. */ + * routines based on the requested algorithm. KEYGEN_FLAGS might be + * updated by this function. */ static int do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expiredate, int is_subkey, - int keygen_flags, const char *passphrase, + int *keygen_flags, const char *passphrase, char **cache_nonce_addr, char **passwd_nonce_addr) { gpg_error_t err; @@ -3220,11 +3272,11 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, if (algo == PUBKEY_ALGO_ELGAMAL_E) err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); else if (algo == PUBKEY_ALGO_DSA) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA @@ -3234,7 +3286,7 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, cache_nonce_addr, passwd_nonce_addr); else if (algo == PUBKEY_ALGO_RSA) err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); else BUG(); @@ -5074,7 +5126,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, strcpy (r->u.value, curve); r->next = para; para = r; - if (!strcmp (curve, "Ed448")) + if (!strcmp (curve, "X448") || !strcmp (curve, "Ed448")) { r = xmalloc_clear (sizeof *r + 20); r->key = pVERSION; @@ -5156,7 +5208,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, strcpy (r->u.value, curve); r->next = para; para = r; - if (!strcmp (curve, "Ed448")) + if (!strcmp (curve, "X448") || !strcmp (curve, "Ed448")) { r = xmalloc_clear (sizeof *r + 20); r->key = pVERSION; @@ -5587,7 +5639,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip, cardkey, pub_root, keytimestamp, - expire, 0, keygen_flags); + expire, 0, &keygen_flags); else if (!card) err = do_create (algo, get_parameter_uint( para, pKEYLENGTH ), @@ -5595,13 +5647,13 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, keytimestamp, expire, 0, - keygen_flags, + &keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL); else err = gen_card_key (1, algo, 1, pub_root, &keytimestamp, - expire, keygen_flags); + expire, &keygen_flags); /* Get the pointer to the generated public key packet. */ if (!err) @@ -5645,7 +5697,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, { err = gen_card_key (3, get_parameter_algo (ctrl, para, pAUTHKEYTYPE, NULL ), - 0, pub_root, &authkeytimestamp, expire, keygen_flags); + 0, pub_root, &authkeytimestamp, expire, + &keygen_flags); if (!err) err = write_keybinding (ctrl, pub_root, pri_psk, NULL, PUBKEY_USAGE_AUTH, signtimestamp, cache_nonce); @@ -5667,16 +5720,18 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, key_from_hexgrip, cardkey, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), - 1, keygen_flags); + 1, &keygen_flags); else if (!card || (s = get_parameter_value (para, pCARDBACKUPKEY))) { + unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION; + err = do_create (subkey_algo, get_parameter_uint (para, pSUBKEYLENGTH), get_parameter_value (para, pSUBKEYCURVE), pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, - s? KEYGEN_FLAG_NO_PROTECTION : keygen_flags, + s? &mykeygenflags : &keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL); /* Get the pointer to the generated public subkey packet. */ @@ -5697,7 +5752,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, else { err = gen_card_key (2, subkey_algo, 0, pub_root, - &subkeytimestamp, expire, keygen_flags); + &subkeytimestamp, expire, &keygen_flags); } if (!err) @@ -6071,7 +6126,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, keyblock, keytime? keytime : cur_time, expire, 1, - keygen_flags); + &keygen_flags); } else { @@ -6087,7 +6142,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, passwd = NULL; err = do_create (algo, nbits, curve, - keyblock, cur_time, expire, 1, keygen_flags, + keyblock, cur_time, expire, 1, &keygen_flags, passwd, &cache_nonce, &passwd_nonce); } if (err) @@ -6211,7 +6266,7 @@ generate_card_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock, /* Note, that depending on the backend, the card key generation may update CUR_TIME. */ err = gen_card_key (keyno, algo, 0, pub_keyblock, &cur_time, expire, - keygen_flags); + &keygen_flags); /* Get the pointer to the generated public subkey packet. */ if (!err) { @@ -6257,11 +6312,10 @@ write_keyblock( IOBUF out, KBNODE node ) } -/* Note that timestamp is an in/out arg. - * FIXME: Does not yet support v5 keys. */ +/* Note that timestamp is an in/out arg. */ static gpg_error_t gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, - u32 *timestamp, u32 expireval, int keygen_flags) + u32 *timestamp, u32 expireval, int *keygen_flags) { #ifdef ENABLE_CARD_SUPPORT gpg_error_t err; @@ -6325,6 +6379,10 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, return err; } + /* Force creation of v5 keys for X448. */ + if (curve_is_448 (s_key)) + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + if (algo == PUBKEY_ALGO_RSA) err = key_from_sexp (pk->pkey, s_key, "public-key", "ne"); else if (algo == PUBKEY_ALGO_ECDSA @@ -6343,7 +6401,7 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, } pk->timestamp = *timestamp; - pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; + pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; if (expireval) pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; From cb8eb366cb009b66af95c7b5a147db4c6a651e40 Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Thu, 18 Jan 2024 11:23:51 +0100 Subject: [PATCH 26/45] Pass PINENTRY_GEOM_HINT environment variable to pinentry * common/session-env.c: Add PINENTRY_GEOM_HINT to variables. -- GnuPG-Bug-ID: 6930 --- common/session-env.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/session-env.c b/common/session-env.c index f07d9d101..e774c1d9b 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -84,9 +84,10 @@ static struct modules (eg "xim"). */ { "INSIDE_EMACS" }, /* Set by Emacs before running a process. */ - { "PINENTRY_USER_DATA", "pinentry-user-data"} + { "PINENTRY_USER_DATA", "pinentry-user-data"}, /* Used for communication with non-standard Pinentries. */ + { "PINENTRY_GEOM_HINT" } /* Used to pass window information. */ }; From c8060a8f23a72cab399c4d7212c97529ae83ba34 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 19 Jan 2024 12:40:58 +0100 Subject: [PATCH 27/45] doc: Document Backup-info in keyformat.txt -- This name is used by Kleopatra for quite some time now but was missing a specification. --- agent/keyformat.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/agent/keyformat.txt b/agent/keyformat.txt index fbe999ca1..e0c4df0f0 100644 --- a/agent/keyformat.txt +++ b/agent/keyformat.txt @@ -155,6 +155,16 @@ This field is for card key. If given and the value is "yes" dialog window when card is not available. When the value is "no", a card operation is refused with GPG_ERR_UNUSABLE_SECKEY error. +*** Backup-info +This gives information for a backup of the key. The follwoing fields +are space delimited: + +- Hexified keygrip (uppercase) to make it easy to identify the + filename. When restoring software should make sure that the keygrip + matches the one derived from the "Key" field. +- Backup time in as ISO string. +- Name of the backup software. +- Arbitrary information. * Private Key Format ** Unprotected Private Key Format From adeb17e37588cf88300a2df91a4ec2ec34fccec7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Jan 2024 18:05:46 +0100 Subject: [PATCH 28/45] card: New subcommand "checkkeys". * agent/command.c (cmd_havekey): Add new option --info. * tools/card-call-scd.c (scd_readkey): Allow using without result arg. (struct havekey_status_parm_s): New. (havekey_status_cb): New. (scd_havekey_info): New. (scd_delete_key): New. * tools/gpg-card.c (print_keygrip): Add arg with_lf. (cmd_checkkeys): New. (cmdCHECKKEYS): New. (cmds): Add command "checkkeys". (dispatch_command, interactive_loop): Call cmd_checkkeys. -- GnuPG-bug-id: 6943 --- agent/command.c | 44 ++++++++++++-- tools/card-call-scd.c | 92 +++++++++++++++++++++++++++- tools/gpg-card.c | 138 +++++++++++++++++++++++++++++++++++++++++- tools/gpg-card.h | 2 + 4 files changed, 265 insertions(+), 11 deletions(-) diff --git a/agent/command.c b/agent/command.c index b7a71cbe5..da91053d8 100644 --- a/agent/command.c +++ b/agent/command.c @@ -634,10 +634,12 @@ cmd_marktrusted (assuan_context_t ctx, char *line) static const char hlp_havekey[] = "HAVEKEY \n" "HAVEKEY --list[=]\n" + "HAVEKEY --info \n" "\n" "Return success if at least one of the secret keys with the given\n" "keygrips is available. With --list return all available keygrips\n" - "as binary data; with bail out at this number of keygrips"; + "as binary data; with bail out at this number of keygrips.\n" + "In --info mode check just one keygrip."; static gpg_error_t cmd_havekey (assuan_context_t ctx, char *line) { @@ -645,7 +647,8 @@ cmd_havekey (assuan_context_t ctx, char *line) gpg_error_t err; unsigned char grip[20]; char *p; - int list_mode; /* Less than 0 for no limit. */ + int list_mode = 0; /* Less than 0 for no limit. */ + int info_mode = 0; int counter; char *dirname; gnupg_dir_t dir; @@ -653,15 +656,46 @@ cmd_havekey (assuan_context_t ctx, char *line) char hexgrip[41]; struct card_key_info_s *keyinfo_on_cards, *l; - if (has_option_name (line, "--list")) + if (has_option (line, "--info")) + info_mode = 1; + else if (has_option_name (line, "--list")) { if ((p = option_value (line, "--list"))) list_mode = atoi (p); else list_mode = -1; } - else - list_mode = 0; + + line = skip_options (line); + + + if (info_mode) + { + int keytype; + const char *infostring; + + ctrl = assuan_get_pointer (ctx); + + err = parse_keygrip (ctx, line, grip); + if (err) + goto leave; + + err = agent_key_info_from_file (ctrl, grip, &keytype, NULL, NULL); + if (err) + goto leave; + + switch (keytype) + { + case PRIVATE_KEY_CLEAR: + case PRIVATE_KEY_OPENPGP_NONE: infostring = "clear"; break; + case PRIVATE_KEY_PROTECTED: infostring = "protected"; break; + case PRIVATE_KEY_SHADOWED: infostring = "shadowed"; break; + default: infostring = "unknown"; break; + } + + err = agent_write_status (ctrl, "KEYFILEINFO", infostring, NULL); + goto leave; + } if (!list_mode) diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 34b03e694..f6ce565c3 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -1529,14 +1529,16 @@ scd_readkey (const char *keyrefstr, int create_shadow, gcry_sexp_t *r_result) unsigned char *buf; size_t len, buflen; - *r_result = NULL; + if (r_result) + *r_result = NULL; err = start_agent (0); if (err) return err; init_membuf (&data, 1024); if (create_shadow) - snprintf (line, DIM(line), "READKEY --card -- %s", keyrefstr); + snprintf (line, DIM(line), "READKEY %s--card -- %s", + r_result? "" : "--no-data ", keyrefstr); else snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr); err = assuan_transact (agent_ctx, line, @@ -1552,7 +1554,7 @@ scd_readkey (const char *keyrefstr, int create_shadow, gcry_sexp_t *r_result) if (!buf) return gpg_error_from_syserror (); - err = gcry_sexp_new (r_result, buf, buflen, 0); + err = r_result ? gcry_sexp_new (r_result, buf, buflen, 0) : 0; xfree (buf); return err; @@ -1769,6 +1771,90 @@ agent_get_s2k_count (void) } + +struct havekey_status_parm_s +{ + char *string; +}; + +static gpg_error_t +havekey_status_cb (void *opaque, const char *line) +{ + struct havekey_status_parm_s *parm = opaque; + const char *s; + char *p; + + if ((s = has_leading_keyword (line, "KEYFILEINFO"))) + { + xfree (parm->string); + parm->string = xtrystrdup (s); + if (!parm->string) + return gpg_error_from_syserror (); + p = strchr (parm->string, ' '); + if (p) + *p = 0; + } + + return 0; +} + + +/* Run the HAVEKEY --info command and stores the retrieved string at + * R_RESULT. Caller must free that string. If an error is returned + * R_RESULT is set to NULL. */ +gpg_error_t +scd_havekey_info (const unsigned char *grip, char **r_result) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + struct havekey_status_parm_s parm = {NULL}; + + *r_result = NULL; + + err = start_agent (0); + if (err) + return err; + + snprintf (line, sizeof line, "HAVEKEY --info "); + log_assert (ASSUAN_LINELENGTH > strlen(line) + 2*KEYGRIP_LEN + 10); + bin2hex (grip, KEYGRIP_LEN, line+strlen(line)); + + err = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, + havekey_status_cb, &parm); + if (err) + xfree (parm.string); + else + *r_result = parm.string; + return err; +} + + +/* Run the DELETE_KEY command. If FORCE is given the user will not be + * asked for confirmation. */ +gpg_error_t +scd_delete_key (const unsigned char *grip, int force) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + struct default_inq_parm_s dfltparm = {NULL}; + + err = start_agent (0); + if (err) + return err; + dfltparm.ctx = agent_ctx; + + snprintf (line, sizeof line, "DELETE_KEY%s ", force?" --force":""); + log_assert (ASSUAN_LINELENGTH > strlen(line) + 2*KEYGRIP_LEN + 10); + bin2hex (grip, KEYGRIP_LEN, line+strlen(line)); + + err = assuan_transact (agent_ctx, line, + NULL, NULL, default_inq_cb, &dfltparm, NULL, NULL); + return err; +} + + + /* Return a malloced string describing the statusword SW. On error * NULL is returned. */ char * diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 4b0457ab9..442acdc84 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -582,13 +582,14 @@ print_shax_fpr (estream_t fp, const unsigned char *fpr, unsigned int fprlen) /* Print the keygrip GRP. */ static void -print_keygrip (estream_t fp, const unsigned char *grp) +print_keygrip (estream_t fp, const unsigned char *grp, int with_lf) { int i; for (i=0; i < 20 ; i++, grp++) tty_fprintf (fp, "%02X", *grp); - tty_fprintf (fp, "\n"); + if (with_lf) + tty_fprintf (fp, "\n"); } @@ -700,7 +701,7 @@ list_one_kinfo (card_info_t info, key_info_t kinfo, goto leave; } - print_keygrip (fp, kinfo->grip); + print_keygrip (fp, kinfo->grip, 1); tty_fprintf (fp, " keyref .....: %s", kinfo->keyref); if (kinfo->usage) { @@ -1376,6 +1377,133 @@ cmd_list (card_info_t info, char *argstr) } + +/* The CHECKKEYS command. */ +static gpg_error_t +cmd_checkkeys (card_info_t callerinfo, char *argstr) +{ + gpg_error_t err; + estream_t fp = opt.interactive? NULL : es_stdout; + strlist_t cards = NULL; + strlist_t sl; + int opt_ondisk; + int opt_delete_clear; + int opt_delete_protected; + int delete_count = 0; + struct card_info_s info_buffer = { 0 }; + card_info_t info = &info_buffer; + key_info_t kinfo; + + + if (!callerinfo) + return print_help + ("CHECKKEYS [--ondisk] [--delete-clear-copy]\n\n" + "Print a list of keys on all inserted cards. With --ondisk only\n" + "keys are listed which also have a copy on disk. Missing shadow\n" + "keys are created. With --delete-clear, copies of keys also stored\n" + "on disk without any protection will be deleted.\n" + , 0); + + + opt_ondisk = has_leading_option (argstr, "--ondisk"); + opt_delete_clear = has_leading_option (argstr, "--delete-clear-copy"); + opt_delete_protected = has_leading_option (argstr, "--delete-protected-copy"); + argstr = skip_options (argstr); + + if (*argstr) + { + /* No args expected */ + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (!callerinfo->serialno) + { + /* This is probably the first call We need to send a SERIALNO + * command to scdaemon so that our session knows all cards. */ + err = scd_serialno (NULL, NULL); + if (err) + goto leave; + } + + /* Get the list of all cards. */ + err = scd_cardlist (&cards); + if (err) + goto leave; + + /* Loop over all cards. We use our own info buffer here. */ + for (sl = cards; sl; sl = sl->next) + { + err = scd_switchcard (sl->d); + if (err) + { + log_error ("Error switching to card %s: %s\n", + sl->d, gpg_strerror (err)); + continue; + } + release_card_info (info); + err = scd_learn (info, 0); + if (err) + { + log_error ("Error getting infos from card %s: %s\n", + sl->d, gpg_strerror (err)); + continue; + } + + for (kinfo = info->kinfo; kinfo; kinfo = kinfo->next) + { + char *infostr; + + err = scd_havekey_info (kinfo->grip, &infostr); + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + { + /* Create a shadow key and try again. */ + scd_readkey (kinfo->keyref, 1, NULL); + err = scd_havekey_info (kinfo->grip, &infostr); + } + if (err) + log_error ("Error getting infos for a key: %s\n", + gpg_strerror (err)); + + if (opt_ondisk && infostr && !strcmp (infostr, "shadowed")) + ; /* Don't print this one. */ + else + { + tty_fprintf (fp, "%s %s ", + nullnone (info->serialno), + app_type_string (info->apptype)); + print_keygrip (fp, kinfo->grip, 0); + tty_fprintf (fp, " %s %s\n", + kinfo->keyref, infostr? infostr: "error"); + } + if (infostr + && ((opt_delete_clear && !strcmp (infostr, "clear")) + || (opt_delete_protected && !strcmp (infostr, "protected")))) + { + err = scd_delete_key (kinfo->grip, 0); + if (err) + log_error ("Error deleting a key copy: %s\n", + gpg_strerror (err)); + else + delete_count++; + } + xfree (infostr); + } + } + if (delete_count) + log_info ("Number of deleted key copies: %d\n", delete_count); + + err = 0; + + leave: + release_card_info (info); + free_strlist (cards); + /* Better reset to the original card. */ + scd_learn (callerinfo, 0); + return err; +} + + /* The VERIFY command. */ static gpg_error_t @@ -3726,6 +3854,7 @@ enum cmdids cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, cmdREADCERT, cmdWRITEKEY, cmdUNBLOCK, cmdFACTRST, cmdKDFSETUP, cmdUIF, cmdAUTH, cmdYUBIKEY, cmdAPDU, cmdGPG, cmdGPGSM, cmdHISTORY, + cmdCHECKKEYS, cmdINVCMD }; @@ -3765,6 +3894,7 @@ static struct { "readcert", cmdREADCERT, N_("read a certificate from a data object")}, { "writecert", cmdWRITECERT, N_("store a certificate to a data object")}, { "writekey", cmdWRITEKEY, N_("store a private key to a data object")}, + { "checkkeys", cmdCHECKKEYS, N_("run various checks on the keys")}, { "yubikey", cmdYUBIKEY, N_("Yubikey management commands")}, { "gpg", cmdGPG, NULL}, { "gpgsm", cmdGPGSM, NULL}, @@ -3901,6 +4031,7 @@ dispatch_command (card_info_t info, const char *orig_command) case cmdGPG: err = cmd_gpg (info, argstr, 0); break; case cmdGPGSM: err = cmd_gpg (info, argstr, 1); break; case cmdHISTORY: err = 0; break; /* Only used in interactive mode. */ + case cmdCHECKKEYS: err = cmd_checkkeys (info, argstr); break; case cmdINVCMD: default: @@ -4160,6 +4291,7 @@ interactive_loop (void) case cmdGPG: err = cmd_gpg (info, argstr, 0); break; case cmdGPGSM: err = cmd_gpg (info, argstr, 1); break; case cmdHISTORY: err = cmd_history (info, argstr); break; + case cmdCHECKKEYS: err = cmd_checkkeys (info, argstr); break; case cmdINVCMD: default: diff --git a/tools/gpg-card.h b/tools/gpg-card.h index 86b63cda0..5b49ef31e 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -246,6 +246,8 @@ gpg_error_t scd_cardlist (strlist_t *result); gpg_error_t scd_applist (strlist_t *result, int all); gpg_error_t scd_change_pin (const char *pinref, int reset_mode, int nullpin); gpg_error_t scd_checkpin (const char *serialno); +gpg_error_t scd_havekey_info (const unsigned char *grip, char **r_result); +gpg_error_t scd_delete_key (const unsigned char *grip, int force); unsigned long agent_get_s2k_count (void); From ee56f71c8a68d909d99062e96c23ffe9f8533b2b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Jan 2024 18:34:19 +0100 Subject: [PATCH 29/45] gpg: Add a communication object to the key generation code. * g10/keygen.c (struct common_gen_cb_parm_s): New. (common_gen): Add args common_gen_cb and common_gen_cb_parm. Adjust all callers. (do_generate_keypair): Clarify the code by using a better var name. -- We may eventually also replace the long arg list with that object. The immediate reason for this change is the followup commit. --- g10/keygen.c | 94 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 8e50a795e..886c3b007 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -131,6 +131,18 @@ struct output_control_s }; +/* An object to help communicating with the actual key generation + * code. */ +struct common_gen_cb_parm_s +{ + /* This variable set to the result of agent_genkey. The callback + * may take a copy of this so that the result can be used after we + * are back from the deep key generation call stack. */ + gcry_sexp_t genkey_result; +}; +typedef struct common_gen_cb_parm_s *common_gen_cb_parm_t; + + /* FIXME: These globals vars are ugly. And using MAX_PREFS even for * aeads is useless, given that we don't expects more than a very few * algorithms. */ @@ -1531,12 +1543,17 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, } -/* Common code for the key generation function gen_xxx. */ +/* Common code for the key generation function gen_xxx. The optinal + * (COMMON_GEN_CB,COMMON_GEN_CB_PARM) can be used as communication + * object. + */ static int common_gen (const char *keyparms, int algo, const char *algoelem, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; PACKET *pkt; @@ -1553,6 +1570,18 @@ common_gen (const char *keyparms, int algo, const char *algoelem, return err; } + if (common_gen_cb && common_gen_cb_parm) + { + common_gen_cb_parm->genkey_result = s_key; + err = common_gen_cb (common_gen_cb_parm); + common_gen_cb_parm->genkey_result = NULL; + if (err) + { + gcry_sexp_release (s_key); + return err; + } + } + pk = xtrycalloc (1, sizeof *pk); if (!pk) { @@ -1605,7 +1634,9 @@ static int gen_elg (int algo, unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; char *keyparms; @@ -1647,7 +1678,8 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root, err = common_gen (keyparms, algo, "pgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -1662,7 +1694,9 @@ static gpg_error_t gen_dsa (unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; unsigned int qbits; @@ -1736,7 +1770,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -1754,7 +1789,9 @@ static gpg_error_t gen_ecc (int algo, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, int *keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { gpg_error_t err; char *keyparms; @@ -1834,7 +1871,8 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, err = common_gen (keyparms, algo, "", pub_root, timestamp, expireval, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -1849,7 +1887,9 @@ static int gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; char *keyparms; @@ -1891,7 +1931,8 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, err = common_gen (keyparms, algo, "ne", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -3257,7 +3298,9 @@ static int do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expiredate, int is_subkey, int *keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { gpg_error_t err; @@ -3273,21 +3316,25 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, if (algo == PUBKEY_ALGO_ELGAMAL_E) err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_DSA) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) err = gen_ecc (algo, curve, pub_root, timestamp, expiredate, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_RSA) err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else BUG(); @@ -5649,7 +5696,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, expire, 0, &keygen_flags, get_parameter_passphrase (para), - &cache_nonce, NULL); + &cache_nonce, NULL, + NULL, NULL); else err = gen_card_key (1, algo, 1, pub_root, &keytimestamp, @@ -5706,9 +5754,9 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, if (!err && get_parameter (para, pSUBKEYTYPE)) { + const char *cardbackupkey = NULL; int subkey_algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, NULL); - s = NULL; key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP); keygen_flags = outctrl->keygen_flags; @@ -5721,7 +5769,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, &keygen_flags); - else if (!card || (s = get_parameter_value (para, pCARDBACKUPKEY))) + else if (!card + || (cardbackupkey = get_parameter_value (para, pCARDBACKUPKEY))) { unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION; @@ -5731,9 +5780,10 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, - s? &mykeygenflags : &keygen_flags, + cardbackupkey? &mykeygenflags : &keygen_flags, get_parameter_passphrase (para), - &cache_nonce, NULL); + &cache_nonce, NULL, + NULL, NULL); /* Get the pointer to the generated public subkey packet. */ if (!err) { @@ -5744,7 +5794,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, sub_psk = node->pkt->pkt.public_key; log_assert (sub_psk); - if (s) + if (cardbackupkey) err = card_store_key_with_backup (ctrl, sub_psk, gnupg_homedir ()); } @@ -6143,7 +6193,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, err = do_create (algo, nbits, curve, keyblock, cur_time, expire, 1, &keygen_flags, - passwd, &cache_nonce, &passwd_nonce); + passwd, &cache_nonce, &passwd_nonce, NULL, NULL); } if (err) goto leave; From 18320d692cfd52df25339fcb650898f5dda0c8c6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Jan 2024 10:15:29 +0100 Subject: [PATCH 30/45] doc: Fix description of gpg --unwrap -- --- doc/gpg.texi | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 7e51aff6f..a54bc1fee 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -638,12 +638,11 @@ The @option{--dearmor} command can also be used to dearmor PEM armors. @item --unwrap @opindex unwrap -This command is similar to @option{--decrypt} with the difference that the -output is not the usual plaintext but the original message with the -encryption layer removed. Thus the output will be an OpenPGP data -structure which often means a signed OpenPGP message. Note that this -option may or may not remove a compression layer which is often found -beneath the encryption layer. +This option modifies the command @option{--decrypt} to output the +original message with the encryption layer removed. Thus the output +will be an OpenPGP data structure which often means a signed OpenPGP +message. Note that this option may or may not remove a compression +layer which is often found beneath the encryption layer. @item --tofu-policy @{auto|good|unknown|bad|ask@} @var{keys} @opindex tofu-policy From 434a641d40cbff82beb9f485e0adca72419bfdf2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Jan 2024 13:22:44 +0100 Subject: [PATCH 31/45] agent: Add "ephemeral" Assuan option. * agent/agent.h (struct ephemeral_private_key_s): New. (struct server_control_s): Add ephemeral_mode and ephemeral_keys. (GENKEY_FLAG_NO_PROTECTION, GENKEY_FLAG_PRESET): New. * agent/genkey.c (clear_ephemeral_keys): New. (store_key): Add arg ctrl and implement ephemeral_mode. Change all callers. (agent_genkey): Replace args no_protection and preset by a generic new flags arg. * agent/findkey.c (wipe_and_fclose): New. (agent_write_private_key): Add arg ctrl and implement ephemeral_mode. Change all callers. (agent_update_private_key): Ditto (read_key_file): Ditto. (agent_key_available): Ditto. * agent/command-ssh.c (card_key_available): Do not update display s/n in ephemeral mode. This is however enver triggred. * agent/gpg-agent.c (agent_deinit_default_ctrl): Cleanup ephemeral keys. * agent/command.c (cmd_genkey): Use the new flags instead of separate vars. (cmd_readkey): Create a shadow key only in non-ephemeral_mode. (cmd_getinfo): Add sub-command "ephemeral". (option_handler): Add option "ephemeral". -- The idea here that a session can be switched in an ephemeral mode which does not store or read keys from disk but keeps them local to the session. GnuPG-bug-id: 6944 --- agent/agent.h | 39 ++++- agent/command-ssh.c | 8 +- agent/command.c | 73 +++++---- agent/cvt-openpgp.c | 10 +- agent/divert-tpm2.c | 4 +- agent/findkey.c | 380 +++++++++++++++++++++++++++++++------------ agent/genkey.c | 156 +++++++++++++----- agent/gpg-agent.c | 1 + agent/learncard.c | 20 ++- agent/pksign.c | 5 +- agent/protect-tool.c | 6 +- 11 files changed, 496 insertions(+), 206 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 531fad210..f0b2a334e 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -225,6 +225,17 @@ typedef struct ssh_control_file_s *ssh_control_file_t; /* Forward reference for local definitions in call-scd.c. */ struct daemon_local_s; +/* Object to hold ephemeral secret keys. */ +struct ephemeral_private_key_s +{ + struct ephemeral_private_key_s *next; + unsigned char grip[KEYGRIP_LEN]; + unsigned char *keybuf; /* Canon-s-exp with the private key (malloced). */ + size_t keybuflen; +}; +typedef struct ephemeral_private_key_s *ephemeral_private_key_t; + + /* Collection of data per session (aka connection). */ struct server_control_s { @@ -246,6 +257,12 @@ struct server_control_s /* Private data of the daemon (call-XXX.c). */ struct daemon_local_s *d_local[DAEMON_MAX_TYPE]; + /* Linked list with ephemeral stored private keys. */ + ephemeral_private_key_t ephemeral_keys; + + /* If set functions will lookup keys in the ephemeral_keys list. */ + int ephemeral_mode; + /* Environment settings for the connection. */ session_env_t session_env; char *lc_ctype; @@ -452,7 +469,8 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t); /*-- findkey.c --*/ gpg_error_t agent_modify_description (const char *in, const char *comment, const gcry_sexp_t key, char **result); -gpg_error_t agent_write_private_key (const unsigned char *grip, +gpg_error_t agent_write_private_key (ctrl_t ctrl, + const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, @@ -477,7 +495,7 @@ gpg_error_t agent_ssh_key_from_file (ctrl_t ctrl, gcry_sexp_t *result, int *r_order); int agent_pk_get_algo (gcry_sexp_t s_key); int agent_is_tpm2_key(gcry_sexp_t s_key); -int agent_key_available (const unsigned char *grip); +int agent_key_available (ctrl_t ctrl, const unsigned char *grip); gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, int *r_keytype, unsigned char **r_shadow_info, @@ -485,7 +503,8 @@ gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, gpg_error_t agent_delete_key (ctrl_t ctrl, const char *desc_text, const unsigned char *grip, int force, int only_stubs); -gpg_error_t agent_update_private_key (const unsigned char *grip, nvc_t pk); +gpg_error_t agent_update_private_key (ctrl_t ctrl, + const unsigned char *grip, nvc_t pk); /*-- call-pinentry.c --*/ void initialize_module_call_pinentry (void); @@ -541,15 +560,21 @@ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, #define CHECK_CONSTRAINTS_NOT_EMPTY 1 #define CHECK_CONSTRAINTS_NEW_SYMKEY 2 +#define GENKEY_FLAG_NO_PROTECTION 1 +#define GENKEY_FLAG_PRESET 2 + +void clear_ephemeral_keys (ctrl_t ctrl); + int check_passphrase_constraints (ctrl_t ctrl, const char *pw, unsigned int flags, char **failed_constraint); gpg_error_t agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, char **r_passphrase); -int agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, +int agent_genkey (ctrl_t ctrl, unsigned int flags, + const char *cache_nonce, time_t timestamp, const char *keyparam, size_t keyparmlen, - int no_protection, const char *override_passphrase, - int preset, membuf_t *outbuf); + const char *override_passphrase, + membuf_t *outbuf); gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey, char **passphrase_addr); @@ -587,7 +612,7 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo, const unsigned char *s2ksalt, unsigned int s2kcount, unsigned char *key, size_t keylen); -gpg_error_t agent_write_shadow_key (const unsigned char *grip, +gpg_error_t agent_write_shadow_key (ctrl_t ctrl, const unsigned char *grip, const char *serialno, const char *keyid, const unsigned char *pkbuf, int force, const char *dispserialno); diff --git a/agent/command-ssh.c b/agent/command-ssh.c index ca3993321..189acd7f8 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2430,14 +2430,14 @@ card_key_available (ctrl_t ctrl, const struct card_key_info_s *keyinfo, } hex2bin (keyinfo->keygrip, grip, sizeof (grip)); - if ( agent_key_available (grip) ) + if (!ctrl->ephemeral_mode && agent_key_available (ctrl, grip) ) { char *dispserialno; /* (Shadow)-key is not available in our key storage. */ agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, keyinfo->keygrip); - err = agent_write_shadow_key (grip, keyinfo->serialno, + err = agent_write_shadow_key (ctrl, grip, keyinfo->serialno, keyinfo->idstr, pkbuf, 0, dispserialno); xfree (dispserialno); if (err) @@ -3222,7 +3222,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Check whether the key is already in our key storage. Don't do anything then besides (re-)adding it to sshcontrol. */ - if ( !agent_key_available (key_grip_raw) ) + if ( !agent_key_available (ctrl, key_grip_raw) ) goto key_exists; /* Yes, key is available. */ err = ssh_key_extract_comment (key, &comment); @@ -3286,7 +3286,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Store this key to our key storage. We do not store a creation * timestamp because we simply do not know. */ - err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0, + err = agent_write_private_key (ctrl, key_grip_raw, buffer, buffer_n, 0, NULL, NULL, NULL, 0); if (err) goto out; diff --git a/agent/command.c b/agent/command.c index da91053d8..20ae08e9f 100644 --- a/agent/command.c +++ b/agent/command.c @@ -251,6 +251,9 @@ reset_notify (assuan_context_t ctx, char *line) clear_nonce_cache (ctrl); + /* Note that a RESET does not clear the ephemeral store becuase + * clients are used to issue a RESET on a connection. */ + return 0; } @@ -643,15 +646,15 @@ static const char hlp_havekey[] = static gpg_error_t cmd_havekey (assuan_context_t ctx, char *line) { - ctrl_t ctrl; + ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; unsigned char grip[20]; char *p; int list_mode = 0; /* Less than 0 for no limit. */ int info_mode = 0; int counter; - char *dirname; - gnupg_dir_t dir; + char *dirname = NULL; + gnupg_dir_t dir = NULL; gnupg_dirent_t dir_entry; char hexgrip[41]; struct card_key_info_s *keyinfo_on_cards, *l; @@ -668,14 +671,11 @@ cmd_havekey (assuan_context_t ctx, char *line) line = skip_options (line); - if (info_mode) { int keytype; const char *infostring; - ctrl = assuan_get_pointer (ctx); - err = parse_keygrip (ctx, line, grip); if (err) goto leave; @@ -706,7 +706,7 @@ cmd_havekey (assuan_context_t ctx, char *line) if (err) return err; - if (!agent_key_available (grip)) + if (!agent_key_available (ctrl, grip)) return 0; /* Found. */ while (*line && *line != ' ' && *line != '\t') @@ -724,7 +724,6 @@ cmd_havekey (assuan_context_t ctx, char *line) /* List mode. */ dir = NULL; dirname = NULL; - ctrl = assuan_get_pointer (ctx); if (ctrl->restricted) { @@ -1117,26 +1116,27 @@ cmd_genkey (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - int no_protection; unsigned char *value = NULL; size_t valuelen; unsigned char *newpasswd = NULL; membuf_t outbuf; char *cache_nonce = NULL; char *passwd_nonce = NULL; - int opt_preset; int opt_inq_passwd; size_t n; char *p, *pend; const char *s; time_t opt_timestamp; int c; + unsigned int flags = 0; if (ctrl->restricted) return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); - no_protection = has_option (line, "--no-protection"); - opt_preset = has_option (line, "--preset"); + if (has_option (line, "--no-protection")) + flags |= GENKEY_FLAG_NO_PROTECTION; + if (has_option (line, "--preset")) + flags |= GENKEY_FLAG_PRESET; opt_inq_passwd = has_option (line, "--inq-passwd"); passwd_nonce = option_value (line, "--passwd-nonce"); if (passwd_nonce) @@ -1191,7 +1191,7 @@ cmd_genkey (assuan_context_t ctx, char *line) /* If requested, ask for the password to be used for the key. If this is not used the regular Pinentry mechanism is used. */ - if (opt_inq_passwd && !no_protection) + if (opt_inq_passwd && !(flags & GENKEY_FLAG_NO_PROTECTION)) { /* (N is used as a dummy) */ assuan_begin_confidential (ctx); @@ -1204,16 +1204,17 @@ cmd_genkey (assuan_context_t ctx, char *line) /* Empty password given - switch to no-protection mode. */ xfree (newpasswd); newpasswd = NULL; - no_protection = 1; + flags |= GENKEY_FLAG_NO_PROTECTION; } } else if (passwd_nonce) newpasswd = agent_get_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE); - rc = agent_genkey (ctrl, cache_nonce, opt_timestamp, - (char*)value, valuelen, no_protection, - newpasswd, opt_preset, &outbuf); + + rc = agent_genkey (ctrl, flags, cache_nonce, opt_timestamp, + (char*)value, valuelen, + newpasswd, &outbuf); leave: if (newpasswd) @@ -1317,7 +1318,7 @@ cmd_keyattr (assuan_context_t ctx, char *line) if (!err) err = nvc_set_private_key (keymeta, s_key); if (!err) - err = agent_update_private_key (grip, keymeta); + err = agent_update_private_key (ctrl, grip, keymeta); } nvc_release (keymeta); @@ -1327,6 +1328,8 @@ cmd_keyattr (assuan_context_t ctx, char *line) leave: return leave_cmd (ctx, err); } + + static const char hlp_readkey[] = "READKEY [--no-data] [--format=ssh] \n" @@ -1390,7 +1393,7 @@ cmd_readkey (assuan_context_t ctx, char *line) goto leave; } - if (agent_key_available (grip)) + if (!ctrl->ephemeral_mode && agent_key_available (ctrl, grip)) { /* (Shadow)-key is not available in our key storage. */ char *dispserialno; @@ -1398,7 +1401,7 @@ cmd_readkey (assuan_context_t ctx, char *line) bin2hex (grip, 20, hexgrip); agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); - rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0, + rc = agent_write_shadow_key (ctrl, grip, serialno, keyid, pkbuf, 0, dispserialno); xfree (dispserialno); if (rc) @@ -2934,7 +2937,7 @@ cmd_import_key (assuan_context_t ctx, char *line) } else { - if (!force && !agent_key_available (grip)) + if (!force && !agent_key_available (ctrl, grip)) err = gpg_error (GPG_ERR_EEXIST); else { @@ -2956,11 +2959,11 @@ cmd_import_key (assuan_context_t ctx, char *line) err = agent_protect (key, passphrase, &finalkey, &finalkeylen, ctrl->s2k_count); if (!err) - err = agent_write_private_key (grip, finalkey, finalkeylen, force, + err = agent_write_private_key (ctrl, grip, finalkey, finalkeylen, force, NULL, NULL, NULL, opt_timestamp); } else - err = agent_write_private_key (grip, key, realkeylen, force, + err = agent_write_private_key (ctrl, grip, key, realkeylen, force, NULL, NULL, NULL, opt_timestamp); leave: @@ -2979,7 +2982,8 @@ cmd_import_key (assuan_context_t ctx, char *line) static const char hlp_export_key[] = - "EXPORT_KEY [--cache-nonce=] [--openpgp|--mode1003] \n" + "EXPORT_KEY [--cache-nonce=] \\\n" + " [--openpgp|--mode1003] \n" "\n" "Export a secret key from the key store. The key will be encrypted\n" "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n" @@ -2987,8 +2991,8 @@ static const char hlp_export_key[] = "prior to using this command. The function takes the keygrip as argument.\n" "\n" "If --openpgp is used, the secret key material will be exported in RFC 4880\n" - "compatible passphrase-protected form. If --mode1003 is use the secret key\n" - "is exported as s-expression as storred locally. Without those options,\n" + "compatible passphrase-protected form. In --mode1003 the secret key\n" + "is exported as s-expression as stored locally. Without those options,\n" "the secret key material will be exported in the clear (after prompting\n" "the user to unlock it, if needed).\n"; static gpg_error_t @@ -3045,7 +3049,7 @@ cmd_export_key (assuan_context_t ctx, char *line) if (err) goto leave; - if (agent_key_available (grip)) + if (agent_key_available (ctrl, grip)) { err = gpg_error (GPG_ERR_NO_SECKEY); goto leave; @@ -3257,9 +3261,9 @@ cmd_keytocard (assuan_context_t ctx, char *line) if (err) goto leave; - if (agent_key_available (grip)) + if (agent_key_available (ctrl, grip)) { - err =gpg_error (GPG_ERR_NO_SECKEY); + err = gpg_error (GPG_ERR_NO_SECKEY); goto leave; } @@ -3577,7 +3581,7 @@ cmd_keytotpm (assuan_context_t ctx, char *line) if (err) goto leave; - if (agent_key_available (grip)) + if (agent_key_available (ctrl, grip)) { err =gpg_error (GPG_ERR_NO_SECKEY); goto leave; @@ -3869,6 +3873,7 @@ static const char hlp_getinfo[] = " getenv NAME - Return value of envvar NAME.\n" " connections - Return number of active connections.\n" " jent_active - Returns OK if Libgcrypt's JENT is active.\n" + " ephemeral - Returns OK if the connection is in ephemeral mode.\n" " restricted - Returns OK if the connection is in restricted mode.\n" " cmd_has_option CMD OPT\n" " - Returns OK if command CMD has option OPT.\n"; @@ -3922,6 +3927,10 @@ cmd_getinfo (assuan_context_t ctx, char *line) snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); } + else if (!strcmp (line, "ephemeral")) + { + rc = ctrl->ephemeral_mode? 0 : gpg_error (GPG_ERR_FALSE); + } else if (!strcmp (line, "restricted")) { rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_FALSE); @@ -4078,6 +4087,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->server_local->allow_fully_canceled = gnupg_compare_version (value, "2.1.0"); } + else if (!strcmp (key, "ephemeral")) + { + ctrl->ephemeral_mode = *value? atoi (value) : 0; + } else if (ctrl->restricted) { err = gpg_error (GPG_ERR_FORBIDDEN); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 6aad35bff..50755c0fd 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -969,7 +969,7 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp, int dontcare_exist, if (err) goto leave; - if (!dontcare_exist && !from_native && !agent_key_available (grip)) + if (!dontcare_exist && !from_native && !agent_key_available (ctrl, grip)) { err = gpg_error (GPG_ERR_EEXIST); goto leave; @@ -1147,14 +1147,16 @@ convert_from_openpgp_native (ctrl_t ctrl, if (!agent_protect (*r_key, passphrase, &protectedkey, &protectedkeylen, ctrl->s2k_count)) - agent_write_private_key (grip, protectedkey, protectedkeylen, 1, - NULL, NULL, NULL, 0); + agent_write_private_key (ctrl, grip, + protectedkey, + protectedkeylen, + 1, NULL, NULL, NULL, 0); xfree (protectedkey); } else { /* Empty passphrase: write key without protection. */ - agent_write_private_key (grip, + agent_write_private_key (ctrl, grip, *r_key, gcry_sexp_canon_len (*r_key, 0, NULL,NULL), 1, NULL, NULL, NULL, 0); diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index e7c6a8aae..2496d091a 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -57,7 +57,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, } len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - err = agent_write_private_key (grip, shdkey, len, 1 /*force*/, + err = agent_write_private_key (ctrl, grip, shdkey, len, 1 /*force*/, NULL, NULL, NULL, 0); xfree (shdkey); if (err) @@ -70,7 +70,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, return GPG_ERR_ENOMEM; gcry_sexp_sprint(s_key, GCRYSEXP_FMT_CANON, pkbuf, len); - err1 = agent_write_private_key (grip, pkbuf, len, 1 /*force*/, + err1 = agent_write_private_key (ctrl, grip, pkbuf, len, 1 /*force*/, NULL, NULL, NULL, 0); xfree(pkbuf); if (err1) diff --git a/agent/findkey.c b/agent/findkey.c index 4e55119e3..1f2938ea3 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -40,7 +40,7 @@ #endif -static gpg_error_t read_key_file (const unsigned char *grip, +static gpg_error_t read_key_file (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, char **r_orig_key_value); static gpg_error_t is_shadowed_key (gcry_sexp_t s_skey); @@ -73,6 +73,30 @@ fname_from_keygrip (const unsigned char *grip, int for_new) } +/* Helper until we have a "wipe" mode flag in es_fopen. */ +static void +wipe_and_fclose (estream_t fp) +{ + void *blob; + size_t blob_size; + + if (!fp) + ; + else if (es_fclose_snatch (fp, &blob, &blob_size)) + { + log_error ("error wiping buffer during fclose\n"); + es_fclose (fp); + } + else if (blob) + { + wipememory (blob, blob_size); + gpgrt_free (blob); + } +} + + + + /* Replace all linefeeds in STRING by "%0A" and return a new malloced * string. May return NULL on memory error. */ static char * @@ -110,7 +134,8 @@ linefeed_to_percent0A (const char *string) * TIMESTAMP is not zero and the key does not yet exists it will be * recorded as creation date. */ gpg_error_t -agent_write_private_key (const unsigned char *grip, +agent_write_private_key (ctrl_t ctrl, + const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, const char *dispserialno, @@ -120,7 +145,7 @@ agent_write_private_key (const unsigned char *grip, char *fname = NULL; char *tmpfname = NULL; estream_t fp = NULL; - int newkey; + int newkey = 0; nvc_t pk = NULL; gcry_sexp_t key = NULL; int removetmp = 0; @@ -134,11 +159,13 @@ agent_write_private_key (const unsigned char *grip, const char *s; int force_modify = 0; - fname = fname_from_keygrip (grip, 0); + fname = (ctrl->ephemeral_mode + ? xtrystrdup ("[ephemeral key store]") + : fname_from_keygrip (grip, 0)); if (!fname) return gpg_error_from_syserror (); - err = read_key_file (grip, &key, &pk, &orig_key_value); + err = read_key_file (ctrl, grip, &key, &pk, &orig_key_value); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -289,43 +316,99 @@ agent_write_private_key (const unsigned char *grip, goto leave; } - /* Create a temporary file for writing. */ - tmpfname = fname_from_keygrip (grip, 1); - fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; - if (!fp) + if (ctrl->ephemeral_mode) { - err = gpg_error_from_syserror (); - log_error ("can't create '%s': %s\n", tmpfname, gpg_strerror (err)); - goto leave; - } + ephemeral_private_key_t ek; + void *blob; + size_t blobsize; - err = nvc_write (pk, fp); - if (!err && es_fflush (fp)) - err = gpg_error_from_syserror (); - if (err) - { - log_error ("error writing '%s': %s\n", tmpfname, gpg_strerror (err)); - removetmp = 1; - goto leave; - } + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN)) + break; + if (!ek) + { + ek = xtrycalloc (1, sizeof *ek); + if (!ek) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (ek->grip, grip, KEYGRIP_LEN); + ek->next = ctrl->ephemeral_keys; + ctrl->ephemeral_keys = ek; + } - if (es_fclose (fp)) - { - err = gpg_error_from_syserror (); - log_error ("error closing '%s': %s\n", tmpfname, gpg_strerror (err)); - removetmp = 1; - goto leave; + fp = es_fopenmem (0, "wb,wipe"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't open memory stream: %s\n", gpg_strerror (err)); + goto leave; + } + + err = nvc_write (pk, fp); + if (err) + { + log_error ("error writing to memory stream: %s\n",gpg_strerror (err)); + goto leave; + } + + if (es_fclose_snatch (fp, &blob, &blobsize) || !blob) + { + err = gpg_error_from_syserror (); + log_error ("error getting memory stream buffer: %s\n", + gpg_strerror (err)); + /* Closing right away so that we don't try another snatch in + * the cleanup. */ + es_fclose (fp); + fp = NULL; + goto leave; + } + fp = NULL; + xfree (ek->keybuf); + ek->keybuf = blob; + ek->keybuflen = blobsize; } else - fp = NULL; - - err = gnupg_rename_file (tmpfname, fname, &blocksigs); - if (err) { - err = gpg_error_from_syserror (); - log_error ("error renaming '%s': %s\n", tmpfname, gpg_strerror (err)); - removetmp = 1; - goto leave; + /* Create a temporary file for writing. */ + tmpfname = fname_from_keygrip (grip, 1); + fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't create '%s': %s\n", tmpfname, gpg_strerror (err)); + goto leave; + } + + err = nvc_write (pk, fp); + if (!err && es_fflush (fp)) + err = gpg_error_from_syserror (); + if (err) + { + log_error ("error writing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + + if (es_fclose (fp)) + { + err = gpg_error_from_syserror (); + log_error ("error closing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + else + fp = NULL; + + err = gnupg_rename_file (tmpfname, fname, &blocksigs); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("error renaming '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } } bump_key_eventcounter (); @@ -333,7 +416,10 @@ agent_write_private_key (const unsigned char *grip, leave: if (blocksigs) gnupg_unblock_all_signals (); - es_fclose (fp); + if (ctrl->ephemeral_mode) + wipe_and_fclose (fp); + else + es_fclose (fp); if (removetmp && tmpfname) gnupg_remove (tmpfname); xfree (orig_key_value); @@ -350,7 +436,7 @@ agent_write_private_key (const unsigned char *grip, gpg_error_t -agent_update_private_key (const unsigned char *grip, nvc_t pk) +agent_update_private_key (ctrl_t ctrl, const unsigned char *grip, nvc_t pk) { gpg_error_t err; char *fname0 = NULL; /* The existing file name. */ @@ -359,6 +445,57 @@ agent_update_private_key (const unsigned char *grip, nvc_t pk) int removetmp = 0; int blocksigs = 0; + if (ctrl->ephemeral_mode) + { + ephemeral_private_key_t ek; + void *blob; + size_t blobsize; + + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN)) + break; + if (!ek) + { + err = gpg_error (GPG_ERR_ENOENT); + goto leave; + } + + fp = es_fopenmem (0, "wbx,wipe"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't open memory stream: %s\n", gpg_strerror (err)); + goto leave; + } + + err = nvc_write (pk, fp); + if (err) + { + log_error ("error writing to memory stream: %s\n",gpg_strerror (err)); + goto leave; + } + + if (es_fclose_snatch (fp, &blob, &blobsize) || !blob) + { + err = gpg_error_from_syserror (); + log_error ("error getting memory stream buffer: %s\n", + gpg_strerror (err)); + /* Closing right away so that we don't try another snatch in + * the cleanup. */ + es_fclose (fp); + fp = NULL; + goto leave; + } + fp = NULL; + /* No need to revisit the linked list because the found EK is + * not expected to change due to the other syscalls above. */ + xfree (ek->keybuf); + ek->keybuf = blob; + ek->keybuflen = blobsize; + goto leave; + } + + fname0 = fname_from_keygrip (grip, 0); if (!fname0) { @@ -404,7 +541,10 @@ agent_update_private_key (const unsigned char *grip, nvc_t pk) leave: if (blocksigs) gnupg_unblock_all_signals (); - es_fclose (fp); + if (ctrl->ephemeral_mode) + wipe_and_fclose (fp); + else + es_fclose (fp); if (removetmp && fname) gnupg_remove (fname); xfree (fname); @@ -888,17 +1028,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, * caller must free it. On failure returns an error code and stores * NULL at RESULT and R_KEYMETA. */ static gpg_error_t -read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, - char **r_orig_key_value) +read_key_file (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t *result, nvc_t *r_keymeta, char **r_orig_key_value) { gpg_error_t err; char *fname; - estream_t fp; - struct stat st; - unsigned char *buf; + estream_t fp = NULL; + unsigned char *buf = NULL; size_t buflen, erroff; - gcry_sexp_t s_skey; + nvc_t pk = NULL; char first; + size_t keybuflen; *result = NULL; if (r_keymeta) @@ -906,19 +1046,42 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, if (r_orig_key_value) *r_orig_key_value = NULL; - fname = fname_from_keygrip (grip, 0); + fname = (ctrl->ephemeral_mode + ? xtrystrdup ("[ephemeral key store]") + : fname_from_keygrip (grip, 0)); if (!fname) { - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; + } + + if (ctrl->ephemeral_mode) + { + ephemeral_private_key_t ek; + + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN) + && ek->keybuf && ek->keybuflen) + break; + if (!ek || !ek->keybuf || !ek->keybuflen) + { + err = gpg_error (GPG_ERR_ENOENT); + goto leave; + } + keybuflen = ek->keybuflen; + fp = es_fopenmem_init (0, "rb", ek->keybuf, ek->keybuflen); + } + else + { + keybuflen = 0; /* Indicates that this is not ephemeral mode. */ + fp = es_fopen (fname, "rb"); } - fp = es_fopen (fname, "rb"); if (!fp) { err = gpg_error_from_syserror (); if (gpg_err_code (err) != GPG_ERR_ENOENT) log_error ("can't open '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - return err; + goto leave; } if (es_fread (&first, 1, 1, fp) != 1) @@ -926,28 +1089,22 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, err = gpg_error_from_syserror (); log_error ("error reading first byte from '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - return err; + goto leave; } if (es_fseek (fp, 0, SEEK_SET)) { err = gpg_error_from_syserror (); log_error ("error seeking in '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - return err; + goto leave; } if (first != '(') { /* Key is in extended format. */ - nvc_t pk = NULL; int line; err = nvc_parse_private_key (&pk, &line, fp); - es_fclose (fp); if (err) log_error ("error parsing '%s' line %d: %s\n", @@ -969,9 +1126,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, if (!*r_orig_key_value) { err = gpg_error_from_syserror (); - nvc_release (pk); - xfree (fname); - return err; + goto leave; } } } @@ -979,35 +1134,31 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, } } - if (!err && r_keymeta) - *r_keymeta = pk; - else - nvc_release (pk); - xfree (fname); - return err; + goto leave; /* Ready. */ } - if (fstat (es_fileno (fp), &st)) + if (keybuflen) + buflen = keybuflen; + else { - err = gpg_error_from_syserror (); - log_error ("can't stat '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - return err; + struct stat st; + + if (fstat (es_fileno (fp), &st)) + { + err = gpg_error_from_syserror (); + log_error ("can't stat '%s': %s\n", fname, gpg_strerror (err)); + goto leave; + } + buflen = st.st_size; } - buflen = st.st_size; buf = xtrymalloc (buflen+1); if (!buf) { err = gpg_error_from_syserror (); log_error ("error allocating %zu bytes for '%s': %s\n", buflen, fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - xfree (buf); - return err; - + goto leave; } if (es_fread (buf, buflen, 1, fp) != 1) @@ -1015,25 +1166,32 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, err = gpg_error_from_syserror (); log_error ("error reading %zu bytes from '%s': %s\n", buflen, fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - xfree (buf); - return err; + goto leave; } /* Convert the file into a gcrypt S-expression object. */ - err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); - xfree (fname); - es_fclose (fp); - xfree (buf); - if (err) - { + { + gcry_sexp_t s_skey; + + err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); + if (err) log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (err)); - return err; - } - *result = s_skey; - return 0; + else + *result = s_skey; + } + + leave: + if (!err && r_keymeta) + *r_keymeta = pk; + else + nvc_release (pk); + if (ctrl->ephemeral_mode) + wipe_and_fclose (fp); + else + es_fclose (fp); + xfree (fname); + return err; } @@ -1226,7 +1384,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, if (!grip && !ctrl->have_keygrip) return gpg_error (GPG_ERR_NO_SECKEY); - err = read_key_file (grip? grip : ctrl->keygrip, &s_skey, &keymeta, NULL); + err = read_key_file (ctrl, grip? grip : ctrl->keygrip, + &s_skey, &keymeta, NULL); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -1485,7 +1644,7 @@ agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip, *result = NULL; - err = read_key_file (grip, &s_skey, r_keymeta, NULL); + err = read_key_file (ctrl, grip, &s_skey, r_keymeta, NULL); if (!err) *result = s_skey; return err; @@ -1528,7 +1687,7 @@ public_key_from_file (ctrl_t ctrl, const unsigned char *grip, if (r_sshorder) *r_sshorder = 0; - err = read_key_file (grip, &s_skey, for_ssh? &keymeta : NULL, NULL); + err = read_key_file (ctrl, grip, &s_skey, for_ssh? &keymeta : NULL, NULL); if (err) return err; @@ -1656,13 +1815,23 @@ agent_ssh_key_from_file (ctrl_t ctrl, /* Check whether the secret key identified by GRIP is available. - Returns 0 is the key is available. */ + Returns 0 is the key is available. */ int -agent_key_available (const unsigned char *grip) +agent_key_available (ctrl_t ctrl, const unsigned char *grip) { int result; char *fname; char hexgrip[40+4+1]; + ephemeral_private_key_t ek; + + if (ctrl && ctrl->ephemeral_mode) + { + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN) + && ek->keybuf && ek->keybuflen) + return 0; + return -1; + } bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); @@ -1675,7 +1844,6 @@ agent_key_available (const unsigned char *grip) } - /* Return the information about the secret key specified by the binary keygrip GRIP. If the key is a shadowed one the shadow information will be stored at the address R_SHADOW_INFO as an allocated @@ -1700,7 +1868,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, { gcry_sexp_t sexp; - err = read_key_file (grip, &sexp, NULL, NULL); + err = read_key_file (ctrl, grip, &sexp, NULL, NULL); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -1784,7 +1952,13 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, char *default_desc = NULL; int key_type; - err = read_key_file (grip, &s_skey, NULL, NULL); + if (ctrl->ephemeral_mode) + { + err = gpg_error (GPG_ERR_NO_SECKEY); + goto leave; + } + + err = read_key_file (ctrl, grip, &s_skey, NULL, NULL); if (gpg_err_code (err) == GPG_ERR_ENOENT) err = gpg_error (GPG_ERR_NO_SECKEY); if (err) @@ -1885,7 +2059,7 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, card's SERIALNO and the IDSTRING. With FORCE passed as true an existing key with the given GRIP will get overwritten. */ gpg_error_t -agent_write_shadow_key (const unsigned char *grip, +agent_write_shadow_key (ctrl_t ctrl, const unsigned char *grip, const char *serialno, const char *keyid, const unsigned char *pkbuf, int force, const char *dispserialno) @@ -1915,7 +2089,7 @@ agent_write_shadow_key (const unsigned char *grip, } len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - err = agent_write_private_key (grip, shdkey, len, force, + err = agent_write_private_key (ctrl, grip, shdkey, len, force, serialno, keyid, dispserialno, 0); xfree (shdkey); if (err) diff --git a/agent/genkey.c b/agent/genkey.c index 741c05f4f..444f89f79 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -30,14 +30,36 @@ #include "../common/exechelp.h" #include "../common/sysutils.h" -static int -store_key (gcry_sexp_t private, const char *passphrase, int force, + +void +clear_ephemeral_keys (ctrl_t ctrl) +{ + while (ctrl->ephemeral_keys) + { + ephemeral_private_key_t next = ctrl->ephemeral_keys->next; + if (ctrl->ephemeral_keys->keybuf) + { + wipememory (ctrl->ephemeral_keys->keybuf, + ctrl->ephemeral_keys->keybuflen); + xfree (ctrl->ephemeral_keys->keybuf); + } + xfree (ctrl->ephemeral_keys); + ctrl->ephemeral_keys = next; + } +} + + +/* Store the key either to a file, or in ctrl->ephemeral_mode in the + * session data. */ +static gpg_error_t +store_key (ctrl_t ctrl, gcry_sexp_t private, + const char *passphrase, int force, unsigned long s2k_count, time_t timestamp) { - int rc; + gpg_error_t err; unsigned char *buf; size_t len; - unsigned char grip[20]; + unsigned char grip[KEYGRIP_LEN]; if ( !gcry_pk_get_keygrip (private, grip) ) { @@ -49,7 +71,10 @@ store_key (gcry_sexp_t private, const char *passphrase, int force, log_assert (len); buf = gcry_malloc_secure (len); if (!buf) - return out_of_core (); + { + err = gpg_error_from_syserror (); + goto leave; + } len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len); log_assert (len); @@ -57,20 +82,56 @@ store_key (gcry_sexp_t private, const char *passphrase, int force, { unsigned char *p; - rc = agent_protect (buf, passphrase, &p, &len, s2k_count); - if (rc) - { - xfree (buf); - return rc; - } + err = agent_protect (buf, passphrase, &p, &len, s2k_count); + if (err) + goto leave; xfree (buf); buf = p; } - rc = agent_write_private_key (grip, buf, len, force, - NULL, NULL, NULL, timestamp); + if (ctrl->ephemeral_mode) + { + ephemeral_private_key_t ek; + + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN)) + break; + if (!ek) + { + ek = xtrycalloc (1, sizeof *ek); + if (!ek) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (ek->grip, grip, KEYGRIP_LEN); + ek->next = ctrl->ephemeral_keys; + ctrl->ephemeral_keys = ek; + } + if (ek->keybuf) + { + wipememory (ek->keybuf, ek->keybuflen); + xfree (ek->keybuf); + } + ek->keybuf = buf; + buf = NULL; + ek->keybuflen = len; + } + else + err = agent_write_private_key (ctrl, grip, buf, len, force, + NULL, NULL, NULL, timestamp); + + if (!err) + { + char hexgrip[2*KEYGRIP_LEN+1]; + + bin2hex (grip, KEYGRIP_LEN, hexgrip); + agent_write_status (ctrl, "KEYGRIP", hexgrip, NULL); + } + + leave: xfree (buf); - return rc; + return err; } @@ -450,16 +511,19 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, /* Generate a new keypair according to the parameters given in - KEYPARAM. If CACHE_NONCE is given first try to lookup a passphrase - using the cache nonce. If NO_PROTECTION is true the key will not - be protected by a passphrase. If OVERRIDE_PASSPHRASE is true that - passphrase will be used for the new key. If TIMESTAMP is not zero - it will be recorded as creation date of the key (unless extended - format is disabled) . */ + * KEYPARAM. If CACHE_NONCE is given first try to lookup a passphrase + * using the cache nonce. If NO_PROTECTION is true the key will not + * be protected by a passphrase. If OVERRIDE_PASSPHRASE is true that + * passphrase will be used for the new key. If TIMESTAMP is not zero + * it will be recorded as creation date of the key (unless extended + * format is disabled). In ctrl_ephemeral_mode the key is stored in + * the session data and an identifier is returned using a status + * line. */ int -agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, - const char *keyparam, size_t keyparamlen, int no_protection, - const char *override_passphrase, int preset, membuf_t *outbuf) +agent_genkey (ctrl_t ctrl, unsigned int flags, + const char *cache_nonce, time_t timestamp, + const char *keyparam, size_t keyparamlen, + const char *override_passphrase, membuf_t *outbuf) { gcry_sexp_t s_keyparam, s_key, s_private, s_public; char *passphrase_buffer = NULL; @@ -478,7 +542,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, /* Get the passphrase now, cause key generation may take a while. */ if (override_passphrase) passphrase = override_passphrase; - else if (no_protection || !cache_nonce) + else if ((flags & GENKEY_FLAG_NO_PROTECTION) || !cache_nonce) passphrase = NULL; else { @@ -486,8 +550,8 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, passphrase = passphrase_buffer; } - if (passphrase || no_protection) - ; + if (passphrase || (flags & GENKEY_FLAG_NO_PROTECTION)) + ; /* No need to ask for a passphrase. */ else { rc = agent_ask_new_passphrase (ctrl, @@ -532,11 +596,14 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, gcry_sexp_release (s_key); s_key = NULL; /* store the secret key */ - if (DBG_CRYPTO) - log_debug ("storing private key\n"); - rc = store_key (s_private, passphrase, 0, ctrl->s2k_count, timestamp); - if (!rc) + if (opt.verbose) + log_info ("storing %sprivate key\n", + ctrl->ephemeral_mode?"ephemeral ":""); + rc = store_key (ctrl, s_private, passphrase, 0, ctrl->s2k_count, timestamp); + if (!rc && !ctrl->ephemeral_mode) { + /* FIXME: or does it make sense to also cache passphrases in + * ephemeral mode using a dedicated cache? */ if (!cache_nonce) { char tmpbuf[12]; @@ -544,21 +611,23 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, cache_nonce = bin2hex (tmpbuf, 12, NULL); } if (cache_nonce - && !no_protection + && !(flags & GENKEY_FLAG_NO_PROTECTION) && !agent_put_cache (ctrl, cache_nonce, CACHE_MODE_NONCE, passphrase, ctrl->cache_ttl_opt_preset)) agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL); - if (preset && !no_protection) - { - unsigned char grip[20]; - char hexgrip[40+1]; - if (gcry_pk_get_keygrip (s_private, grip)) - { - bin2hex(grip, 20, hexgrip); - rc = agent_put_cache (ctrl, hexgrip, CACHE_MODE_ANY, passphrase, + if ((flags & GENKEY_FLAG_PRESET) + && !(flags & GENKEY_FLAG_NO_PROTECTION)) + { + unsigned char grip[20]; + char hexgrip[40+1]; + if (gcry_pk_get_keygrip (s_private, grip)) + { + bin2hex(grip, 20, hexgrip); + rc = agent_put_cache (ctrl, hexgrip, + CACHE_MODE_ANY, passphrase, ctrl->cache_ttl_opt_preset); - } - } + } + } } xfree (passphrase_buffer); passphrase_buffer = NULL; @@ -607,7 +676,8 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey, if (passphrase_addr && *passphrase_addr) { /* Take an empty string as request not to protect the key. */ - err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1, + err = store_key (ctrl, s_skey, + **passphrase_addr? *passphrase_addr:NULL, 1, ctrl->s2k_count, 0); } else @@ -623,7 +693,7 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey, L_("Please enter the new passphrase"), &pass); if (!err) - err = store_key (s_skey, pass, 1, ctrl->s2k_count, 0); + err = store_key (ctrl, s_skey, pass, 1, ctrl->s2k_count, 0); if (!err && passphrase_addr) *passphrase_addr = pass; else diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index b0150031d..a5448ac38 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1989,6 +1989,7 @@ agent_deinit_default_ctrl (ctrl_t ctrl) { unregister_progress_cb (); session_env_release (ctrl->session_env); + clear_ephemeral_keys (ctrl); xfree (ctrl->digest.data); ctrl->digest.data = NULL; diff --git a/agent/learncard.c b/agent/learncard.c index 8d80b809d..83945b8be 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -397,7 +397,7 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) for (p=item->hexgrip, i=0; i < 20; p += 2, i++) grip[i] = xtoi_2 (p); - if (!force && !agent_key_available (grip)) + if (!force && !agent_key_available (ctrl, grip)) continue; /* The key is already available. */ /* Unknown key - store it. */ @@ -408,15 +408,17 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) goto leave; } - { - char *dispserialno; + if (!ctrl->ephemeral_mode) + { + char *dispserialno; - agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, - item->hexgrip); - rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force, - dispserialno); - xfree (dispserialno); - } + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + item->hexgrip); + rc = agent_write_shadow_key (ctrl, + grip, serialno, item->id, pubkey, force, + dispserialno); + xfree (dispserialno); + } xfree (pubkey); if (rc) goto leave; diff --git a/agent/pksign.c b/agent/pksign.c index a7b5c579f..322918969 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -371,13 +371,14 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, goto leave; } - if (keyref) + if (keyref && !ctrl->ephemeral_mode) { char *dispserialno; agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); - agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, + agent_write_shadow_key (ctrl, + ctrl->keygrip, serialno, keyref, pkbuf, 0, dispserialno); xfree (dispserialno); } diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 17f6fd559..c6450a20e 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -755,8 +755,9 @@ release_passphrase (char *pw) /* Stub function. */ int -agent_key_available (const unsigned char *grip) +agent_key_available (ctrl_t ctrl, const unsigned char *grip) { + (void)ctrl; (void)grip; return -1; /* Not available. */ } @@ -814,7 +815,7 @@ agent_askpin (ctrl_t ctrl, /* Replacement for the function in findkey.c. Here we write the key * to stdout. */ gpg_error_t -agent_write_private_key (const unsigned char *grip, +agent_write_private_key (ctrl_t ctrl, const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, const char *dispserialno, time_t timestamp) @@ -822,6 +823,7 @@ agent_write_private_key (const unsigned char *grip, char hexgrip[40+4+1]; char *p; + (void)ctrl; (void)force; (void)serialno; (void)keyref; From ead2982286f8ae94e96c0da09c6ed8c294711a47 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Jan 2024 16:52:22 +0100 Subject: [PATCH 32/45] gpg: Use ephemeral mode for generating card keys. * g10/call-agent.c (agent_set_ephemeral_mode): New. * g10/keyedit.c (keyedit_menu) : Switch to ephemeral mode. * g10/keygen.c (do_generate_keypair): Switch to ephemeral mode for card keys with backup. -- GnuPG-bug-id: 6944 --- g10/call-agent.c | 39 +++++++++++++++++++++++++++++++++++++++ g10/call-agent.h | 4 ++++ g10/keyedit.c | 32 ++++++++++++++++++++++---------- g10/keygen.c | 48 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 104 insertions(+), 19 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 744c0fcb8..daf12fae7 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -3243,6 +3243,45 @@ agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify, } +/* Enable or disable the ephemeral mode. In ephemeral mode keys are + * created,searched and used in a per-session key store and not in the + * on-disk file. Set ENABLE to 1 to enable this mode, to 0 to disable + * this mode and to -1 to only query the current mode. If R_PREVIOUS + * is given the previously used state of the ephemeral mode is stored + * at that address. */ +gpg_error_t +agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous) +{ + gpg_error_t err; + + err = start_agent (ctrl, 0); + if (err) + goto leave; + + if (r_previous) + { + err = assuan_transact (agent_ctx, "GETINFO ephemeral", + NULL, NULL, NULL, NULL, NULL, NULL); + if (!err) + *r_previous = 1; + else if (gpg_err_code (err) == GPG_ERR_FALSE) + *r_previous = 0; + else + goto leave; + } + + /* Skip setting if we are only querying or if the mode is already set. */ + if (enable == -1 || (r_previous && !!*r_previous == !!enable)) + err = 0; + else + err = assuan_transact (agent_ctx, + enable? "OPTION ephemeral=1" : "OPTION ephemeral=0", + NULL, NULL, NULL, NULL, NULL, NULL); + leave: + return err; +} + + /* Return the version reported by gpg-agent. */ gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version) diff --git a/g10/call-agent.h b/g10/call-agent.h index 45af95422..1e72dc03f 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -247,6 +247,10 @@ gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify, char **cache_nonce_addr, char **passwd_nonce_addr); + +/* Set or get the ephemeral mode. */ +gpg_error_t agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous); + /* Get the version reported by gpg-agent. */ gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version); diff --git a/g10/keyedit.c b/g10/keyedit.c index a12546f71..cae0f7841 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1905,6 +1905,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, PACKET *pkt; IOBUF a; struct parse_packet_ctx_s parsectx; + int lastmode; if (!*arg_string) { @@ -1959,17 +1960,28 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, xfree (fname); node = new_kbnode (pkt); - /* Transfer it to gpg-agent which handles secret keys. */ - err = transfer_secret_keys (ctrl, NULL, node, 1, 1, 0); - - /* Treat the pkt as a public key. */ - pkt->pkttype = PKT_PUBLIC_KEY; - - /* Ask gpg-agent to store the secret key to card. */ - if (card_store_subkey (node, 0, NULL)) + err = agent_set_ephemeral_mode (ctrl, 1, &lastmode); + if (err) + log_error ("error switching to ephemeral mode: %s\n", + gpg_strerror (err)); + else { - redisplay = 1; - sec_shadowing = 1; + /* Transfer it to gpg-agent which handles secret keys. */ + err = transfer_secret_keys (ctrl, NULL, node, 1, 1, 0); + if (!err) + { + /* Treat the pkt as a public key. */ + pkt->pkttype = PKT_PUBLIC_KEY; + + /* Ask gpg-agent to store the secret key to card. */ + if (card_store_subkey (node, 0, NULL)) + { + redisplay = 1; + sec_shadowing = 1; + } + } + if (!lastmode && agent_set_ephemeral_mode (ctrl, 0, NULL)) + log_error ("error clearing the ephemeral mode\n"); } release_kbnode (node); } diff --git a/g10/keygen.c b/g10/keygen.c index 886c3b007..b263a47de 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -5754,7 +5754,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, if (!err && get_parameter (para, pSUBKEYTYPE)) { - const char *cardbackupkey = NULL; int subkey_algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, NULL); key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP); @@ -5769,22 +5768,57 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, &keygen_flags); - else if (!card - || (cardbackupkey = get_parameter_value (para, pCARDBACKUPKEY))) + else if (get_parameter_value (para, pCARDBACKUPKEY)) { + int lastmode; unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION; + err = agent_set_ephemeral_mode (ctrl, 1, &lastmode); + if (err) + log_error ("error switching to ephemeral mode: %s\n", + gpg_strerror (err)); + else + { + err = do_create (subkey_algo, + get_parameter_uint (para, pSUBKEYLENGTH), + get_parameter_value (para, pSUBKEYCURVE), + pub_root, + subkeytimestamp, + get_parameter_u32 (para, pSUBKEYEXPIRE), 1, + &mykeygenflags, + get_parameter_passphrase (para), + &cache_nonce, NULL, + NULL, NULL); + /* Get the pointer to the generated public subkey packet. */ + if (!err) + { + kbnode_t node; + + for (node = pub_root; node; node = node->next) + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + sub_psk = node->pkt->pkt.public_key; + log_assert (sub_psk); + err = card_store_key_with_backup (ctrl, + sub_psk, gnupg_homedir ()); + } + + /* Reset the ephemeral mode as needed. */ + if (!lastmode && agent_set_ephemeral_mode (ctrl, 0, NULL)) + log_error ("error clearing the ephemeral mode\n"); + } + } + else if (!card) + { err = do_create (subkey_algo, get_parameter_uint (para, pSUBKEYLENGTH), get_parameter_value (para, pSUBKEYCURVE), pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, - cardbackupkey? &mykeygenflags : &keygen_flags, + &keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL, NULL, NULL); - /* Get the pointer to the generated public subkey packet. */ if (!err) { kbnode_t node; @@ -5793,10 +5827,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) sub_psk = node->pkt->pkt.public_key; log_assert (sub_psk); - - if (cardbackupkey) - err = card_store_key_with_backup (ctrl, - sub_psk, gnupg_homedir ()); } } else From 9408c6bf51722a4b268f8fa9152998fd73695bcc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 23 Jan 2024 15:36:26 +0900 Subject: [PATCH 33/45] sm: Fix ECDH encryption with dhSinglePass-stdDH-sha384kdf-scheme. * sm/encrypt.c (ecdh_encrypt): Cipher is AES192 for id-aes192-wrap. -- Signed-off-by: NIIBE Yutaka --- sm/encrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/encrypt.c b/sm/encrypt.c index 3c43edf61..741fe6206 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -260,7 +260,7 @@ ecdh_encrypt (DEK dek, gcry_sexp_t s_pkey, gcry_sexp_t *r_encval) encr_algo_str = "1.3.132.1.11.2"; wrap_algo_str = "2.16.840.1.101.3.4.1.25"; hash_algo = GCRY_MD_SHA384; - cipher_algo = GCRY_CIPHER_AES256; + cipher_algo = GCRY_CIPHER_AES192; keylen = 24; } else From b7c15948610b8c0a94f978860ba8123082f5836e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Jan 2024 09:04:10 +0100 Subject: [PATCH 34/45] speedo: Minor fix to the install target -- --- README | 4 ++-- build-aux/speedo.mk | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index 13205c275..b979234ce 100644 --- a/README +++ b/README @@ -93,9 +93,9 @@ libraries can be installed into an arbitrary location using for example: - make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg-foo + make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24 - and adding the directory to PATH. + and adding /usr/local/gnupg24/bin to PATH. ** Specific build problems on some machines: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index be400c37a..335594b51 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -1125,13 +1125,13 @@ ifneq ($(TARGETOS),w32) fi; \ done; \ done; \ - echo "sysconfdir = /etc" >bin/gpgconf.ctl ;\ + echo "sysconfdir = /etc/gnupg" >bin/gpgconf.ctl ;\ echo "rootdir = $(idir)" >>bin/gpgconf.ctl ;\ echo "speedo: /*" ;\ echo "speedo: * Now copy $(idir)/ to the final location and" ;\ echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ echo "speedo: * Or run:" ;\ - echo "speedo: * make -f build-aux/speedo.mk install SYSROOT=/somewhere" ;\ + echo "speedo: * make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24" ;\ echo "speedo: */") endif @@ -1146,7 +1146,7 @@ ifneq ($(TARGETOS),w32) echo "speedo: ERROR: SYSROOT has not been given";\ echo "speedo: Set SYSROOT to the desired install directory";\ echo "speedo: Example:";\ - echo "speedo: make -f build-aux/speedo.mk install SYSROOT=/usr/local";\ + echo "speedo: make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24";\ exit 1;\ fi;\ if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ @@ -1170,8 +1170,8 @@ ifneq ($(TARGETOS),w32) -exec install -Dm 755 "{}" "$$SYSROOT/{}" \; ;\ find . -type f \! -executable \ -exec install -Dm 644 "{}" "$$SYSROOT/{}" \; ;\ - echo "sysconfdir = /etc" > "$$SYSROOT"/bin/gpgconf.ctl ;\ - echo "rootdir = $$SYSROOT" >> "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo "sysconfdir = /etc/gnupg" > "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo "rootdir = $$SYSROOT" >> "$$SYSROOT"/bin/gpgconf.ctl ;\ echo '/*' ;\ echo " * Installation to $$SYSROOT done" ;\ echo ' */' ) From 34d19d448dd3720bb0cdb3333e5b26d89309792d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Jan 2024 13:55:43 +0100 Subject: [PATCH 35/45] tests: Add two more sample p12 files -- GnuPG-bug-id: 6940 --- tests/cms/Makefile.am | 2 ++ tests/cms/samplekeys/Description-p12 | 12 ++++++++++++ .../credential_private_encrypted_3DES.p12 | Bin 0 -> 4220 bytes .../credential_private_encrypted_AES256.p12 | Bin 0 -> 4370 bytes 4 files changed, 14 insertions(+) create mode 100644 tests/cms/samplekeys/credential_private_encrypted_3DES.p12 create mode 100644 tests/cms/samplekeys/credential_private_encrypted_AES256.p12 diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index 557729770..f6a9c6099 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -102,6 +102,8 @@ EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ samplekeys/t6752-ov-user-ff.p12 \ samplekeys/edward.tester@demo.gnupg.com.p12 \ samplekeys/nistp256-openssl-self-signed.p12 \ + samplekeys/credential_private_encrypted_AES256.p12 \ + samplekeys/credential_private_encrypted_3DES.p12 \ samplemsgs/pwri-sample.cbc.p7m \ samplemsgs/pwri-sample.cbc-2.p7m \ samplemsgs/pwri-sample.gcm.p7m \ diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index 01276087f..7d80caa1e 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -51,4 +51,16 @@ Pass: start Cert: 4753a910e0c8b4caa8663ca0e4273a884eb5397d Key: 93be89edd11214ab74280d988a665b6beef876c5 +Name: credential_private_encrypted_AES256.p12 +Desc: AES256 encrypted P12 file from T6940 +Pass: qeFGds84/Sf0eKkJwcp6 +Cert: 20f65740b4a15bac6d6a299026756088f7604937,cbb4b26f93cfd9715ac9fa43440470df9395571b +Key: 37eedaaf317edb69029eed79f69dd479fb10bf08 + +Name: credential_private_encrypted_3DES.p12 +Desc: 3DES encrypted P12 file from T6940 +Pass: qeFGds84/Sf0eKkJwcp6 +Cert: 20f65740b4a15bac6d6a299026756088f7604937,cbb4b26f93cfd9715ac9fa43440470df9395571b +Key: 37eedaaf317edb69029eed79f69dd479fb10bf08 + # eof # diff --git a/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 b/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 new file mode 100644 index 0000000000000000000000000000000000000000..58e80467d368a991ee1142efc904b12ea8e91af8 GIT binary patch literal 4220 zcmZWrbx;%zw_RYDT$YwvO1hVB0i{D&B&4K7knRwvB_$;Vqy?l)LIeaP7F@ywq#IE> zM0Q~%K7KRbd%rjH=FXWrbIzUf=eY-lpbWytBY+_&?-7y+#A?N2$?=HriV>8eKm?`W zEzJuQQwqj=@SA1b`iDklS8&Uxb8n|5YsjIC?eS$iqKv4S!OdUI zj&qvE1tj$S;r<<26UF>_dTJ^0z^pZUZiN~@Uk$r#p*UAA+9yj6`#X!l62*2#`BnY;Da)TE3( z+S8itpyE&XQ-u3$4t4L%N3S|Elx+`C>RT7?Yio*{G?&d-E!_DlT(N+G@tfL^H35gL z0%Pdj!tNIX5Z_$B=i=l%F>->i<;IMNz`hu^QvI-@JO9uAH< zaoAs(;wAamX?wD?^&1997{h5u`)cV zO|#?F6~bRZY9}vwqwU?kydi;%$Y%~durbQ|6kDV6wMAp^1L6*_f3@q1#A9aTu7*m9 zLxE>)5?e_;3wn-EFId3eJ2MOjXz{F0CZT350<#{s7F{`-!%yRWm-GoYnGwAy$j ziq(ICDr~FPAP0R&(*#LZ-tdDf-^)~S6q`qR436m0vJXBZLjv?KZEVsFJ;FFy@Na?} z_^GC}7Y_^?ubwy492u$k@k)^GER%ZdD!6H>ToV!;y~sZ-h%o{P^B;UU*Xq!m>51{t z=y)*Hl1d5YtTH4WI)`B_`_RP#2$@a&s;{ZC+k?*7uzYppjsTPh)VH(3#eaSfCxs-j zlPv^4u)5jGn&;KvI$#W6I+FWv*zne)KMUsOqWPKqXxirCIBG{sVZW>A3 z&d}Q?FR^zbiflfms7$cTL5NJBn`qY+D$}J3U-SuGfB&RXAe~44jPQAf=l0yiNSH~v z$Vx`+c7xHxmi^TL^|!or7E2;^$PK>tsE2rB)UM`0dPdbq0Q?8urbTr|^%DEWQ`i}( z+4Kc?InjLM%lt&K-AhB6u;_$Ri|d!lSLrQ0H(vuv)zDloEcz;4H#ofO0vIe&U9y6- zzB2dq-f$-a<)J9&ye1QvXP8foQYTHf(uFAnR`t`llYnGCC0ki%)8Io}--PdFPk&2K zOtsc`{n1}dizc&)$q)CoK18!e1J7h1?GiwypR%!0dqy7Q1~ZOQP4&=jZhK6aXRODt z(LITJ7UUAXY!x$5#YQdp2!Cg!mmVw0AEtB!$5?KGGDNn4zpe%TxUIQo8shM&cPL;h z1{1jJw;>Vz)hi`xW8YKKeP2O#^4ZlBctU~Bzr7}ajRp-Kp~1Zmr`}VHtG%WAsvy}; z(*uPhTUh5NQ_JA8>X$x_-|J&l*VP$|n?5`*?60VwiV5;$ES3Ou`+d`B@E%Tj~8UcTk6v8?99%p>!trq zjKbZ|G}PPMZFdODSh#WnuZ0T-4TcpwPqu2C0cq5N&L`Eu+sNR>Y^>7$gpPf1=3+8Y z*B)hRm}_o9tMp@U!uOMFuKU#P9p5?qlNz?J*+ImC0e*YJWfv7U=eoXYWCRJL$-d>B#Ri4@XexM?C-RW!%V zpuw|x>;g*bN!sva5t{B>evD_ZpjQX+Xb^GXm28Wz=nvNh$2GeOL}leK^)EQre#nlS zn{tUCv#s9gbNQ+kL1on(Wle{C#Bql4EF-xZwr?X-?KO)41DCnb9`^2?RO{q?R00}n zIy;JG?~hH@-Xf#r({!C=)Wy?09l@{PLi39;fX8nfFd>~6oZ09GqOVK+m0`Q0Geu=D zv>6X9_@<W*sH_#@w^{{D7g z0&NUY?99&~(Sy8!fWdc3J{A}ssFiI+mA2{;o6h9?Y42`Jp*{^JW>bEAMYVY$94ozU z22w%0oDzpTU>8s|HS`L-V=ltKI%|Zp9`^F(@>ximB3DridE8Eomm%`h_{eRv+wwWz z;hK-Nf9ZmGKzLr^n`8&a=nX$PjdpBOV0Bzyb;C*_cMJV*LdUj!)w-SFA0_2lJf@2b zYT|NUT_$$?7_d*^bw3B3Z9F0pK?AC3?pRgI`5-4C`(;XFnxKUl^0EE zGs#Cx!0Ka|S~Txll`?cwZm(f0+2)0EM}?Z=@=qI6m~c^ambz?h$-+sb5_F^Q6fcCa zXX8UMc_*gFX|4B{8vo2ZD|<37BBLnc$AEqY)}o`!n@AtPVDBBti$zyq?~f{?TBclB zpWy3^&;kRE0~r|01nN)6Kb*zY4hhM2H_9>GL!9w*mE7mF4D%srBUcOY{g4oPwwX8V zi3t^1N$kAdPqeOIp>57Xg}%;+!B}9Wfj$;VF2YBUw%h>u_kVC1kYi1z{zmpoDsY9~ z<=s?YUnfjfzL1uErEfwy&V`i!b$@oj5$ll${l;D%8MZ#fz+Hm9bzPH>P6X1{-?n^h zt9zUa(oYVfLWrUG^h1ZnnFINQI={EmtqUOc_x`JDn&G{Z!!|Q@vCEkkrRSSKRZi`T2-X*~?p4SP@ zo?*~-G30OdVjXwp+kMM!n^$ zR`o8ks-f>dFAM?l`ai|A7y+^aB0$!+wD~Pe2+97Zrjp{}7bAd&Fa&V-|F_o@)xvU7 zxNqt|?G=as4ilFUW7{*+e{j@VoM7Rq7R{@dZdxIw^p`{mbstMk?njIsAfn@4blIlo zAL0Bg=5=itHZ&JE`KB4Kj>yGCSIfWr{ZMD~E;moPy+_#hhrLNxVo^{kcDXmWFZp5* zl)fL6Zmx(eOE-su@zg`&(s7ynM|!t;djqV;l-8K+z4=AzVEC}OYE{v4c2T0-L#Ij1 zh&M_ZavT>%m6o>CErVY}QM;=6NQyWU`l+OM^o3HW?EH{)*vyjTDaq&Ch(FJ6hrJ$> zv9o?v;V$Y|0bHCP?(s+bC>+}FY}G}*nB4|edXs@;`C?4ZsGM5Z%<62DZ1yw+OGSz9 zOS;z)^e9~kvORlh@Vq}oQxVc7)8Z#9ivsO25_4D^m1MXzy;~M=FCCwAzWvfwoF7=e z_q~xac#;i*rM7EKz1`c*R9ih;i@9EFA;w;&AOhmt$i5 z>&kx1l^Yg_{l!0WGl>nb4mu;)4q?@0TD=4C??0aH*eh^E$|o2+bh@I+K22V$$O!E|3K3_j5mA3RlB*{4Ucpw?5VXiM9 zG?O#Xv)8z9*~c@&PLFbYIark7R%|uAzc3M`F%FxrPQ%%>Ue4CLvt_-``}C&Iy;*bq z-d}M?#uJ`sM(~GiV;HOa1sikLqw6auI_{VK@zoCtdn|PLO_Cx5pZC2agEgBp6QY+h zV&~y=Swh88Q$?R2qV!Lb9N~qXHXmI=gK<%2>Ix;}Op5?P&tszx>Z2Ojd@Xray0Z4e z-CB!23XU`?22p%%y>YbdT$myb{iNFS$*K7@89%K}!9CHa7Hrs#%{jJ#Wi^$c)NZIA z;XD{DTGQC%mWXFKgO2ERd5cI9<sBpo8OIP&ZZzPL>eU@{rpmREEe9??nH%4pQsCeBqaF)Jr|=*$Ps6V`lG-qnq@t?B$V9(z++A6e4YN zUlj%W9?b;tR)4uHPDwAoa3=spa}Z0(y4=q5-O|PO^SRd&p}xiy>K>C>amA&NC%^oy z)(j0>i}SFQU`dwx7MtAyvXzf{?C{ZWNcGgQWAU*_!l8C;=(rT?Q9Fl&zP6QF$p@bS zHmxYhRDL?_NsYTtxftFBOg*zO#2Mx@F!$Ik$~T`z8`jl?=qO6cP#%LV7A7xN9{VPK z?O;yK%Kkk0bhG$-e=M;|21lTl2UT2hDk9qfPQdJCeaybd%d86gsh<`NrB!LRTe>Jv zd&*56-Tx|ZvEo~!x0g*TN|g*ny)blY=ObGB>Dq~pSY@I(nWWkxP-5@_CqCM_a*iR- zr0BH3O#3vifeKkIN8`w|DRHjndcq#XG0A$<<~<{EKmvDL{v&1#U;4;?9nawpyuL2Ln2Syn)0*qbutT0TKfLgzA3) D`}_k0 literal 0 HcmV?d00001 diff --git a/tests/cms/samplekeys/credential_private_encrypted_AES256.p12 b/tests/cms/samplekeys/credential_private_encrypted_AES256.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ced504c8593bc55e9d1fc4fe65b278cc1241cef0 GIT binary patch literal 4370 zcmai&bx;%x^T!W38WAK#i6alGqno2cknTo~?(_huqq_u2=@K|mQc@a^kP@Wx0F@(- z5)^oS=l7fE`SYEfot^!DcV_?F`OHEPl;pTLcn}1|AOZ1{SoPS;dpLwRB?yWZAcErk zU%3H-Ai@4?5tJZEw*N}&xHy2n<=ejw4#ec22LB%9DTMpqmJIS3NQ7!H7FhYEfRBqy z1b~nc5dGgaTw;6xgpq*QHdYQ##BICyN{=Q+xhPS+i0f%GLtSX><;yT|Oa|#hY|+QSZ(&+_0nGBI$r|nKhTa z=K(X>9>km+w|*s=X4tJ5vOXG04_?`m0(n%S&uR2b3_12EZU7}&Wd}baP6e}bnop~5 zJi_$Cy0NBHCj*^hGt!w0r{9BZWjEDf`BFl@>hFXw4r8rW_G($`JXET^uD}eUV;Z)K z=&w6XRVkF}jAtYgihA{f>Cc%Z$lX~jd@s*yWL!T@F?#V6d`RAj6TGb%d~v==sfY2i zwC{)D7~HEIi|7n}nVLbqU1)vOZc)f=(=De_RerZdJ7@GhB~T&+l+Ko5lbCUyU=xW% zV5^aRcOLn>bT%AaBJTJ~ht0J|JZb)N&m~jM6~bnId1u%S2=wk04dZCdQa%EskpbrO|*GmZ40trJou^*^R#|)^PQiy>2zG18-KP=WVMFw_R&dz*NgQR8%3M2vMZ=s zrhn5I+3l_jy}!Ywbl3IuqAZ+M%Q@Vvij7G(?uw_btxhA0UVfgcS7<-?JFku+P^4Mk zczZ-^f>VRMOXU}9%rk70^F|NObuS@QUaL)dfQt|BRS4{K$Kt0RQL$P+%sTCeM&YP$ zr;W3CBT#xo!!KiuUv`Fi>N#iKPJ0e6k$pL#8x<=#^X)lU*m+NSZ=v4GCqI7$WBzV` zm18vKn^63GD+?+o0H^*fH1#+f`;(iujbiwsuoJy z)A8c<$V#N@e6J}l4>2M2ip61btO40<&rY8 zjuj1^_36Dqqa)yL5gnV2tc|LcWUG0Pr;xvMd~sT;Rcn?XJsxERF7~O)cgOa2C4yG3 z82s!?SC*vGsA;aeNjx%h3P-*+<4enVedp>Gn(nKWba$&H(9=~Gx{&jDOeb795`LE= z0rxoveR4UunfWLzp4^iRuN2EMfIFWd7)R&Vv*f}Iyq;ihUSOu93w(szPa5=Z@=B(N zELzHAIM08St;a?)FpiEZ+&5|*dVP>s+{Me7j|kyEDXzmc4juNJY;jxQBXZGSe|QER z!+t)*bmp%!x}1*OF@(e~?7@tlJ^_e{m)v5P=DfcPsq+`Wy?C$Fs zuXfkf776a#G0l_QcS>p2qR^GEt6B6w_+*EJA4P0hy<$)B1}v3ebU#0Qqw7l#cI_(S z%pba8YbC=abrSZv!rLgn48pTY>SitelHqWcR>=TLl^2#>6>t<2*#?+6VNj@wN~`v3 zRjdx5p_f#A)F3GnY(OmR~=njjMDv9ki0j z7+yL?STU=OLkg|)wb_-y0zcUR(n}|&NRDsf&e~nC0uMWrUx%Ekd^oh?6AVX|_|Wj+ zKP3n2C&ZH!vj$ORUgwui>PWPdN%Kx71*>qut5X~Cm|Auy1A5m)+c&T$g-2V>y2y)j z3*Q~A=9QZ6;@f=@{MND!R9I-tOUKVWD=$J73t8ZaV~3dNrU= z#CW@8YETlJyd3MymV;l|gftYW2z+N%XVb!mhh~zsjfv1+QWc(+@pqofXJgc67oCuI z4RQpT7a#WviiASbni%3qdo_r=dK!^kb7B#O@B5r6JpG^Vk;uqbC`JC@T5Y$Az5J8- zZnOlPo>IsSB7dx8Jf7v;;wS+vzuQ{<71zXb(^uW32C~zd${(@^U$3a8Teenw{4m3k ztX;@Nkyzw9;>X42D5k&Lh^8aw#5F#Ti>|3MC=C6?x;@sTxOVSGs-BO`Scs{%>9vj>9QTj8M^}~KsaI? zt_=bqSDceCS&|uEaqDlfN@i^TKJW>QRqblDiwdLFGnJ*@=66ySY+~jKFIputaBI!|}_xJIY*08Mrdah|lN~O&Be8zWt2WvEKS^^} zHGb#iS@7|MM?VULgjct!yvfw_b|PZD2p_v1f-SBL0XN`YyG$sq=g~?!)|woevJX>C z4JnFdUH1Bo*1!bp-VWcM#dYe=MzHW(ZBMlnayOe6(MQ710Pxl991vuu6YIzHU2IXJ4LBcrJU5cx> zs_b2vUgp*jXOAN<@g*S${HA~S^}j%jUjanmm;99r|7I=$>Ho7b83_*VUsLd}$oIbh zIA3s%m93O*@P7huEaALGe|-Y6F~Oa$2*kz;hyYGmH670rUS+joyo>wnXL1^Xbra;^ zjm2QgAaZ4+2aD{QB`24O%8Abky=8s?p*nt)TbcVZZ4FqMntd9GOiLccKCir=Q6Vf+ z{L^hQEx7hrZMIoHpcLC{5|9^Y7}u*y`a%Hl5h~3{!{pJ~XEl)^A^n9vH_riaObV0c zH}p*qC2VP?+6qdLvHoyp8ds?~WnEK??i3K+Q*j+&D3_TMGak{a{b73cA$D%1_m1B; zhh=4o=_6=AhGyGyujK6^{9)@_?y~9-yYN7(n4tr-1_@Of79Q8Ngx3Z7ehifShNJNX zD^%fhnlU=qQx z$%3ug=%cFIo;@2XYe@OkAig*OL8;+Zcs!&El;CcgOFm-TU>AelmP2`YcNn0jKo>aP zP^mjvg{f2`HZbgiPY|^XkXLQw-g++g8*~s`mJiRiO2I&4SY-}xfPditCCWQN=V`a8 z_DfXs`^&HFa%$sqS$=MuEDC$}?WfyK6{jTx1k9$GW< znx-GaQJpUZea0ISe1AiT9A_(aHO`Au5mOg)IOsGi9|Ug(>*Bu>WH&wdkU9Rdjr_}Z zICVk0(1R_J(GPM)Y|V7{n%0C+GBrN1pg-|zI&RyG_O|l$OPBt~$13&rwROP0aW}PK zw&#*aBZuxWaK(1esO0@t7-?-|DI9}Um@Ro;=vn5%jeONzwrRI;l-^Dzl-$hY5g~4Q zS~1xsnPp}c*mER2VykUKrLY^r@kPq5jDK=Yk$`cz^7TPh?c(c(f=Mv*&Y7!2$C4n+ zl1TGfx{!)`NDZSSVdt+?dI(+6(RMq|({fpd!ZyU@ZlXT=UgKFIx!k_M|5 z%;<_{k8G8wz!kWMHW$180X?2W6DrhyCqwcJ7M%EP7tD*JDDkQ1GpfcPXZEj!;xB8n znpA?PaxUDHhIw|T)E`Peug93)y)(gPHM|hyM^%lU!Wkq!9{RQ(#A*o zCM8CT(CeYLiIw)L{aKV(`g`pnw1mM|aKKnkO=9aaL$8Ci6q~3RrJ-VjaW;p;N%CG( zN<}1_I~}y-KC>1l6D{`J$znk9MPOL+Vh;1VukEDz0x$iwreefQm4OOcr1nq0<52lj zMzHYUF#BHvtUQSaf(oz59x8-Ho5Ar9gDcZgb$ zg^3BE3vdRw0NnqE3&0z|0?-Ep06YP9fERx=2%-QHgxve*n}Cah4*;^5wgA_Oe|&Z# pJ}`TK2P;+J1QUVGfue*p0gCHMdU literal 0 HcmV?d00001 From fd6c38605a0b3c19f5c33d7062625fde6cb3bb58 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Jan 2024 14:19:40 +0100 Subject: [PATCH 36/45] speedo: Add a hint to run ldconfig -- --- README | 1 + build-aux/speedo.mk | 2 ++ g10/keyedit.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index b979234ce..a1e989356 100644 --- a/README +++ b/README @@ -94,6 +94,7 @@ example: make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24 + ldconfig -n /usr/local/gnupg24/lib and adding /usr/local/gnupg24/bin to PATH. diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 335594b51..00244fa8e 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -1132,6 +1132,7 @@ ifneq ($(TARGETOS),w32) echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ echo "speedo: * Or run:" ;\ echo "speedo: * make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24" ;\ + echo "speedo: * ldconfig -n /usr/local/gnupg24/lib";\ echo "speedo: */") endif @@ -1147,6 +1148,7 @@ ifneq ($(TARGETOS),w32) echo "speedo: Set SYSROOT to the desired install directory";\ echo "speedo: Example:";\ echo "speedo: make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24";\ + echo "speedo: ldconfig -n /usr/local/gnupg24/lib";\ exit 1;\ fi;\ if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ diff --git a/g10/keyedit.c b/g10/keyedit.c index cae0f7841..e56e6d10b 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3336,7 +3336,7 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) /* Unattended expiration setting function for the main key. If * SUBKEYFPRS is not NULL and SUBKEYSFPRS[0] is neither NULL, it is * expected to be an array of fingerprints for subkeys to change. It - * may also be an array which just one item "*" to indicate that all + * may also be an array with only the item "*" to indicate that all * keys shall be set to that expiration date. */ void From bea31c845aad89142ac43e67b188591cf9b73c50 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 10:39:23 +0100 Subject: [PATCH 37/45] card: flush stdout to get checkcmd's info messages in order. * tools/gpg-card.c (cmd_checkkeys): Insert an fflush. --- tools/gpg-card.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 442acdc84..185d04b62 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -1490,6 +1490,7 @@ cmd_checkkeys (card_info_t callerinfo, char *argstr) xfree (infostr); } } + es_fflush (es_stdout); if (delete_count) log_info ("Number of deleted key copies: %d\n", delete_count); From 154ecf17bddc85c1cea0786e5c5792aca45413ca Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 13:41:04 +0100 Subject: [PATCH 38/45] speedo: Build zlib, bzip2 and sqlite also on Unix. -- This avoids extra build dependencies. Note that bzip2 is not necessary statically linked but an existing bzip2 SO might be used. We would need to fix the bzip2 SO building and also provide a gnupg configure option to build statically against bzip2. --- build-aux/speedo.mk | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 00244fa8e..477873f60 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -304,14 +304,9 @@ w32src := $(topsrc)/build-aux/speedo/w32 # Fixme: Do we need to build pkg-config for cross-building? speedo_spkgs = \ - libgpg-error npth libgcrypt - -ifeq ($(TARGETOS),w32) -speedo_spkgs += \ - zlib bzip2 sqlite -endif - -speedo_spkgs += libassuan libksba ntbtls gnupg + libgpg-error npth libgcrypt \ + zlib bzip2 sqlite \ + libassuan libksba ntbtls gnupg ifeq ($(STATIC),0) speedo_spkgs += gpgme @@ -546,7 +541,7 @@ speedo_pkg_gnupg_configure = \ else speedo_pkg_gnupg_configure = --disable-g13 --enable-wks-tools endif -speedo_pkg_gnupg_extracflags = -g +speedo_pkg_gnupg_extracflags = # Create the version info files only for W32 so that they won't get # installed if for example INSTALL_PREFIX=/usr/local is used. From a227a0d54da693bae4fe709c65e53b81762269f4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 14:06:32 +0100 Subject: [PATCH 39/45] po: Update German translation. -- Just the new string for gpg-card's checkkeys. --- po/de.po | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/po/de.po b/po/de.po index 7afa2d086..d4bf929ee 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.4.1\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-05-30 13:46+0200\n" +"PO-Revision-Date: 2024-01-24 14:05+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German\n" "Language: de\n" @@ -230,8 +230,9 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Bitte geben Sie ein Passwort ein, um den empfangenen geheimen Schlüssel" -"%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu schützen." +"Bitte geben Sie ein Passwort ein, um den empfangenen geheimen " +"Schlüssel%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu " +"schützen." #, c-format msgid "failed to create stream from socket: %s\n" @@ -710,9 +711,9 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" -"Wenn Sie vollständiges Vertrauen haben, daß%%0A \"%s" -"\"%%0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit \"Ja" -"\"." +"Wenn Sie vollständiges Vertrauen haben, daß%%0A " +"\"%s\"%%0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit " +"\"Ja\"." msgid "Yes" msgstr "Ja" @@ -776,8 +777,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Möchten Sie den Schlüssel mit dem \"Keygrip\"%%0A %s%%0A %%C%%0Awirklich " "entfernen?" @@ -1837,14 +1838,14 @@ msgstr "Aufgrund des S2K-Modus kann ein SKESK Paket nicht benutzt werden\n" msgid "using cipher %s.%s\n" msgstr "benutze Cipher %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "`%s' ist bereits komprimiert\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "WARNUNG: '%s' ist eine leere Datei.\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "`%s' ist bereits komprimiert\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "Die Benutzung der Hashmethode %s ist im %s Modus nicht erlaubt.\n" @@ -9106,6 +9107,9 @@ msgstr "Ein Zertifikat in einem Datenobjekt speichern" msgid "store a private key to a data object" msgstr "Privaten Schlüssel in einem Datenobjekt speichern" +msgid "run various checks on the keys" +msgstr "Die Schlüssel verschiedener Prüfungen unterziehen" + msgid "Yubikey management commands" msgstr "Verwaltungskommandos für Yubikeys" @@ -10484,8 +10488,8 @@ msgstr "Verwaltung der Kommandohistorie" #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n" #~ msgstr "" -#~ "Die \"Trust\"-Datenbank ist beschädigt; verwenden Sie \"gpg --fix-trustdb" -#~ "\".\n" +#~ "Die \"Trust\"-Datenbank ist beschädigt; verwenden Sie \"gpg --fix-" +#~ "trustdb\".\n" #~ msgid "Please report bugs to <" #~ msgstr "Fehlerberichte bitte an <" @@ -10710,8 +10714,8 @@ msgstr "Verwaltung der Kommandohistorie" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." From d4976e35d2ca431b2a651aa11be8a4589c8dd39a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 18:23:02 +0100 Subject: [PATCH 40/45] gpg: Add sub-option ignore-attributes to --import-options. * g10/options.h (IMPORT_IGNORE_ATTRIBUTES): New. * g10/import.c (parse_import_options): Add new sub-option. (read_block): Implement sub-option. -- Suggested-by: Robin H. Johnson Tested using the import-export feature: gpg --export KEY_WITH_PICTURE \ | gpg --import --import-options import-export,ignore-attributes \ | gpg --show-key --- doc/gpg.texi | 4 ++++ g10/import.c | 12 ++++++++++++ g10/options.h | 1 + 3 files changed, 17 insertions(+) diff --git a/doc/gpg.texi b/doc/gpg.texi index a54bc1fee..1bc2bd9e4 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2579,6 +2579,10 @@ opposite meaning. The options are: import-clean it suppresses the final clean step after merging the imported key into the existing key. + @item ignore-attributes + Ignore all attribute user IDs (photo IDs) and their signatures while + importing a key. + @item repair-keys After import, fix various problems with the keys. For example, this reorders signatures, and strips duplicate diff --git a/g10/import.c b/g10/import.c index c1e76c3f0..8f874a7d1 100644 --- a/g10/import.c +++ b/g10/import.c @@ -209,6 +209,9 @@ parse_import_options(char *str,unsigned int *options,int noisy) {"repair-keys", IMPORT_REPAIR_KEYS, NULL, N_("repair keys on import")}, + /* New options. Right now, without description string. */ + {"ignore-attributes", IMPORT_IGNORE_ATTRIBUTES, NULL, NULL}, + /* Hidden options which are enabled by default and are provided * in case of problems with the respective implementation. */ {"collapse-uids", IMPORT_COLLAPSE_UIDS, NULL, NULL}, @@ -1008,6 +1011,15 @@ read_block( IOBUF a, unsigned int options, init_packet(pkt); continue; } + else if ((opt.import_options & IMPORT_IGNORE_ATTRIBUTES) + && (pkt->pkttype == PKT_USER_ID || pkt->pkttype == PKT_ATTRIBUTE) + && pkt->pkt.user_id->attrib_data) + { + skip_sigs = 1; + free_packet (pkt, &parsectx); + init_packet (pkt); + continue; + } if (skip_sigs) { diff --git a/g10/options.h b/g10/options.h index e0ee99533..146b78361 100644 --- a/g10/options.h +++ b/g10/options.h @@ -406,6 +406,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define IMPORT_COLLAPSE_UIDS (1<<15) #define IMPORT_COLLAPSE_SUBKEYS (1<<16) #define IMPORT_BULK (1<<17) +#define IMPORT_IGNORE_ATTRIBUTES (1<<18) #define EXPORT_LOCAL_SIGS (1<<0) #define EXPORT_ATTRIBUTES (1<<1) From 6481d410ec673b9defcc150057988d34b7c0e712 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 Jan 2024 09:07:11 +0900 Subject: [PATCH 41/45] po: Update Japanese Translation. -- Signed-off-by: NIIBE Yutaka --- po/ja.po | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/po/ja.po b/po/ja.po index d067bf202..ab6a8dda4 100644 --- a/po/ja.po +++ b/po/ja.po @@ -5,13 +5,13 @@ # Yoshihiro Kajiki , 1999. # Takashi P.KATOH, 2002. # NIIBE Yutaka , 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021, 2022, 2023. +# 2020, 2021, 2022, 2023, 2024. # msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-11-20 10:50+0900\n" +"PO-Revision-Date: 2024-01-25 09:06+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -8729,6 +8729,9 @@ msgstr "証明書をデータオブジェクトに保管します" msgid "store a private key to a data object" msgstr "プライベート鍵をデータオブジェクトに保管する" +msgid "run various checks on the keys" +msgstr "鍵に対して様々なチェックを実行する" + msgid "Yubikey management commands" msgstr "Yubikey管理コマンド" From 2a4180812ac21257a82c091df1bec1b6e087a0bd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 10:00:13 +0100 Subject: [PATCH 42/45] card: Tweak the checkcmds sub-command. * tools/gpg-card.c (cmd_checkkeys): Skip not found keys. --- doc/gpg-card.texi | 34 ++++++++++++++++++++++++++++++++++ tools/gpg-card.c | 13 ++++++++----- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/doc/gpg-card.texi b/doc/gpg-card.texi index 33cdbd96d..8787793f8 100644 --- a/doc/gpg-card.texi +++ b/doc/gpg-card.texi @@ -316,6 +316,40 @@ Write a private key object identified by @var{keygrip} to the card under the id @var{keyref}. Option @option{--force} allows overwriting an existing key. +@item CHECKKEYS [--ondisk] [--delete-clear-copy] [--delete-protected-copy] +@opindex checkkeys +Print a list of keys noticed on all inserted cards. With +@option{--ondisk} only smartcard keys with a copy on disk are listed. +With @option{--delete-clear-copy} copies of smartcard keys stored on +disk without any protection will be deleted. With +@option{--delete-protected-copy} password protected copies of +smartcard keys stored on disk will be deleted. + +This command creates missing shadow keys. The delete options print +the status of the keys before they are deleted. + +The format of the output is: +@table @var +@item Serial number +A hex-string with the serial number of the card. +@item Type +This gives the type of the card's application. For example "OpenPGP" +or "PIV". +@item Keygrip +A hex-string identifying a key. +@item Keyref +The application slot where the key is stored on the card. For example +"OpenPGP.1" +@item Status +The status of the key. The most common value is "shadowed" for a key +where only the public key along with the card's serial number is +stored on the disk. The value "clear" indicates that a copy of the +card's key is stored unprotected on disk. The value "protected" +indicated that a copy of the car's key is stored on disk but is +protected by a password. The value "error" may also be shown if there +was a problem reading information from the card. +@end table + @item YUBIKEY @var{cmd} @var{args} @opindex yubikey Various commands pertaining to Yubikey tokens with @var{cmd} being: diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 185d04b62..f65a17b3c 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -1397,11 +1397,12 @@ cmd_checkkeys (card_info_t callerinfo, char *argstr) if (!callerinfo) return print_help - ("CHECKKEYS [--ondisk] [--delete-clear-copy]\n\n" + ("CHECKKEYS [--ondisk] [--delete-clear-copy] [--delete-protected-copy]" + "\n\n" "Print a list of keys on all inserted cards. With --ondisk only\n" "keys are listed which also have a copy on disk. Missing shadow\n" - "keys are created. With --delete-clear, copies of keys also stored\n" - "on disk without any protection will be deleted.\n" + "keys are created. With --delete-clear-copy, copies of keys also\n" + "stored on disk without any protection will be deleted.\n" , 0); @@ -1461,11 +1462,13 @@ cmd_checkkeys (card_info_t callerinfo, char *argstr) scd_readkey (kinfo->keyref, 1, NULL); err = scd_havekey_info (kinfo->grip, &infostr); } - if (err) + if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND) log_error ("Error getting infos for a key: %s\n", gpg_strerror (err)); - if (opt_ondisk && infostr && !strcmp (infostr, "shadowed")) + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + ; /* does not make sense to show this. */ + else if (opt_ondisk && infostr && !strcmp (infostr, "shadowed")) ; /* Don't print this one. */ else { From c5429644e98b7231ddc03a1fb3a514245550cf88 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 11:05:48 +0100 Subject: [PATCH 43/45] po: msgmerge -- --- po/ca.po | 21 +++++++++------- po/cs.po | 23 +++++++++-------- po/da.po | 25 +++++++++++-------- po/el.po | 21 +++++++++------- po/eo.po | 21 +++++++++------- po/es.po | 31 ++++++++++++----------- po/et.po | 25 +++++++++++-------- po/fi.po | 21 +++++++++------- po/fr.po | 23 +++++++++-------- po/gl.po | 29 +++++++++++---------- po/hu.po | 21 +++++++++------- po/id.po | 21 +++++++++------- po/it.po | 19 ++++++++------ po/nb.po | 19 ++++++++------ po/pl.po | 72 ++++++++++++++++++++++++++++------------------------- po/pt.po | 31 +++++++++++++++++++++-- po/ro.po | 33 +++++++++++++----------- po/ru.po | 27 +++++++++++--------- po/sk.po | 29 +++++++++++---------- po/sv.po | 25 +++++++++++-------- po/tr.po | 15 ++++++----- po/uk.po | 23 +++++++++-------- po/zh_CN.po | 19 ++++++++------ po/zh_TW.po | 15 ++++++----- 24 files changed, 353 insertions(+), 256 deletions(-) diff --git a/po/ca.po b/po/ca.po index 9b7cd8d1c..b2c28e72f 100644 --- a/po/ca.po +++ b/po/ca.po @@ -810,8 +810,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Realment voleu eliminar les claus seleccionades? " #, fuzzy @@ -1953,16 +1953,16 @@ msgstr "no es pot usar un paquet asimètric ESK al estar en mode S2K\n" msgid "using cipher %s.%s\n" msgstr "Ha fallat el procés de signatura: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "«%s» ja està comprimida\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVÍS: «%s» és un fitxer buit\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "«%s» ja està comprimida\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "no podeu usar l'algorisme de resum %s mentre esteu en mode %s\n" @@ -9496,6 +9496,9 @@ msgstr "S'ha creat el certificat de revocació.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10682,8 +10685,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/cs.po b/po/cs.po index 7506778cd..8b6287734 100644 --- a/po/cs.po +++ b/po/cs.po @@ -786,8 +786,8 @@ msgstr "Vyžádáno použití klíče%%0A %s%%0A %s%%0APřejete si to povolit? #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Opravdu chcete smazat klíč určený pomocí keygripu%%0A %s%%0A %%C%%0A?" @@ -1831,14 +1831,14 @@ msgstr "v režimu S2K nelze použít SKESK paket\n" msgid "using cipher %s.%s\n" msgstr "použití šifry %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "„%s“ je již zkomprimován\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "POZOR: soubor „%s“ je prázdný\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "„%s“ je již zkomprimován\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "hashovací algoritmus „%s“ se nesmí používat v režimu %s\n" @@ -8974,6 +8974,9 @@ msgstr "uloží certifikát do datového objektu" msgid "store a private key to a data object" msgstr "uloží soukromý klíč do datového objektu" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Příkazy pro správu Yubikey" @@ -10568,8 +10571,8 @@ msgstr "spravuje historii příkazů" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10616,8 +10619,8 @@ msgstr "spravuje historii příkazů" #~ "Answer \"yes\" if you really want to delete this user ID.\n" #~ "All certificates are then also lost!" #~ msgstr "" -#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte \"ano" -#~ "\".\n" +#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte " +#~ "\"ano\".\n" #~ "Všechny certifikáty budou také ztraceny!" #~ msgid "Answer \"yes\" if it is okay to delete the subkey" diff --git a/po/da.po b/po/da.po index a2b7ef163..602b28d75 100644 --- a/po/da.po +++ b/po/da.po @@ -259,8 +259,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Indtast venligst en adgangsfrase for at beskytte den modtaget hemmelige nøgle" -"%%0A %s%%0A %s%%0Ainden i gpg-agentens nøglelager" +"Indtast venligst en adgangsfrase for at beskytte den modtaget hemmelige " +"nøgle%%0A %s%%0A %s%%0Ainden i gpg-agentens nøglelager" #, c-format msgid "failed to create stream from socket: %s\n" @@ -868,8 +868,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Vil du virkelig slette de valgte nøgler? (j/N) " #, fuzzy @@ -1995,16 +1995,16 @@ msgstr "kan ikke bruge en symmetrisk ESK-pakke på grund af S2K-tilstanden\n" msgid "using cipher %s.%s\n" msgstr "bruger chiffer %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "»%s« allerede komprimeret\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "ADVARSEL: »%s« er en tom fil\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "»%s« allerede komprimeret\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2527,8 +2527,8 @@ msgstr "ADVARSEL: Usikre indelukkede mapperettigheder på hjemmemappe »%s«\n" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -9711,6 +9711,9 @@ msgstr " (certifkat oprettet den " msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/el.po b/po/el.po index 08f85c82c..9417187b7 100644 --- a/po/el.po +++ b/po/el.po @@ -777,8 +777,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Σίγουρα θέλετε να διαγραφούν τα επιλεγμένα κλειδιά; " #, fuzzy @@ -1885,16 +1885,16 @@ msgstr "αδυναμία χρήσης ενός συμμετρικού πακέτ msgid "using cipher %s.%s\n" msgstr "χρήση του κρυπταλγόριθμου: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' ήδη συμπιέστηκε\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: `%s' είναι ένα άδειο αρχείο\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' ήδη συμπιέστηκε\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9320,6 +9320,9 @@ msgstr "Πιστοποιητικό ανάκλησης δημιουργήθηκε msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10489,8 +10492,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/eo.po b/po/eo.po index d77143896..3a9a4d130 100644 --- a/po/eo.po +++ b/po/eo.po @@ -776,8 +776,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Ĉu vi vere volas forviŝi la elektitajn ŝlosilojn? " #, fuzzy @@ -1878,16 +1878,16 @@ msgstr "" msgid "using cipher %s.%s\n" msgstr "subskribado malsukcesis: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "'%s' jam densigita\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVERTO: '%s' estas malplena dosiero\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "'%s' jam densigita\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "Tiu komando ne eblas en la reĝimo %s.\n" @@ -9231,6 +9231,9 @@ msgstr "ŝlosilo %08lX: revokatestilo aldonita\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10312,8 +10315,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/es.po b/po/es.po index 635084915..7edbe88d7 100644 --- a/po/es.po +++ b/po/es.po @@ -776,8 +776,8 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"Por favor verifique que el certificado identificado como:%%0A \"%s" -"\"%%0Atiene la huella digital:%%0A %s" +"Por favor verifique que el certificado identificado como:%%0A " +"\"%s\"%%0Atiene la huella digital:%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The @@ -821,8 +821,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "¿De verdad quiere borrar la clave identificada con el keygrip%%0A %s%%0A " "%%C%%0A?" @@ -1889,14 +1889,14 @@ msgstr "no puede usar un paquete simétrico ESK debido al modo S2K\n" msgid "using cipher %s.%s\n" msgstr "usando cifrado %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' ya está comprimido\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "ATENCIÓN '%s' es un fichero vacío\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' ya está comprimido\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "no puede usar el resumen '%s' en modo %s\n" @@ -5704,8 +5704,8 @@ msgstr "" "la clave secreta. De cualquier modo, si la clave secreta está disponible,\n" "es mejor generar un nuevo certificado de revocación y dar una razón para la " "misma\n" -"Para más detalles, lee la descripción de la orden gpg \"--generate-revocation" -"\"\n" +"Para más detalles, lee la descripción de la orden gpg \"--generate-" +"revocation\"\n" "en el manual GnuPG." msgid "" @@ -9157,6 +9157,9 @@ msgstr "añadir un certificado a la cache" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10532,8 +10535,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10572,8 +10575,8 @@ msgstr "" #~ " al poseedor de la clave.\n" #~ "\n" #~ "Observe que los ejemplos dados en los niveles 2 y 3 son *solo* ejemplos.\n" -#~ "En definitiva, usted decide lo que significa \"informal\" y \"exhaustivo" -#~ "\"\n" +#~ "En definitiva, usted decide lo que significa \"informal\" y " +#~ "\"exhaustivo\"\n" #~ "para usted cuando firma las claves de otros.\n" #~ "\n" #~ "Si no sabe qué contestar, conteste \"0\"." diff --git a/po/et.po b/po/et.po index 1f07b58fc..139ed412c 100644 --- a/po/et.po +++ b/po/et.po @@ -774,8 +774,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Kas te tõesti soovite valitud võtmeid kustutada? " #, fuzzy @@ -1879,16 +1879,16 @@ msgstr "S2K moodi tõttu ei saa sümmeetrilist ESK paketti kasutada\n" msgid "using cipher %s.%s\n" msgstr "kasutan šiffrit %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' on juba pakitud\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "HOIATUS: `%s' on tühi fail\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' on juba pakitud\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "sõnumilühendi algoritm \"%s\" ei ole moodis %s lubatud\n" @@ -9235,6 +9235,9 @@ msgstr "Tühistamise sertifikaat on loodud.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10276,8 +10279,8 @@ msgstr "" #~ msgid "If you want to use this untrusted key anyway, answer \"yes\"." #~ msgstr "" -#~ "Kui te ikkagi soovite kasutada seda mitteusaldatavat võtit, vastake \"jah" -#~ "\"." +#~ "Kui te ikkagi soovite kasutada seda mitteusaldatavat võtit, vastake " +#~ "\"jah\"." #~ msgid "" #~ "Enter the user ID of the addressee to whom you want to send the message." @@ -10373,8 +10376,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/fi.po b/po/fi.po index 4248372d3..505f5c237 100644 --- a/po/fi.po +++ b/po/fi.po @@ -791,8 +791,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Haluatko varmasti poistaa valitut avaimet? " #, fuzzy @@ -1897,16 +1897,16 @@ msgstr "symmetristä ESK-pakettia ei voi käyttää S2K-tilan vuoksi\n" msgid "using cipher %s.%s\n" msgstr "käytetään salakirjoitusalgoritmia %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" on jo pakattu\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VAROITUS: \"%s\" on tyhjä tiedosto\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" on jo pakattu\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "tiivistealgoritmia \"%s\" ei voi käyttää %s-tilassa\n" @@ -9303,6 +9303,9 @@ msgstr "Mitätöintivarmenne luotu.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10465,8 +10468,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/fr.po b/po/fr.po index e7ea9ffc2..7baf95d2c 100644 --- a/po/fr.po +++ b/po/fr.po @@ -246,8 +246,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Veuillez entrer une phrase secrète pour protéger la clef secrète%%0A %s" -"%%0A %s%%0Areçue dans l'espace de stockage de clefs de gpg-agent" +"Veuillez entrer une phrase secrète pour protéger la clef secrète%%0A " +"%s%%0A %s%%0Areçue dans l'espace de stockage de clefs de gpg-agent" #, c-format msgid "failed to create stream from socket: %s\n" @@ -824,8 +824,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Voulez-vous vraiment supprimer les clefs sélectionnées ? (o/N) " msgid "Delete key" @@ -1931,14 +1931,14 @@ msgstr "impossible d'utiliser un paquet ESK symétrique en mode S2K\n" msgid "using cipher %s.%s\n" msgstr "utilisation de l'algorithme de chiffrement %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "« %s » est déjà compressé\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "Attention : « %s » est un fichier vide\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "« %s » est déjà compressé\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm '%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -9514,6 +9514,9 @@ msgstr "ajouter un certificat au cache" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10997,8 +11000,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/gl.po b/po/gl.po index 73e3ff463..5f408eabd 100644 --- a/po/gl.po +++ b/po/gl.po @@ -779,8 +779,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "¿Seguro de que quere borra-las chaves seleccionadas? " #, fuzzy @@ -1889,16 +1889,16 @@ msgstr "non se pode empregar un paquete simétrico ESK debido ao modo S2K\n" msgid "using cipher %s.%s\n" msgstr "fallou a sinatura: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' xa está comprimido\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVISO: `%s' é un ficheiro baleiro\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' xa está comprimido\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "non se pode empregar o algoritmo de resumo \"%s\" no modo %s\n" @@ -3173,8 +3173,8 @@ msgstr "chave %08lX: non hai ID de usuario para a sinatura\n" #, fuzzy, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"chave %08lX: algoritmo de chave pública non soportado no ID de usuario \"%s" -"\"\n" +"chave %08lX: algoritmo de chave pública non soportado no ID de usuario " +"\"%s\"\n" #, fuzzy, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -9315,6 +9315,9 @@ msgstr "Creouse o certificado de revocación.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10302,8 +10305,8 @@ msgstr "" #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n" #~ msgstr "" -#~ "a base de datos de confianza está corrompida; execute \"gpg --fix-trustdb" -#~ "\".\n" +#~ "a base de datos de confianza está corrompida; execute \"gpg --fix-" +#~ "trustdb\".\n" #~ msgid "Please report bugs to .\n" #~ msgstr "" @@ -10483,8 +10486,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/hu.po b/po/hu.po index a0e96c94d..0955d468a 100644 --- a/po/hu.po +++ b/po/hu.po @@ -774,8 +774,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Valóban törli a kiválasztott kulcsokat? " #, fuzzy @@ -1880,16 +1880,16 @@ msgstr "Nem tudok szimmetrikus ESK csomagot használni a S2K mód miatt!\n" msgid "using cipher %s.%s\n" msgstr "%s rejtjelezést használok.\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" már tömörített.\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "FIGYELEM: A(z) \"%s\" állomány üres.\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" már tömörített.\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9262,6 +9262,9 @@ msgstr "Visszavonó igazolás létrehozva.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10418,8 +10421,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/id.po b/po/id.po index 259fe9937..5a22bb96d 100644 --- a/po/id.po +++ b/po/id.po @@ -779,8 +779,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Anda ingin menghapus kunci terpilih ini? " #, fuzzy @@ -1886,16 +1886,16 @@ msgstr "tidak dapat menggunakan paket simetri ESK karena mode S2K\n" msgid "using cipher %s.%s\n" msgstr "menggunakan cipher %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' sudah dikompresi\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "PERINGATAN: `%s' adalah file kosong\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' sudah dikompresi\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9261,6 +9261,9 @@ msgstr "Sertifikat pembatalan tercipta.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10418,8 +10421,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/it.po b/po/it.po index f301780da..f3bcde883 100644 --- a/po/it.po +++ b/po/it.po @@ -225,8 +225,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Immettere una passphrase per proteggere la chiave segreta ricevuta%%0A %s" -"%%0A %s%%0A all'interno dell'archivio chiavi dell'agente gpg" +"Immettere una passphrase per proteggere la chiave segreta ricevuta%%0A " +"%s%%0A %s%%0A all'interno dell'archivio chiavi dell'agente gpg" #, c-format msgid "failed to create stream from socket: %s\n" @@ -771,8 +771,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Si desidera eliminare la chiave identificata da keygrip%%0A %s%%0A %%C%%0A?" @@ -1828,14 +1828,14 @@ msgstr "" msgid "using cipher %s.%s\n" msgstr "utilizzando il cifrario %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' già compresso\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "AVVISO: '%s' è un file vuoto\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' già compresso\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "l'algoritmo digest '%s' non può essere utilizzato in modalità %s\n" @@ -9069,6 +9069,9 @@ msgstr "archiviare un certificato in un oggetto dati" msgid "store a private key to a data object" msgstr "archiviare una chiave privata in un oggetto dati" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Comandi di gestione Yubikey" diff --git a/po/nb.po b/po/nb.po index dcbd64efa..e79896ccb 100644 --- a/po/nb.po +++ b/po/nb.po @@ -237,8 +237,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Skriv inn passordfrase som skal brukes til å beskytte mottatt hemmelig nøkkel" -"%%0A %s%%0A %s%%0Ai nøkkellageret for gpg-agent" +"Skriv inn passordfrase som skal brukes til å beskytte mottatt hemmelig " +"nøkkel%%0A %s%%0A %s%%0Ai nøkkellageret for gpg-agent" #, c-format msgid "failed to create stream from socket: %s\n" @@ -782,8 +782,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Er du sikker på at du vil slette nøkkel med nøkkelgrep%%0A %s%%0A %%C%%0A?" @@ -1858,14 +1858,14 @@ msgstr "klarte ikke å bruke symmetrisk ESK-pakke på grunn av S2K-modus\n" msgid "using cipher %s.%s\n" msgstr "bruker krypteringsmetode %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "«%s» er allerede komprimert\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "ADVARSEL: «%s» er en tom fil\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "«%s» er allerede komprimert\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "du kan ikke bruke algoritme «%s» i %s-modus\n" @@ -9046,6 +9046,9 @@ msgstr "legg til sertifikat i hurtiglager" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/pl.po b/po/pl.po index d9d98e9d2..1248d87c6 100644 --- a/po/pl.po +++ b/po/pl.po @@ -170,14 +170,15 @@ msgid "" "Please enter the passphrase to protect the imported object within the %s " "system." msgstr "" -"Proszę wprowadzić hasło do zabezpieczenia importowanego obiektu w systemie %s." +"Proszę wprowadzić hasło do zabezpieczenia importowanego obiektu w systemie " +"%s." msgid "" "This key (or subkey) is not protected with a passphrase. Please enter a new " "passphrase to export it." msgstr "" -"Ten klucz (lub podklucz) nie jest zabezpieczony hasłem. Proszę wprowadzić nowe " -"hasło, aby go wyeksportować." +"Ten klucz (lub podklucz) nie jest zabezpieczony hasłem. Proszę wprowadzić " +"nowe hasło, aby go wyeksportować." #, c-format msgid "ssh keys greater than %d bits are not supported\n" @@ -221,8 +222,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Proszę wprowadzić hasło do zabezpieczenia odebranego klucza tajnego%%0A %s" -"%%0A %s%%0Aw miejscu przechowywania kluczy gpg-agenta" +"Proszę wprowadzić hasło do zabezpieczenia odebranego klucza tajnego%%0A " +"%s%%0A %s%%0Aw miejscu przechowywania kluczy gpg-agenta" #, c-format msgid "failed to create stream from socket: %s\n" @@ -714,8 +715,8 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a „%s”%%0Ama " -"odcisk:%%0A %s" +"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a „%s”%%0Ama odcisk:" +"%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The @@ -752,8 +753,8 @@ msgstr "Zażądano użycia klucza%%0A %s%%0A %s%%0ACzy zezwolić na to?" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Czy na pewno usunąć klucz identyfikowany przez uchwyt%%0A %s%%0A %%C%%0A?" @@ -1796,14 +1797,14 @@ msgstr "nie można użyć pakietu SKESK ze względu na tryb S2K\n" msgid "using cipher %s.%s\n" msgstr "szyfrem %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "„%s” już jest skompresowany\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "OSTRZEŻENIE: plik „%s” jest pusty\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "„%s” już jest skompresowany\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "algorytm skrótu „%s” nie może być używany w trybie %s\n" @@ -2216,8 +2217,7 @@ msgstr "w definicji grupy „%s” brak znaku „=”\n" #, c-format msgid "WARNING: unsafe ownership on homedir '%s'\n" -msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego „%s”\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego „%s”\n" #, c-format msgid "WARNING: unsafe ownership on configuration file '%s'\n" @@ -2316,7 +2316,8 @@ msgid "show revoked and expired subkeys in key listings" msgstr "pokazywanie unieważnionych i wygasłych podkluczy na listach kluczy" msgid "show signatures with invalid algorithms during signature listings" -msgstr "pokazywanie podpisów z niepoprawnymi algorytmami przy wypisywaniu podpisów" +msgstr "" +"pokazywanie podpisów z niepoprawnymi algorytmami przy wypisywaniu podpisów" msgid "show the keyring name in key listings" msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy" @@ -3536,7 +3537,8 @@ msgstr "Dostępne są podklucze tajne.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "Uwaga: kopia lokalna klucza tajnego będzie usunięta tylko z \"save\".\n" +msgstr "" +"Uwaga: kopia lokalna klucza tajnego będzie usunięta tylko z \"save\".\n" msgid "Need the secret key to do this.\n" msgstr "Do wykonania tej operacji potrzebny jest klucz tajny.\n" @@ -4483,8 +4485,7 @@ msgstr "tworzenie mimo to\n" #, c-format msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n" msgstr "" -"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez „%s " -"%s”.\n" +"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez „%s %s”.\n" #, c-format msgid "Key generation canceled.\n" @@ -4827,7 +4828,9 @@ msgstr "błąd odszyfrowywania: %s\n" #, c-format msgid "operation forced to fail due to unfulfilled compliance rules\n" -msgstr "wymuszono niepowodzenie operacji ze względu na niespełnione zasady zgodności\n" +msgstr "" +"wymuszono niepowodzenie operacji ze względu na niespełnione zasady " +"zgodności\n" #, c-format msgid "Note: sender requested \"for-your-eyes-only\"\n" @@ -4839,8 +4842,7 @@ msgstr "pierwotna nazwa pliku='%.*s'\n" #, c-format msgid "standalone revocation - use \"gpg --import\" to apply\n" -msgstr "" -"osobny certyfikat unieważnienia - użyj „gpg --import” aby go wczytać\n" +msgstr "osobny certyfikat unieważnienia - użyj „gpg --import” aby go wczytać\n" #, c-format msgid "no signature found\n" @@ -5020,15 +5022,13 @@ msgstr "" #, c-format msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n" -msgstr "" -"%s:%u: „%s” jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" +msgstr "%s:%u: „%s” jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" #, c-format msgid "" "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n" msgstr "" -"OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu z wyjątkiem " -"%s\n" +"OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu z wyjątkiem %s\n" msgid "Uncompressed" msgstr "Nieskompresowany" @@ -5132,7 +5132,8 @@ msgid "Do you really want to permanently delete the OpenPGP secret key:" msgstr "Czy na pewno trwale usunąć klucz prywatny OpenPGP:" msgid "Please enter the passphrase to export the secret key with keygrip:" -msgstr "Proszę wprowadzić hasło do wyeksportowania klucza prywatnego z uchwytem:" +msgstr "" +"Proszę wprowadzić hasło do wyeksportowania klucza prywatnego z uchwytem:" #, c-format msgid "" @@ -5381,7 +5382,9 @@ msgstr "Uwaga: Data ważności tego klucza upłynęła!\n" #, c-format msgid "WARNING: The key's User ID is not certified with a trusted signature!\n" -msgstr "OSTRZEŻENIE: Identyfikator użytkownika tego klucza nie jest poświadczony zaufanym podpisem!\n" +msgstr "" +"OSTRZEŻENIE: Identyfikator użytkownika tego klucza nie jest poświadczony " +"zaufanym podpisem!\n" #, c-format msgid "WARNING: This key is not certified with a trusted signature!\n" @@ -6066,8 +6069,7 @@ msgstr[2] "Adres e-mail „%s” jest powiązany z %d kluczami!" msgid " Since this binding's policy was 'auto', it has been changed to 'ask'." msgstr "" -" Ponieważ polityką tego powiązania było „auto”, została zmieniona na „" -"ask”." +" Ponieważ polityką tego powiązania było „auto”, została zmieniona na „ask”." #, c-format msgid "" @@ -7862,8 +7864,7 @@ msgstr "nieprawidłowy znacznik czasu w „%s”, linia %u\n" #, c-format msgid "WARNING: invalid cache file hash in '%s' line %u\n" -msgstr "" -"UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w „%s”, linia %u\n" +msgstr "UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w „%s”, linia %u\n" #, c-format msgid "detected errors in cache dir file\n" @@ -7876,8 +7877,8 @@ msgstr "proszę sprawdzić przyczynę i ręcznie usunąć ten plik\n" #, c-format msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "" -"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej „" -"%s”: %s\n" +"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej „%s”: " +"%s\n" #, c-format msgid "error renaming '%s' to '%s': %s\n" @@ -9046,6 +9047,9 @@ msgstr "dodanie certyfikatu do pamięci podręcznej" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/pt.po b/po/pt.po index cf440b3a3..c0b052b2e 100644 --- a/po/pt.po +++ b/po/pt.po @@ -881,8 +881,28 @@ msgid "waiting for process %d to terminate failed: %s\n" msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" #, c-format -msgid "waiting for process to terminate failed: ec=%d\n" -msgstr "falha ao esperar que o processo terminasse: ec=%d\n" +msgid "error running '%s': probably not installed\n" +msgstr "" + +#, fuzzy, c-format +#| msgid "error accessing '%s': http status %u\n" +msgid "error running '%s': exit status %d\n" +msgstr "erro ao aceder '%s': status http %u\n" + +#, fuzzy, c-format +#| msgid "error opening '%s': %s\n" +msgid "error running '%s': terminated\n" +msgstr "erro ao abrir '%s': %s\n" + +#, fuzzy, c-format +#| msgid "waiting for process %d to terminate failed: %s\n" +msgid "waiting for processes to terminate failed: %s\n" +msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" + +#, fuzzy, c-format +#| msgid "error getting list of cards: %s\n" +msgid "error getting exit code of process %d: %s\n" +msgstr "erro ao obter a lista de cartões: %s\n" #, c-format msgid "can't connect to '%s': %s\n" @@ -8968,8 +8988,15 @@ msgstr "armazenar um certificado em um objeto de dados" msgid "store a private key to a data object" msgstr "armazenar uma chave privada em um objeto de dados" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "comandos de gerir uma Yubikey" msgid "manage the command history" msgstr "gerir o histórico de comandos" + +#, c-format +#~ msgid "waiting for process to terminate failed: ec=%d\n" +#~ msgstr "falha ao esperar que o processo terminasse: ec=%d\n" diff --git a/po/ro.po b/po/ro.po index ab6fe8396..c7b55e2f1 100644 --- a/po/ro.po +++ b/po/ro.po @@ -792,8 +792,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Doriţi într-adevăr să ştergeţi cheile selectate? (d/N) " #, fuzzy @@ -1908,16 +1908,16 @@ msgstr "nu pot crea un pachet ESK simetric datorită modului S2K\n" msgid "using cipher %s.%s\n" msgstr "folosesc cifrul %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' deja compresat\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVERTISMENT: `%s' este un fişier gol\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' deja compresat\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2449,8 +2449,8 @@ msgstr "" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -3236,8 +3236,8 @@ msgstr "cheia %s: nici un ID utilizator pentru semnătură\n" #, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"cheia %s: algoritm cu cheie publică nesuportat pentru ID-ul utilizator \"%s" -"\"\n" +"cheia %s: algoritm cu cheie publică nesuportat pentru ID-ul utilizator " +"\"%s\"\n" #, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -9406,6 +9406,9 @@ msgstr "Certificat de revocare creat.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10620,8 +10623,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -11539,8 +11542,8 @@ msgstr "" #~ "crea\n" #~ "o cheie sigură pentru semnături: acest program face acest lucru, dar " #~ "alte\n" -#~ "implementări OpenPGP ar putea să nu înţeleagă varianta de semnare" -#~ "+cifrare.\n" +#~ "implementări OpenPGP ar putea să nu înţeleagă varianta de " +#~ "semnare+cifrare.\n" #~ "\n" #~ "Prima cheie (primară) trebuie să fie întotdeauna capabilă de semnare;\n" #~ "acesta este motivul pentru care cheia ElGamal nu este disponibilă în\n" diff --git a/po/ru.po b/po/ru.po index a144acd53..47b9e3b56 100644 --- a/po/ru.po +++ b/po/ru.po @@ -18,8 +18,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" #, c-format msgid "failed to acquire the pinentry lock: %s\n" @@ -328,8 +328,8 @@ msgstr[2] "" #, c-format msgid "A passphrase may not be a known term or match%%0Acertain pattern." msgstr "" -"Фраза-пароль не должна быть известным выражением и не должна быть составлена" -"%%0Aпо определенному образцу." +"Фраза-пароль не должна быть известным выражением и не должна быть " +"составлена%%0Aпо определенному образцу." msgid "Warning: You have entered an insecure passphrase." msgstr "Внимание: Вы ввели небезопасную фразу-пароль." @@ -786,8 +786,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Вы действительно хотите удалить ключ с кодом%%0A %s%%0A %%C%%0A?" msgid "Delete key" @@ -1843,14 +1843,14 @@ msgstr "не могу использовать симметричный паке msgid "using cipher %s.%s\n" msgstr "используется симметричный шифр %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' уже сжат\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "Внимание: файл '%s' пуст\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' уже сжат\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "хеш-функцию '%s' нельзя использовать в режиме %s\n" @@ -9147,6 +9147,9 @@ msgstr "добавить сертификат в буфер" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -9617,8 +9620,8 @@ msgstr "" #~ msgid "error setting policy for key %s, user id \"%s\": %s" #~ msgstr "" -#~ "ошибка установки правил для ключа %s с идентификатором пользователя \"%s" -#~ "\": %s" +#~ "ошибка установки правил для ключа %s с идентификатором пользователя " +#~ "\"%s\": %s" #~ msgid "only SHA-1 is supported for OCSP responses\n" #~ msgstr "для ответов OCSP поддерживается только SHA-1\n" diff --git a/po/sk.po b/po/sk.po index e730decf0..638bc8955 100644 --- a/po/sk.po +++ b/po/sk.po @@ -779,8 +779,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Skutočne chcete zmazať vybrané kľúče? " #, fuzzy @@ -1886,16 +1886,16 @@ msgstr "v móde S2K nemožno použiť symetrický ESK paket\n" msgid "using cipher %s.%s\n" msgstr "použitá šifra %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' je už skomprimovaný\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VAROVANIE: súbor `%s' je prázdny\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' je už skomprimovaný\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "nemôžete použiť hashovací algoritmus \"%s\" v móde %s\n" @@ -3180,8 +3180,8 @@ msgstr "kľúč %08lX: neexistuje id užívateľa pre podpis\n" #, fuzzy, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"kľúč %08lX: nepodporovaný algoritmus verejného kľúča u užívateľského id \"%s" -"\"\n" +"kľúč %08lX: nepodporovaný algoritmus verejného kľúča u užívateľského id " +"\"%s\"\n" #, fuzzy, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -9295,6 +9295,9 @@ msgstr "Revokačný certifikát bol vytvorený.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10452,8 +10455,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10496,8 +10499,8 @@ msgstr "" #, fuzzy #~ msgid "Answer \"yes\" if you want to sign ALL the user IDs" #~ msgstr "" -#~ "Pokiaľ chcete podpísať VŠETKY identifikátory užívateľov, odpovedzte \"ano" -#~ "\"" +#~ "Pokiaľ chcete podpísať VŠETKY identifikátory užívateľov, odpovedzte " +#~ "\"ano\"" #~ msgid "" #~ "Answer \"yes\" if you really want to delete this user ID.\n" diff --git a/po/sv.po b/po/sv.po index 5fcf6532c..0e6951f81 100644 --- a/po/sv.po +++ b/po/sv.po @@ -881,8 +881,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Vill du verkligen ta bort de valda nycklarna? (j/N) " #, fuzzy @@ -2026,16 +2026,16 @@ msgstr "kan inte använda symmetriska ESK-paket pga S2K-läge\n" msgid "using cipher %s.%s\n" msgstr "använder %s-chiffer\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" är redan komprimerad\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VARNING: \"%s\" är en tom fil\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" är redan komprimerad\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2570,8 +2570,8 @@ msgstr "" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -9851,6 +9851,9 @@ msgstr " (certifikat skapat " msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -11212,8 +11215,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/tr.po b/po/tr.po index 27f15bc61..95aa0aef5 100644 --- a/po/tr.po +++ b/po/tr.po @@ -762,8 +762,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "%%0A %s%%0A %%C%%0A anahtar maşası tarafından tanımlanan anahtarı silmek " "istediğnizden emin misiniz?" @@ -1799,14 +1799,14 @@ msgstr "S2K kipi nedeniyle bir SKESK paketi kullanılamıyor\n" msgid "using cipher %s.%s\n" msgstr "%s.%s şifrelemesi kullanılıyor\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' halihazırda sıkıştırılmış\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "UYARI: '%s', boş bir dosya\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' halihazırda sıkıştırılmış\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "özet algoritması '%s', %s kipinde kullanılamayabilir\n" @@ -8910,6 +8910,9 @@ msgstr "bir veri nesnesine bir sertifika depola" msgid "store a private key to a data object" msgstr "bir veri nesnesine bir özel anahtar depola" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Yubikey yönetim konsolu" diff --git a/po/uk.po b/po/uk.po index c3e927947..3f5bfedba 100644 --- a/po/uk.po +++ b/po/uk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" "X-Generator: Lokalize 20.11.70\n" #, c-format @@ -235,8 +235,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Будь ласка, вкажіть пароль для захисту отриманого закритого ключа%%0A %s" -"%%0A %s%%0Aу сховищі ключів gpg-agent" +"Будь ласка, вкажіть пароль для захисту отриманого закритого ключа%%0A " +"%s%%0A %s%%0Aу сховищі ключів gpg-agent" #, c-format msgid "failed to create stream from socket: %s\n" @@ -787,8 +787,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Справді хочете вилучити ключ, що визначається keygrip%%0A %s%%0A %%C%%0A?" @@ -1860,14 +1860,14 @@ msgstr "не можна використовувати симетричний п msgid "using cipher %s.%s\n" msgstr "використано шифр %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "«%s» вже стиснено\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "УВАГА: файл «%s» є порожнім\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "«%s» вже стиснено\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9240,6 +9240,9 @@ msgstr "додати сертифікат до кешу" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po index ef737a37d..f48fdec84 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -221,8 +221,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"请输入一个密码,以便于在 gpg-agent 的密钥存储中保护接收到的私钥 %%0A %s" -"%%0A %s%%0A" +"请输入一个密码,以便于在 gpg-agent 的密钥存储中保护接收到的私钥 %%0A " +"%s%%0A %s%%0A" #, c-format msgid "failed to create stream from socket: %s\n" @@ -742,8 +742,8 @@ msgstr "请求使用密钥%%0A %s%%0A %s%%0A您想要允许这一请求吗?" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "您真的想要删除这个被以下的 keygrip 所标识的密钥吗 %%0A %s%%0A %%C%%0A?" @@ -1774,14 +1774,14 @@ msgstr "由于在 S2K 模式,不能使用一个对称的 ESK 封包\n" msgid "using cipher %s.%s\n" msgstr "使用加密 %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "‘%s’已被压缩\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "警告:‘%s’是一个空文件\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "‘%s’已被压缩\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "摘要算法‘%s’不能在 %s 模式下使用\n" @@ -8666,6 +8666,9 @@ msgstr "储存一个证书到数据对象" msgid "store a private key to a data object" msgstr "储存私钥到数据对象" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Yubikey 管理命令" diff --git a/po/zh_TW.po b/po/zh_TW.po index 4cb6f64bb..aa5a1125e 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -783,8 +783,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "你真的想要刪除所選的金鑰嗎? (y/N) " msgid "Delete key" @@ -1868,14 +1868,14 @@ msgstr "因處於 S2K 模式下而無法使用對稱式 ESK 封包\n" msgid "using cipher %s.%s\n" msgstr "正在使用 %s 編密法\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' 已經被壓縮了\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "警告: '%s' 是個空檔案\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' 已經被壓縮了\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm '%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -9048,6 +9048,9 @@ msgstr "加入憑證至快取" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" From a43271cc08e2068acc75a1742f90740afe0479e0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 11:04:33 +0100 Subject: [PATCH 44/45] Release 2.4.4 --- NEWS | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 4e2d84d67..7ed00a015 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ -Noteworthy changes in version 2.4.4 (unreleased) +Noteworthy changes in version 2.4.4 (2024-01-25) ------------------------------------------------ + * gpg: Do not keep an unprotected smartcard backup key on disk. See + https://gnupg.org/blog/20240125-smartcard-backup-key.html for a + security advisory. [T6944] + * gpg: Allow to specify seconds since Epoch beyond 2038 on 32-bit platforms. [T6736] @@ -10,11 +14,14 @@ Noteworthy changes in version 2.4.4 (unreleased) * gpg: Add option --with-v5-fingerprint. [T6705] - * gpg: Fix validity of re-imported keys. [T6399] + * gpg: Add sub-option ignore-attributes to --import-options. + [rGd4976e35d2] * gpg: Add --list-filter properties sig_expires/sig_expires_d. [rGbf662d0f93af] + * gpg: Fix validity of re-imported keys. [T6399] + * gpg: Report BEGIN_ status before examining the input. [T6481] * gpg: Don't try to compress a read-only keybox. [T6811] From 367ae86019063ca0af74aea556414aff44693bea Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 11:30:37 +0100 Subject: [PATCH 45/45] Post release updates -- --- NEWS | 7 +++++++ configure.ac | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7ed00a015..26228b242 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +Noteworthy changes in version 2.4.5 (unreleased) +------------------------------------------------ + + + Release-info: https://dev.gnupg.org/T6960 + + Noteworthy changes in version 2.4.4 (2024-01-25) ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 26d7f7b55..ac4f08c12 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.16.3" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [4]) -m4_define([mym4_micro], [4]) +m4_define([mym4_micro], [5]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release