aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-01-26 08:41:00 +0000
committerWerner Koch <[email protected]>2024-01-26 08:41:00 +0000
commitdfa60c09f5cd992515df5fdb275dbee7f8f23b71 (patch)
treee68215d4b947727fa98eb8c95244b8819b058b1e
parentgpg: Clean up pk_ecdh_decrypt function. (diff)
parentPost release updates (diff)
downloadgnupg-dfa60c09f5cd992515df5fdb275dbee7f8f23b71.tar.gz
gnupg-dfa60c09f5cd992515df5fdb275dbee7f8f23b71.zip
Merge branch 'STABLE-BRANCH-2-4'
-- Fixed conflicts: NEWS configure.ac doc/gpg.texi
-rw-r--r--AUTHORS2
-rw-r--r--Makefile.am7
-rw-r--r--NEWS107
-rw-r--r--README25
-rw-r--r--agent/agent.h39
-rw-r--r--agent/command-ssh.c8
-rw-r--r--agent/command.c111
-rw-r--r--agent/cvt-openpgp.c10
-rw-r--r--agent/divert-tpm2.c4
-rw-r--r--agent/findkey.c380
-rw-r--r--agent/genkey.c156
-rw-r--r--agent/gpg-agent.c5
-rw-r--r--agent/keyformat.txt10
-rw-r--r--agent/learncard.c22
-rw-r--r--agent/pksign.c5
-rw-r--r--agent/protect-tool.c6
-rw-r--r--build-aux/speedo.mk321
-rw-r--r--common/homedir.c27
-rw-r--r--common/session-env.c3
-rw-r--r--common/status.h1
-rw-r--r--common/util.h2
-rw-r--r--common/w32info-rc.h.in2
-rw-r--r--configure.ac2
-rw-r--r--doc/gpg-agent.texi21
-rw-r--r--doc/gpg-card.texi34
-rw-r--r--doc/gpg.texi24
-rw-r--r--doc/tools.texi13
-rw-r--r--g10/call-agent.c52
-rw-r--r--g10/call-agent.h4
-rw-r--r--g10/getkey.c33
-rw-r--r--g10/import.c12
-rw-r--r--g10/keydb.c26
-rw-r--r--g10/keyedit.c44
-rw-r--r--g10/keygen.c307
-rw-r--r--g10/options.h1
-rw-r--r--g10/parse-packet.c11
-rw-r--r--g10/sign.c12
-rw-r--r--g13/call-syshelp.c14
-rw-r--r--g13/g13-common.h2
-rw-r--r--g13/g13-syshelp.c2
-rw-r--r--g13/g13-syshelp.h2
-rw-r--r--g13/g13.c4
-rw-r--r--g13/sh-cmd.c30
-rw-r--r--g13/sh-dmcrypt.c64
-rw-r--r--po/ca.po31
-rw-r--r--po/cs.po23
-rw-r--r--po/da.po35
-rw-r--r--po/de.po42
-rw-r--r--po/el.po33
-rw-r--r--po/eo.po33
-rw-r--r--po/es.po39
-rw-r--r--po/et.po37
-rw-r--r--po/fi.po33
-rw-r--r--po/fr.po25
-rw-r--r--po/gl.po41
-rw-r--r--po/hu.po33
-rw-r--r--po/id.po57
-rw-r--r--po/it.po25
-rw-r--r--po/ja.po7
-rw-r--r--po/nb.po21
-rw-r--r--po/pl.po457
-rw-r--r--po/pt.po31
-rw-r--r--po/ro.po39
-rw-r--r--po/ru.po27
-rw-r--r--po/sk.po41
-rw-r--r--po/sv.po35
-rw-r--r--po/tr.po15
-rw-r--r--po/uk.po27
-rw-r--r--po/zh_CN.po19
-rw-r--r--po/zh_TW.po25
-rw-r--r--scd/app-common.h4
-rw-r--r--scd/app-p15.c155
-rw-r--r--scd/app-piv.c56
-rw-r--r--scd/app.c53
-rw-r--r--sm/encrypt.c2
-rw-r--r--sm/import.c157
-rw-r--r--sm/minip12.c58
-rw-r--r--sm/minip12.h1
-rw-r--r--sm/t-minip12.c8
-rw-r--r--sm/verify.c7
-rw-r--r--tests/cms/Makefile.am3
-rw-r--r--tests/cms/samplekeys/Description-p1212
-rw-r--r--tests/cms/samplekeys/credential_private_encrypted_3DES.p12bin0 -> 4220 bytes
-rw-r--r--tests/cms/samplekeys/credential_private_encrypted_AES256.p12bin0 -> 4370 bytes
-rw-r--r--tools/card-call-scd.c92
-rw-r--r--tools/gpg-card.c142
-rw-r--r--tools/gpg-card.h2
-rw-r--r--tools/gpgconf.c128
88 files changed, 2657 insertions, 1421 deletions
diff --git a/AUTHORS b/AUTHORS
index 65522a1cc..6451a5b48 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 <[email protected]>
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/NEWS b/NEWS
index b9bff6232..4a5fe2f27 100644
--- a/NEWS
+++ b/NEWS
@@ -3,9 +3,104 @@ Noteworthy changes in version 2.5.0 (unreleased)
Changes also found in 2.4.4:
- * gpgsm: Support ECDSA in de-vs compliance mode. [T6802]
+ * 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]
+
+ * 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: 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]
+
+ * 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]
+
+ * 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]
- * Fix garbled time output in non-English Windows. [T6741]
Changes also found in 2.4.3:
@@ -21,6 +116,8 @@ Noteworthy changes in version 2.5.0 (unreleased)
* 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]
@@ -52,6 +149,9 @@ Noteworthy changes in version 2.5.0 (unreleased)
* scd: Fix authentication with Administration Key for PIV.
[rG25b59cf6ce]
+ * Fix garbled time output in non-English Windows. [T6741]
+
+
Changes also found in 2.4.2:
* gpg: Print a warning if no more encryption subkeys are left over
@@ -78,7 +178,7 @@ Noteworthy changes in version 2.5.0 (unreleased)
Release dates of 2.4 versions
-----------------------------
-Version 2.4.4 (unreleased) https://dev.gnupg.org/T6578
+Version 2.4.4 (2024-01-25) https://dev.gnupg.org/T6578
Version 2.4.3 (2023-07-04) https://dev.gnupg.org/T6509
Version 2.4.2 (2023-05-30) https://dev.gnupg.org/T6506
Version 2.4.1 (2023-04-28) https://dev.gnupg.org/T6454
@@ -1678,6 +1778,7 @@ 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
diff --git a/README b/README
index 6905daafb..fc30b1601 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,24 @@
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 -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. 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/gnupg24
+ ldconfig -n /usr/local/gnupg24/lib
+
+ and adding /usr/local/gnupg24/bin to PATH.
- 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.
** Specific build problems on some machines:
diff --git a/agent/agent.h b/agent/agent.h
index 3bedab121..37582483b 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;
@@ -453,7 +470,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,
@@ -478,7 +496,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,
@@ -486,7 +504,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);
@@ -542,15 +561,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);
@@ -588,7 +613,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 0afa24111..02f069dea 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 b7a71cbe5..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;
}
@@ -634,34 +637,65 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
static const char hlp_havekey[] =
"HAVEKEY <hexstrings_with_keygrips>\n"
"HAVEKEY --list[=<limit>]\n"
+ "HAVEKEY --info <hexkeygrip>\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 <limit> bail out at this number of keygrips";
+ "as binary data; with <limit> 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)
{
- ctrl_t ctrl;
+ ctrl_t ctrl = assuan_get_pointer (ctx);
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;
+ 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;
- 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;
+
+ 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)
@@ -672,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')
@@ -690,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)
{
@@ -1083,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)
@@ -1157,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);
@@ -1170,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)
@@ -1283,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);
@@ -1293,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] <hexstring_with_keygrip>\n"
@@ -1356,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;
@@ -1364,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)
@@ -2900,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
{
@@ -2922,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:
@@ -2945,7 +2982,8 @@ cmd_import_key (assuan_context_t ctx, char *line)
static const char hlp_export_key[] =
- "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp|--mode1003] <hexkeygrip>\n"
+ "EXPORT_KEY [--cache-nonce=<nonce>] \\\n"
+ " [--openpgp|--mode1003] <hexkeygrip>\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"
@@ -2953,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
@@ -3011,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;
@@ -3223,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;
}
@@ -3543,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;
@@ -3835,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";
@@ -3888,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);
@@ -4044,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 cf37cdafc..503a7eb53 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;
}
@@ -458,16 +519,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;
@@ -486,7 +550,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
{
@@ -494,8 +558,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,
@@ -540,11 +604,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];
@@ -552,21 +619,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;
@@ -615,7 +684,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
@@ -631,7 +701,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 6ffff6eb3..e7818697d 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -364,7 +364,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
@@ -1307,7 +1307,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;
@@ -2002,6 +2002,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/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
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;
-
- agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno,
- item->hexgrip);
- rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force,
- dispserialno);
- xfree (dispserialno);
- }
+ if (!ctrl->ephemeral_mode)
+ {
+ char *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;
diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk
index 7777411e2..477873f60 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'
@@ -114,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.'
@@ -148,66 +147,52 @@ 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 \
- installer-from-source
+ $(SPEEDOMAKE) TARGETOS=w32 WHAT=release installer-from-source
w32-msi-release: check-tools
- $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \
+ $(SPEEDOMAKE) TARGETOS=w32 WHAT=release \
WITH_WIXLIB=1 installer-from-source
w32-sign-installer: check-tools
- $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \
- sign-installer
+ $(SPEEDOMAKE) TARGETOS=w32 WHAT=release sign-installer
w32-release-offline: check-tools
- $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \
+ $(SPEEDOMAKE) TARGETOS=w32 WHAT=release \
CUSTOM_SWDB=1 pkgrep=${HOME}/b pkg10rep=${HOME}/b \
installer-from-source
@@ -220,17 +205,14 @@ 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
# 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
@@ -240,7 +222,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 +233,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)
@@ -319,60 +304,16 @@ 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
-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
+ libgpg-error npth libgcrypt \
+ zlib bzip2 sqlite \
+ libassuan libksba ntbtls gnupg
ifeq ($(STATIC),0)
-speedo_spkgs += \
- gpgme
-endif
-
-ifeq ($(TARGETOS),w32)
-ifeq ($(WITH_GUI),1)
-speedo_spkgs += \
- libpng \
- gdk-pixbuf atk pixman cairo pango gtk+
-endif
+speedo_spkgs += gpgme
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 +324,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 +389,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 +404,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 +415,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 +472,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 +489,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 +499,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
#
@@ -638,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.
@@ -651,25 +554,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 +571,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,64 +634,12 @@ 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
+install: install-speedo
+
report: report-speedo
clean: clean-speedo
@@ -1286,6 +1109,71 @@ 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/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 $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24" ;\
+ echo "speedo: * ldconfig -n /usr/local/gnupg24/lib";\
+ 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 $(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 \
+ 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/gnupg" > "$$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))
@@ -1357,9 +1245,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
@@ -1565,4 +1450,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
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] == '/')
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. */
};
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/common/util.h b/common/util.h
index 2b46ec930..e2d95b1af 100644
--- a/common/util.h
+++ b/common/util.h
@@ -366,7 +366,7 @@ gpg_error_t b64decode (const char *string, const char *title,
/*-- 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/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 c21138641..0dfbe6193 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/doc/gpg-agent.texi b/doc/gpg-agent.texi
index 08dd7f49f..6e78558aa 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
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/doc/gpg.texi b/doc/gpg.texi
index 17de880ea..7e6420a49 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
@@ -2580,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
@@ -4637,10 +4640,11 @@ 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.
+algorithm of the designated revoker (i.e. RSA=1, DSA=17, etc.)
+@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/doc/tools.texi b/doc/tools.texi
index 07a50820b..2f60a46dd 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/g10/call-agent.c b/g10/call-agent.c
index f545b6690..06ed232fa 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -2227,7 +2227,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)
{
@@ -2241,11 +2248,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);
@@ -3237,6 +3244,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/getkey.c b/g10/getkey.c
index 21ffd5cfa..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
@@ -3772,6 +3790,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. */
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/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++;
}
}
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 1f614fb7e..e56e6d10b 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);
}
@@ -3212,7 +3224,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 +3236,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 +3260,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 +3289,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 +3301,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 +3326,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);
}
@@ -3318,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
diff --git a/g10/keygen.c b/g10/keygen.c
index 9b0113c5a..c98deb635 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. */
@@ -159,7 +171,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 +1278,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 +1449,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 +1493,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 +1507,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;
@@ -1494,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;
@@ -1516,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)
{
@@ -1568,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;
@@ -1610,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);
}
@@ -1625,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;
@@ -1699,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);
}
@@ -1709,13 +1781,17 @@ 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,
- char **cache_nonce_addr, char **passwd_nonce_addr)
+ int *keygen_flags, const char *passphrase,
+ 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;
@@ -1741,40 +1817,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,8 +1870,9 @@ 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);
+ *keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr,
+ common_gen_cb, common_gen_cb_parm);
xfree (keyparms);
}
@@ -1798,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;
@@ -1840,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);
}
@@ -3200,12 +3292,15 @@ 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,
- char **cache_nonce_addr, char **passwd_nonce_addr)
+ int *keygen_flags, const char *passphrase,
+ 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;
@@ -3220,22 +3315,26 @@ 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);
+ *keygen_flags, passphrase,
+ 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);
+ *keygen_flags, passphrase,
+ 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);
+ *keygen_flags, passphrase,
+ cache_nonce_addr, passwd_nonce_addr,
+ common_gen_cb, common_gen_cb_parm);
else
BUG();
@@ -4106,7 +4205,7 @@ parse_revocation_key (const char *fname,
pn++;
- for(i=0;i<MAX_FINGERPRINT_LEN && *pn;i++,pn+=2)
+ for(i=0;i<MAX_FINGERPRINT_LEN && *pn && !spacep (pn);i++,pn+=2)
{
int c=hextobyte(pn);
if(c==-1)
@@ -4247,12 +4346,13 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname,
if (!err)
{
/* Default to algo capabilities if subkey-usage is not
- provided */
+ provided. Take care not to include RENC. */
r = xmalloc_clear (sizeof(*r));
r->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)
@@ -5100,7 +5200,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;
@@ -5182,7 +5282,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;
@@ -5613,7 +5713,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 ),
@@ -5621,13 +5721,14 @@ 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);
+ &cache_nonce, NULL,
+ NULL, 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)
@@ -5671,7 +5772,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);
@@ -5681,7 +5783,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
{
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;
@@ -5693,8 +5794,47 @@ 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);
- else if (!card || (s = get_parameter_value (para, pCARDBACKUPKEY)))
+ 1, &keygen_flags);
+ 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),
@@ -5702,10 +5842,10 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
pub_root,
subkeytimestamp,
get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
- s? KEYGEN_FLAG_NO_PROTECTION : keygen_flags,
+ &keygen_flags,
get_parameter_passphrase (para),
- &cache_nonce, NULL);
- /* Get the pointer to the generated public subkey packet. */
+ &cache_nonce, NULL,
+ NULL, NULL);
if (!err)
{
kbnode_t node;
@@ -5714,16 +5854,12 @@ 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 (s)
- err = card_store_key_with_backup (ctrl,
- sub_psk, gnupg_homedir ());
}
}
else
{
err = gen_card_key (2, subkey_algo, 0, pub_root,
- &subkeytimestamp, expire, keygen_flags);
+ &subkeytimestamp, expire, &keygen_flags);
}
if (!err)
@@ -6097,7 +6233,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
keyblock,
keytime? keytime : cur_time,
expire, 1,
- keygen_flags);
+ &keygen_flags);
}
else
{
@@ -6113,8 +6249,8 @@ 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,
- passwd, &cache_nonce, &passwd_nonce);
+ keyblock, cur_time, expire, 1, &keygen_flags,
+ passwd, &cache_nonce, &passwd_nonce, NULL, NULL);
}
if (err)
goto leave;
@@ -6237,7 +6373,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)
{
@@ -6283,11 +6419,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;
@@ -6351,6 +6486,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
@@ -6369,7 +6508,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;
diff --git a/g10/options.h b/g10/options.h
index 5326ac8d8..571399967 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -408,6 +408,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)
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 31c77de93..34760a2d1 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -2765,7 +2765,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)
{
diff --git a/g10/sign.c b/g10/sign.c
index ee3fac1df..b6c4d2126 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),
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 6d0d1a659..08b67377c 100644
--- a/g13/g13-syshelp.c
+++ b/g13/g13-syshelp.c
@@ -583,7 +583,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 e15fd8812..9662dd028 100644
--- a/g13/g13.c
+++ b/g13/g13.c
@@ -104,6 +104,7 @@ enum cmd_and_opt_values {
oWithColons,
oDryRun,
oNoDetach,
+ oNoMount,
oNoRandomSeedFile,
oFakedSystemTime
@@ -138,6 +139,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")),
@@ -516,6 +518,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 <type>\n"
+ "MOUNT [--no-mount] <type>\n"
"\n"
"Mount an encrypted partition on the current device.\n"
- "<type> must be \"dm-crypt\" for now.";
+ "<type> 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);
+ log_debug ("now running \"findmnt %s\"\n", targetname_abs);
+ err = gnupg_exec_tool ("/bin/findmnt", argv, NULL, &result, NULL);
+
+ 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);
+ }
}
- 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];
-
- 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;
diff --git a/po/ca.po b/po/ca.po
index d6840dbc1..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
@@ -1954,16 +1954,16 @@ 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"
@@ -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: "
@@ -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?"
@@ -1832,14 +1832,14 @@ 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 011ea7d0d..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
@@ -1996,16 +1996,16 @@ 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"
msgstr "du må ikke bruge sammendragsalgoritmen »%s« i tilstanden %s\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 ""
@@ -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
@@ -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/de.po b/po/de.po
index 04ed2a697..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: [email protected]\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 <[email protected]>\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?"
@@ -1838,14 +1839,14 @@ 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"
@@ -4245,11 +4246,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: "
@@ -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"
@@ -9406,7 +9410,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"
@@ -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\"."
diff --git a/po/el.po b/po/el.po
index 7d4e8e738..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
@@ -1886,16 +1886,16 @@ 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 ""
"απαγορεύετε η χρήση του αλγόριθμου περίληψης \"%s\" στην κατάσταση %s\n"
@@ -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: "
@@ -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\"."
@@ -11225,7 +11228,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..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
@@ -1879,16 +1879,16 @@ 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"
@@ -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: "
@@ -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\"."
@@ -10993,7 +10996,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..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?"
@@ -1890,14 +1890,14 @@ 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"
@@ -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: "
@@ -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 5e106d6f5..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
@@ -1880,16 +1880,16 @@ 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"
@@ -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: "
@@ -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\"."
@@ -11089,7 +11092,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..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
@@ -1898,16 +1898,16 @@ 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"
@@ -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: "
@@ -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\"."
@@ -11195,7 +11198,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..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"
@@ -1932,13 +1932,13 @@ 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"
@@ -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 : "
@@ -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 d6972580a..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
@@ -1890,16 +1890,16 @@ 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"
@@ -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: "
@@ -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 <[email protected]>.\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\"."
@@ -11216,7 +11219,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..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
@@ -1881,16 +1881,16 @@ 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 ""
"Lehet, hogy nem használhatja \"%s\" kivonatoló algoritmust %s módban!\n"
@@ -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: "
@@ -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\"."
@@ -11148,7 +11151,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..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
@@ -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"
@@ -1887,16 +1887,16 @@ 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 ""
"anda tidak boleh menggunakan algoritma digest \"%s\" saat dalam mode %s.\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 ""
@@ -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 ""
@@ -9502,7 +9505,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"
@@ -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\"."
@@ -11140,7 +11143,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 +11151,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..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?"
@@ -1829,14 +1829,14 @@ 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"
@@ -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"
@@ -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/ja.po b/po/ja.po
index d067bf202..ab6a8dda4 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -5,13 +5,13 @@
# Yoshihiro Kajiki <[email protected]>, 1999.
# Takashi P.KATOH, 2002.
# NIIBE Yutaka <[email protected]>, 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: [email protected]\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 <[email protected]>\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管理コマンド"
diff --git a/po/nb.po b/po/nb.po
index 922cb4957..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?"
@@ -1859,14 +1859,14 @@ 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"
@@ -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: "
@@ -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 dcbab2240..1248d87c6 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 <[email protected]>, 1999, 2000, 2001, 2002, 2003-2004
-# Jakub Bogusz <[email protected]>, 2003-2020.
+# Jakub Bogusz <[email protected]>, 2003-2023.
#
msgid ""
msgstr ""
-"Project-Id-Version: gnupg-2.2.24\n"
+"Project-Id-Version: gnupg-2.4.3\n"
"Report-Msgid-Bugs-To: [email protected]\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 <[email protected]>\n"
"Language-Team: Polish <[email protected]>\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,20 @@ 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"
@@ -230,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"
@@ -276,10 +268,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 +325,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 +367,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 +388,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 +440,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 +507,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"
@@ -732,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
@@ -764,18 +747,14 @@ 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 ""
-"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?"
@@ -1154,19 +1133,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 +1320,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 +1402,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 +1478,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 +1600,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 +1655,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,26 +1789,23 @@ 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"
-
-#, fuzzy, c-format
-#| msgid "using cipher %s\n"
-msgid "using cipher %s.%s\n"
-msgstr "szyfrem %s\n"
+msgstr "nie można użyć pakietu SKESK ze względu na tryb S2K\n"
#, c-format
-msgid "'%s' already compressed\n"
-msgstr "„%s” już jest skompresowany\n"
+msgid "using cipher %s.%s\n"
+msgstr "szyfrem %s.%s\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"
@@ -1898,18 +1864,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 +2089,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 +2107,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 +2124,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 +2139,10 @@ msgstr ""
"odszyfrowania"
msgid "Options for unattended use"
-msgstr ""
+msgstr "Opcje użycia nieinteraktywnego"
msgid "Other options"
-msgstr ""
+msgstr "Pozostałe opcje"
msgid ""
"@\n"
@@ -2265,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"
@@ -2364,10 +2315,9 @@ 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 +2325,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 +2540,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 +2686,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 +2935,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 +3083,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 +3455,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 +3466,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 +3535,10 @@ 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 +3654,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 +3796,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 +3814,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 +3897,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 +4071,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 +4131,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: "
@@ -4273,22 +4204,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"
@@ -4521,11 +4452,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 ""
@@ -4554,12 +4485,11 @@ 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"
-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 +4733,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 +4753,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"
@@ -4904,6 +4829,8 @@ 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"
#, c-format
msgid "Note: sender requested \"for-your-eyes-only\"\n"
@@ -4915,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"
@@ -5096,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"
@@ -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,9 @@ 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 +5380,11 @@ 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 +5404,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 +5526,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 +5699,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 +5840,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"
@@ -6150,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 ""
@@ -6645,53 +6563,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 +6671,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 +6886,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 +6918,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 +7196,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 +7378,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 +7548,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 +7639,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 "
@@ -7966,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"
@@ -7980,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"
@@ -8269,10 +8166,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 +8320,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 +8340,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 +8349,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 +8553,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 +8583,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 +8791,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 +8850,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 +8864,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 +8874,7 @@ msgid "Smartcards"
msgstr "Karty procesorowe"
msgid "TPM"
-msgstr ""
+msgstr "TPM"
msgid "Network"
msgstr "Sieć"
@@ -9163,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 b32a1dcd5..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
@@ -1909,16 +1909,16 @@ 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"
msgstr "nu puteţi folosi algorimul de rezumat `%s' câtă vreme în modul %s\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"
@@ -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"
@@ -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"
@@ -1844,14 +1844,14 @@ 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 743ce6b0a..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
@@ -1887,16 +1887,16 @@ 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"
@@ -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: "
@@ -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"
@@ -11179,7 +11182,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..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
@@ -2027,16 +2027,16 @@ 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"
msgstr ""
@@ -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 ""
@@ -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: "
@@ -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?"
@@ -1800,14 +1800,14 @@ 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 730e9e135..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?"
@@ -1861,14 +1861,14 @@ 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» не можна використовувати у режимі "
@@ -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: "
@@ -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?"
@@ -1775,14 +1775,14 @@ 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 f14cce879..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"
@@ -1869,13 +1869,13 @@ 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"
@@ -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 "請輸入金鑰鑰柄: "
@@ -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 ""
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-p15.c b/scd/app-p15.c
index 8edd737a6..2bb90beaa 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)
@@ -5497,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;
@@ -5594,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)
@@ -5669,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;
@@ -5758,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
@@ -5772,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];
@@ -5801,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);
@@ -5862,6 +5955,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 +6054,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. */
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 468fed294..a9591a12c 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);
}
}
diff --git a/sm/encrypt.c b/sm/encrypt.c
index 16c48c8d5..202bbb92f 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
diff --git a/sm/import.c b/sm/import.c
index cd28cfbff..4f993ef30 100644
--- a/sm/import.c
+++ b/sm/import.c
@@ -681,6 +681,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. */
@@ -695,7 +774,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;
@@ -781,82 +859,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);
diff --git a/sm/verify.c b/sm/verify.c
index 53d1b468a..39226ed28 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -737,7 +737,12 @@ gpgsm_verify (ctrl_t ctrl, estream_t in_fp, estream_t data_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;
diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am
index b43fb1c91..f6a9c6099 100644
--- a/tests/cms/Makefile.am
+++ b/tests/cms/Makefile.am
@@ -99,8 +99,11 @@ 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/[email protected] \
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 000000000..58e80467d
--- /dev/null
+++ b/tests/cms/samplekeys/credential_private_encrypted_3DES.p12
Binary files differ
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 000000000..ced504c85
--- /dev/null
+++ b/tests/cms/samplekeys/credential_private_encrypted_AES256.p12
Binary files differ
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index 17815c61b..f8557e32b 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -1530,14 +1530,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,
@@ -1553,7 +1555,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;
@@ -1770,6 +1772,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 e66348232..056cdca66 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,137 @@ 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] [--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-copy, copies of keys also\n"
+ "stored 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 && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
+ log_error ("Error getting infos for a key: %s\n",
+ gpg_strerror (err));
+
+ 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
+ {
+ 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);
+ }
+ }
+ es_fflush (es_stdout);
+ 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
@@ -3728,6 +3860,7 @@ enum cmdids
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
cmdREADCERT, cmdWRITEKEY, cmdUNBLOCK, cmdFACTRST, cmdKDFSETUP,
cmdUIF, cmdAUTH, cmdYUBIKEY, cmdAPDU, cmdGPG, cmdGPGSM, cmdHISTORY,
+ cmdCHECKKEYS,
cmdINVCMD
};
@@ -3767,6 +3900,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},
@@ -3903,6 +4037,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:
@@ -4162,6 +4297,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);
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index 83b4bca21..22569a870 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 ") },
-
- { 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_group (300, N_("@Commands:\n ")),
+
+ 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 ()
};
@@ -1072,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
{
@@ -1151,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));
@@ -1173,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
{