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 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 \n" "HAVEKEY --list[=]\n" + "HAVEKEY --info \n" "\n" "Return success if at least one of the secret keys with the given\n" "keygrips is available. With --list return all available keygrips\n" - "as binary data; with bail out at this number of keygrips"; + "as binary data; with bail out at this number of keygrips.\n" + "In --info mode check just one keygrip."; static gpg_error_t cmd_havekey (assuan_context_t ctx, char *line) { - 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] \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=] [--openpgp|--mode1003] \n" + "EXPORT_KEY [--cache-nonce=] \\\n" + " [--openpgp|--mode1003] \n" "\n" "Export a secret key from the key store. The key will be encrypted\n" "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n" @@ -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; + if (!ctrl->ephemeral_mode) + { + char *dispserialno; - agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, - item->hexgrip); - rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force, - dispserialno); - xfree (dispserialno); - } + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + item->hexgrip); + rc = agent_write_shadow_key (ctrl, + grip, serialno, item->id, pubkey, force, + dispserialno); + xfree (dispserialno); + } xfree (pubkey); if (rc) goto leave; diff --git a/agent/pksign.c b/agent/pksign.c index a7b5c579f..322918969 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -371,13 +371,14 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, goto leave; } - if (keyref) + if (keyref && !ctrl->ephemeral_mode) { char *dispserialno; agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); - agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, + agent_write_shadow_key (ctrl, + ctrl->keygrip, serialno, keyref, pkbuf, 0, dispserialno); xfree (dispserialno); } diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 17f6fd559..c6450a20e 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -755,8 +755,9 @@ release_passphrase (char *pw) /* Stub function. */ int -agent_key_available (const unsigned char *grip) +agent_key_available (ctrl_t ctrl, const unsigned char *grip) { + (void)ctrl; (void)grip; return -1; /* Not available. */ } @@ -814,7 +815,7 @@ agent_askpin (ctrl_t ctrl, /* Replacement for the function in findkey.c. Here we write the key * to stdout. */ gpg_error_t -agent_write_private_key (const unsigned char *grip, +agent_write_private_key (ctrl_t ctrl, const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, const char *dispserialno, time_t timestamp) @@ -822,6 +823,7 @@ agent_write_private_key (const unsigned char *grip, char hexgrip[40+4+1]; char *p; + (void)ctrl; (void)force; (void)serialno; (void)keyref; 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 +speedo_spkgs += gpgme endif ifeq ($(TARGETOS),w32) -ifeq ($(WITH_GUI),1) -speedo_spkgs += \ - libpng \ - gdk-pixbuf atk pixman cairo pango gtk+ -endif -endif - -ifeq ($(TARGETOS),w32) - speedo_spkgs += pinentry -ifeq ($(WITH_GUI),1) -speedo_spkgs += gpa gpgex -endif - -else - -ifeq ($(WITH_GUI),1) -speedo_spkgs += pinentry gpa -endif - endif @@ -383,15 +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;ikey = 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 \n" + "MOUNT [--no-mount] \n" "\n" "Mount an encrypted partition on the current device.\n" - " must be \"dm-crypt\" for now."; + " must be \"dm-crypt\" for now. Option --no-mount\n" + "stops right before calling the mount command.\n"; static gpg_error_t cmd_mount (assuan_context_t ctx, char *line) { @@ -443,6 +444,9 @@ cmd_mount (assuan_context_t ctx, char *line) unsigned char *keyblob = NULL; size_t keybloblen; tupledesc_t tuples = NULL; + int nomount; + + nomount = has_option (line, "--no-mount"); line = skip_options (line); @@ -493,7 +497,7 @@ cmd_mount (assuan_context_t ctx, char *line) err = sh_dmcrypt_mount_container (ctrl, ctrl->server_local->devicename, - tuples); + tuples, nomount); leave: destroy_tupledesc (tuples); diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index 6f7173ec5..c3b5a6d77 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -220,7 +220,7 @@ mk_setup_area_prefix (size_t *r_length) } -/* Create a new g13 styloe DM-Crypt container on devoce DEVNAME. */ +/* Create a new g13 style DM-Crypt container on device DEVNAME. */ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) { @@ -538,10 +538,11 @@ sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) /* Mount a DM-Crypt container on device DEVNAME taking keys and other - * meta data from KEYBLOB. */ + * meta data from KEYBLOB. If NOMOUNT is set the actual mount command + * is not run. */ gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, - tupledesc_t keyblob) + tupledesc_t keyblob, int nomount) { gpg_error_t err; char *targetname_abs = NULL; @@ -696,8 +697,10 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, xfree (result); result = NULL; + g13_status (ctrl, STATUS_PLAINDEV, targetname_abs, NULL); + /* Mount if a mountpoint has been given. */ - if (ctrl->devti->mountpoint) + if (!nomount && ctrl->devti->mountpoint) { const char *argv[3]; @@ -766,32 +769,43 @@ sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname) goto leave; } - /* Run the regular umount command. */ + /* Run the regular umount command but first test with findmnt. */ { - const char *argv[2]; + const char *argv[3]; argv[0] = targetname_abs; argv[1] = NULL; - log_debug ("now running \"umount %s\"\n", targetname_abs); - err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); - } - if (err) - { - log_error ("error running umount: %s\n", gpg_strerror (err)); - if (1) - { - /* Try to show some info about processes using the partition. */ - const char *argv[3]; + log_debug ("now running \"findmnt %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/findmnt", argv, NULL, &result, NULL); - argv[0] = "-mv"; - argv[1] = targetname_abs; - argv[2] = NULL; - gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); - } - goto leave; - } - if (result && *result) /* (We should not see output to stdout). */ - log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + if (err) + log_info ("Note: device was not mounted\n"); + else + { + xfree (result); + result = NULL; + + argv[0] = targetname_abs; + argv[1] = NULL; + log_debug ("now running \"umount %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); + if (err) + { + log_error ("error running umount: %s\n", gpg_strerror (err)); + if (1) + { + /* Try to show some info about processes using the partition. */ + argv[0] = "-mv"; + argv[1] = targetname_abs; + argv[2] = NULL; + gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); + } + goto leave; + } + if (result && *result) /* (We should not see output to stdout). */ + log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + } + } xfree (result); result = NULL; 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 @@ -1953,16 +1953,16 @@ msgstr "no es pot usar un paquet asimètric ESK al estar en mode S2K\n" msgid "using cipher %s.%s\n" msgstr "Ha fallat el procés de signatura: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "«%s» ja està comprimida\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVÍS: «%s» és un fitxer buit\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "«%s» ja està comprimida\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "no podeu usar l'algorisme de resum %s mentre esteu en mode %s\n" @@ -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?" @@ -1831,14 +1831,14 @@ msgstr "v režimu S2K nelze použít SKESK paket\n" msgid "using cipher %s.%s\n" msgstr "použití šifry %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "„%s“ je již zkomprimován\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "POZOR: soubor „%s“ je prázdný\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "„%s“ je již zkomprimován\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "hashovací algoritmus „%s“ se nesmí používat v režimu %s\n" @@ -8974,6 +8974,9 @@ msgstr "uloží certifikát do datového objektu" msgid "store a private key to a data object" msgstr "uloží soukromý klíč do datového objektu" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Příkazy pro správu Yubikey" @@ -10568,8 +10571,8 @@ msgstr "spravuje historii příkazů" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10616,8 +10619,8 @@ msgstr "spravuje historii příkazů" #~ "Answer \"yes\" if you really want to delete this user ID.\n" #~ "All certificates are then also lost!" #~ msgstr "" -#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte \"ano" -#~ "\".\n" +#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte " +#~ "\"ano\".\n" #~ "Všechny certifikáty budou také ztraceny!" #~ msgid "Answer \"yes\" if it is okay to delete the subkey" diff --git a/po/da.po b/po/da.po index 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 @@ -1995,16 +1995,16 @@ msgstr "kan ikke bruge en symmetrisk ESK-pakke på grund af S2K-tilstanden\n" msgid "using cipher %s.%s\n" msgstr "bruger chiffer %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "»%s« allerede komprimeret\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "ADVARSEL: »%s« er en tom fil\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "»%s« allerede komprimeret\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2527,8 +2527,8 @@ msgstr "ADVARSEL: Usikre indelukkede mapperettigheder på hjemmemappe »%s«\n" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -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: translations@gnupg.org\n" -"PO-Revision-Date: 2023-05-30 13:46+0200\n" +"PO-Revision-Date: 2024-01-24 14:05+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German\n" "Language: de\n" @@ -230,8 +230,9 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Bitte geben Sie ein Passwort ein, um den empfangenen geheimen Schlüssel" -"%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu schützen." +"Bitte geben Sie ein Passwort ein, um den empfangenen geheimen " +"Schlüssel%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu " +"schützen." #, c-format msgid "failed to create stream from socket: %s\n" @@ -710,9 +711,9 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" -"Wenn Sie vollständiges Vertrauen haben, daß%%0A \"%s" -"\"%%0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit \"Ja" -"\"." +"Wenn Sie vollständiges Vertrauen haben, daß%%0A " +"\"%s\"%%0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit " +"\"Ja\"." msgid "Yes" msgstr "Ja" @@ -776,8 +777,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Möchten Sie den Schlüssel mit dem \"Keygrip\"%%0A %s%%0A %%C%%0Awirklich " "entfernen?" @@ -1837,14 +1838,14 @@ msgstr "Aufgrund des S2K-Modus kann ein SKESK Paket nicht benutzt werden\n" msgid "using cipher %s.%s\n" msgstr "benutze Cipher %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "`%s' ist bereits komprimiert\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "WARNUNG: '%s' ist eine leere Datei.\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "`%s' ist bereits komprimiert\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "Die Benutzung der Hashmethode %s ist im %s Modus nicht erlaubt.\n" @@ -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 @@ -1885,16 +1885,16 @@ msgstr "αδυναμία χρήσης ενός συμμετρικού πακέτ msgid "using cipher %s.%s\n" msgstr "χρήση του κρυπταλγόριθμου: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' ήδη συμπιέστηκε\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: `%s' είναι ένα άδειο αρχείο\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' ήδη συμπιέστηκε\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -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 @@ -1878,16 +1878,16 @@ msgstr "" msgid "using cipher %s.%s\n" msgstr "subskribado malsukcesis: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "'%s' jam densigita\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVERTO: '%s' estas malplena dosiero\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "'%s' jam densigita\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "Tiu komando ne eblas en la reĝimo %s.\n" @@ -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?" @@ -1889,14 +1889,14 @@ msgstr "no puede usar un paquete simétrico ESK debido al modo S2K\n" msgid "using cipher %s.%s\n" msgstr "usando cifrado %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' ya está comprimido\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "ATENCIÓN '%s' es un fichero vacío\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' ya está comprimido\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "no puede usar el resumen '%s' en modo %s\n" @@ -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 @@ -1879,16 +1879,16 @@ msgstr "S2K moodi tõttu ei saa sümmeetrilist ESK paketti kasutada\n" msgid "using cipher %s.%s\n" msgstr "kasutan šiffrit %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' on juba pakitud\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "HOIATUS: `%s' on tühi fail\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' on juba pakitud\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "sõnumilühendi algoritm \"%s\" ei ole moodis %s lubatud\n" @@ -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 @@ -1897,16 +1897,16 @@ msgstr "symmetristä ESK-pakettia ei voi käyttää S2K-tilan vuoksi\n" msgid "using cipher %s.%s\n" msgstr "käytetään salakirjoitusalgoritmia %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" on jo pakattu\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VAROITUS: \"%s\" on tyhjä tiedosto\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" on jo pakattu\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "tiivistealgoritmia \"%s\" ei voi käyttää %s-tilassa\n" @@ -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" @@ -1931,14 +1931,14 @@ msgstr "impossible d'utiliser un paquet ESK symétrique en mode S2K\n" msgid "using cipher %s.%s\n" msgstr "utilisation de l'algorithme de chiffrement %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "« %s » est déjà compressé\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "Attention : « %s » est un fichier vide\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "« %s » est déjà compressé\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm '%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -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 @@ -1889,16 +1889,16 @@ msgstr "non se pode empregar un paquete simétrico ESK debido ao modo S2K\n" msgid "using cipher %s.%s\n" msgstr "fallou a sinatura: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' xa está comprimido\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVISO: `%s' é un ficheiro baleiro\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' xa está comprimido\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "non se pode empregar o algoritmo de resumo \"%s\" no modo %s\n" @@ -3173,8 +3173,8 @@ msgstr "chave %08lX: non hai ID de usuario para a sinatura\n" #, fuzzy, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"chave %08lX: algoritmo de chave pública non soportado no ID de usuario \"%s" -"\"\n" +"chave %08lX: algoritmo de chave pública non soportado no ID de usuario " +"\"%s\"\n" #, fuzzy, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -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 .\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 @@ -1880,16 +1880,16 @@ msgstr "Nem tudok szimmetrikus ESK csomagot használni a S2K mód miatt!\n" msgid "using cipher %s.%s\n" msgstr "%s rejtjelezést használok.\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" már tömörített.\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "FIGYELEM: A(z) \"%s\" állomány üres.\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" már tömörített.\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -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" @@ -1886,16 +1886,16 @@ msgstr "tidak dapat menggunakan paket simetri ESK karena mode S2K\n" msgid "using cipher %s.%s\n" msgstr "menggunakan cipher %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' sudah dikompresi\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "PERINGATAN: `%s' adalah file kosong\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' sudah dikompresi\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -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?" @@ -1828,14 +1828,14 @@ msgstr "" msgid "using cipher %s.%s\n" msgstr "utilizzando il cifrario %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' già compresso\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "AVVISO: '%s' è un file vuoto\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' già compresso\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "l'algoritmo digest '%s' non può essere utilizzato in modalità %s\n" @@ -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 , 1999. # Takashi P.KATOH, 2002. # NIIBE Yutaka , 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021, 2022, 2023. +# 2020, 2021, 2022, 2023, 2024. # msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-11-20 10:50+0900\n" +"PO-Revision-Date: 2024-01-25 09:06+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -8729,6 +8729,9 @@ msgstr "証明書をデータオブジェクトに保管します" msgid "store a private key to a data object" msgstr "プライベート鍵をデータオブジェクトに保管する" +msgid "run various checks on the keys" +msgstr "鍵に対して様々なチェックを実行する" + msgid "Yubikey management commands" msgstr "Yubikey管理コマンド" 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?" @@ -1858,14 +1858,14 @@ msgstr "klarte ikke å bruke symmetrisk ESK-pakke på grunn av S2K-modus\n" msgid "using cipher %s.%s\n" msgstr "bruker krypteringsmetode %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "«%s» er allerede komprimert\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "ADVARSEL: «%s» er en tom fil\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "«%s» er allerede komprimert\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "du kan ikke bruke algoritme «%s» i %s-modus\n" @@ -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 , 1999, 2000, 2001, 2002, 2003-2004 -# Jakub Bogusz , 2003-2020. +# Jakub Bogusz , 2003-2023. # msgid "" msgstr "" -"Project-Id-Version: gnupg-2.2.24\n" +"Project-Id-Version: gnupg-2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2020-11-18 17:35+0100\n" +"PO-Revision-Date: 2023-10-20 21:29+0200\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -56,12 +56,12 @@ msgid "|pinentry-tt|Hide passphrase" msgstr "|pinentry-tt|Ukrycie hasła" msgid "Caps Lock is on" -msgstr "" +msgstr "Caps Lock jest włączony" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for generating a passphrase. msgid "Suggest" -msgstr "" +msgstr "Propozycja" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the generate button. Please use an appropriate @@ -70,26 +70,20 @@ msgstr "" #. translate this entry, a default English text (see source) #. will be used. The strcmp thingy is there to detect a #. non-translated string. -#, fuzzy -#| msgid "pinentry.qualitybar.tooltip" msgid "pinentry.genpin.tooltip" -msgstr "" -"Jakość wpisanego wyżej tekstu.\n" -"Kryteria jakości można uzyskać od administratora." +msgstr "Propozycja losowego hasła." #. TRANSLATORS: This is a text shown by pinentry if the option #. for formatted passphrase is enabled. The length is #. limited to about 900 characters. msgid "Note: The blanks are not part of the passphrase." -msgstr "" +msgstr "Uwaga: odstępy nie są częścią hasła." #. TRANSLATORS: This is a text shown by pinentry as title of a dialog #. telling the user that the entered new passphrase does not satisfy #. the passphrase constraints. Please keep it short. -#, fuzzy -#| msgid "Passphrase too long" msgid "Passphrase Not Allowed" -msgstr "Hasło zbyt długie" +msgstr "Hasło niedozwolone" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for the quality bar. @@ -127,10 +121,8 @@ msgstr "Hasło:" msgid "does not match - try again" msgstr "nie pasują - proszę spróbować jeszcze raz" -#, fuzzy -#| msgid "Passphrase Entry" msgid "Passphrases match." -msgstr "Wpisywanie hasła" +msgstr "Hasła się zgadzają." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the @@ -161,10 +153,10 @@ msgid "Bad Passphrase" msgstr "Niepoprawne hasło" msgid "Note: Request from the web browser." -msgstr "" +msgstr "Uwaga: żądanie z przeglądarki WWW." msgid "Note: Request from a remote site." -msgstr "" +msgstr "Uwaga: żądanie z maszyny zdalnej." #, c-format msgid "error getting serial number of card: %s\n" @@ -173,20 +165,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,25 +1789,22 @@ 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 @@ -1908,16 +1908,16 @@ msgstr "nu pot crea un pachet ESK simetric datorită modului S2K\n" msgid "using cipher %s.%s\n" msgstr "folosesc cifrul %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' deja compresat\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVERTISMENT: `%s' este un fişier gol\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' deja compresat\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2449,8 +2449,8 @@ msgstr "" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -3236,8 +3236,8 @@ msgstr "cheia %s: nici un ID utilizator pentru semnătură\n" #, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"cheia %s: algoritm cu cheie publică nesuportat pentru ID-ul utilizator \"%s" -"\"\n" +"cheia %s: algoritm cu cheie publică nesuportat pentru ID-ul utilizator " +"\"%s\"\n" #, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -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" @@ -1843,14 +1843,14 @@ msgstr "не могу использовать симметричный паке msgid "using cipher %s.%s\n" msgstr "используется симметричный шифр %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' уже сжат\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "Внимание: файл '%s' пуст\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' уже сжат\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "хеш-функцию '%s' нельзя использовать в режиме %s\n" @@ -9147,6 +9147,9 @@ msgstr "добавить сертификат в буфер" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -9617,8 +9620,8 @@ msgstr "" #~ msgid "error setting policy for key %s, user id \"%s\": %s" #~ msgstr "" -#~ "ошибка установки правил для ключа %s с идентификатором пользователя \"%s" -#~ "\": %s" +#~ "ошибка установки правил для ключа %s с идентификатором пользователя " +#~ "\"%s\": %s" #~ msgid "only SHA-1 is supported for OCSP responses\n" #~ msgstr "для ответов OCSP поддерживается только SHA-1\n" diff --git a/po/sk.po b/po/sk.po index 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 @@ -1886,16 +1886,16 @@ msgstr "v móde S2K nemožno použiť symetrický ESK paket\n" msgid "using cipher %s.%s\n" msgstr "použitá šifra %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' je už skomprimovaný\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VAROVANIE: súbor `%s' je prázdny\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' je už skomprimovaný\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "nemôžete použiť hashovací algoritmus \"%s\" v móde %s\n" @@ -3180,8 +3180,8 @@ msgstr "kľúč %08lX: neexistuje id užívateľa pre podpis\n" #, fuzzy, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"kľúč %08lX: nepodporovaný algoritmus verejného kľúča u užívateľského id \"%s" -"\"\n" +"kľúč %08lX: nepodporovaný algoritmus verejného kľúča u užívateľského id " +"\"%s\"\n" #, fuzzy, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -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 @@ -2026,16 +2026,16 @@ msgstr "kan inte använda symmetriska ESK-paket pga S2K-läge\n" msgid "using cipher %s.%s\n" msgstr "använder %s-chiffer\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" är redan komprimerad\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VARNING: \"%s\" är en tom fil\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" är redan komprimerad\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2570,8 +2570,8 @@ msgstr "" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -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?" @@ -1799,14 +1799,14 @@ msgstr "S2K kipi nedeniyle bir SKESK paketi kullanılamıyor\n" msgid "using cipher %s.%s\n" msgstr "%s.%s şifrelemesi kullanılıyor\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' halihazırda sıkıştırılmış\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "UYARI: '%s', boş bir dosya\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' halihazırda sıkıştırılmış\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "özet algoritması '%s', %s kipinde kullanılamayabilir\n" @@ -8910,6 +8910,9 @@ msgstr "bir veri nesnesine bir sertifika depola" msgid "store a private key to a data object" msgstr "bir veri nesnesine bir özel anahtar depola" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Yubikey yönetim konsolu" diff --git a/po/uk.po b/po/uk.po index 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?" @@ -1860,14 +1860,14 @@ msgstr "не можна використовувати симетричний п msgid "using cipher %s.%s\n" msgstr "використано шифр %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "«%s» вже стиснено\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "УВАГА: файл «%s» є порожнім\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "«%s» вже стиснено\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -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?" @@ -1774,14 +1774,14 @@ msgstr "由于在 S2K 模式,不能使用一个对称的 ESK 封包\n" msgid "using cipher %s.%s\n" msgstr "使用加密 %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "‘%s’已被压缩\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "警告:‘%s’是一个空文件\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "‘%s’已被压缩\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "摘要算法‘%s’不能在 %s 模式下使用\n" @@ -8666,6 +8666,9 @@ msgstr "储存一个证书到数据对象" msgid "store a private key to a data object" msgstr "储存私钥到数据对象" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Yubikey 管理命令" diff --git a/po/zh_TW.po b/po/zh_TW.po index 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" @@ -1868,14 +1868,14 @@ msgstr "因處於 S2K 模式下而無法使用對稱式 ESK 封包\n" msgid "using cipher %s.%s\n" msgstr "正在使用 %s 編密法\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' 已經被壓縮了\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "警告: '%s' 是個空檔案\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' 已經被壓縮了\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm '%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -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/edward.tester@demo.gnupg.com.p12 \ samplekeys/nistp256-openssl-self-signed.p12 \ + samplekeys/credential_private_encrypted_AES256.p12 \ + samplekeys/credential_private_encrypted_3DES.p12 \ samplemsgs/pwri-sample.cbc.p7m \ samplemsgs/pwri-sample.cbc-2.p7m \ samplemsgs/pwri-sample.gcm.p7m \ diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index 01276087f..7d80caa1e 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -51,4 +51,16 @@ Pass: start Cert: 4753a910e0c8b4caa8663ca0e4273a884eb5397d Key: 93be89edd11214ab74280d988a665b6beef876c5 +Name: credential_private_encrypted_AES256.p12 +Desc: AES256 encrypted P12 file from T6940 +Pass: qeFGds84/Sf0eKkJwcp6 +Cert: 20f65740b4a15bac6d6a299026756088f7604937,cbb4b26f93cfd9715ac9fa43440470df9395571b +Key: 37eedaaf317edb69029eed79f69dd479fb10bf08 + +Name: credential_private_encrypted_3DES.p12 +Desc: 3DES encrypted P12 file from T6940 +Pass: qeFGds84/Sf0eKkJwcp6 +Cert: 20f65740b4a15bac6d6a299026756088f7604937,cbb4b26f93cfd9715ac9fa43440470df9395571b +Key: 37eedaaf317edb69029eed79f69dd479fb10bf08 + # eof # diff --git a/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 b/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 new file mode 100644 index 000000000..58e80467d Binary files /dev/null and b/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 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 Binary files /dev/null and b/tests/cms/samplekeys/credential_private_encrypted_AES256.p12 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 ") }, + ARGPARSE_group (300, N_("@Commands:\n ")), - { aListComponents, "list-components", 256, N_("list all components") }, - { aCheckPrograms, "check-programs", 256, N_("check all programs") }, - { aListOptions, "list-options", 256, N_("|COMPONENT|list options") }, - { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") }, - { aCheckOptions, "check-options", 256, N_("|COMPONENT|check options") }, - { aApplyDefaults, "apply-defaults", 256, - N_("apply global default values") }, - { aApplyProfile, "apply-profile", 256, - N_("|FILE|update configuration files using FILE") }, - { aListDirs, "list-dirs", 256, - N_("get the configuration directories for @GPGCONF@") }, - { aListConfig, "list-config", 256, - N_("list global configuration file") }, - { aCheckConfig, "check-config", 256, - N_("check global configuration file") }, - { aQuerySWDB, "query-swdb", 256, - N_("query the software version database") }, - { aReload, "reload", 256, N_("reload all or a given component")}, - { aLaunch, "launch", 256, N_("launch a given component")}, - { aKill, "kill", 256, N_("kill a given component")}, - { aCreateSocketDir, "create-socketdir", 256, "@"}, - { aRemoveSocketDir, "remove-socketdir", 256, "@"}, + ARGPARSE_c (aListComponents, "list-components", N_("list all components")), + ARGPARSE_c (aCheckPrograms, "check-programs", N_("check all programs")), + ARGPARSE_c (aListOptions, "list-options", N_("|COMPONENT|list options")), + ARGPARSE_c (aChangeOptions, "change-options", + N_("|COMPONENT|change options")), + ARGPARSE_c (aCheckOptions, "check-options", N_("|COMPONENT|check options")), + ARGPARSE_c (aApplyDefaults, "apply-defaults", + N_("apply global default values")), + ARGPARSE_c (aApplyProfile, "apply-profile", + N_("|FILE|update configuration files using FILE")), + ARGPARSE_c (aListDirs, "list-dirs", + N_("get the configuration directories for @GPGCONF@")), + ARGPARSE_c (aListConfig, "list-config", + N_("list global configuration file")), + ARGPARSE_c (aCheckConfig, "check-config", + N_("check global configuration file")), + ARGPARSE_c (aQuerySWDB, "query-swdb", + N_("query the software version database")), + ARGPARSE_c (aReload, "reload", N_("reload all or a given component")), + ARGPARSE_c (aLaunch, "launch", N_("launch a given component")), + ARGPARSE_c (aKill, "kill", N_("kill a given component")), + ARGPARSE_c (aCreateSocketDir, "create-socketdir", "@"), + ARGPARSE_c (aRemoveSocketDir, "remove-socketdir", "@"), ARGPARSE_c (aShowVersions, "show-versions", ""), ARGPARSE_c (aShowConfigs, "show-configs", ""), /* hidden commands: for debugging */ @@ -117,24 +118,25 @@ static gpgrt_opt_t opts[] = ARGPARSE_c (aDotlockLock, "lock", "@"), ARGPARSE_c (aDotlockUnlock, "unlock", "@"), - { 301, NULL, 0, N_("@\nOptions:\n ") }, + ARGPARSE_header (NULL, N_("@\nOptions:\n ")), - { oOutput, "output", 2, N_("use as output file") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, + ARGPARSE_s_s (oOutput, "output", N_("use as output file")), + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")), + ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), + ARGPARSE_s_n (oRuntime, "runtime", + N_("activate changes at runtime, if possible")), ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), /* hidden options */ - { oHomedir, "homedir", 2, "@" }, - { oBuilddir, "build-prefix", 2, "@" }, - { oNull, "null", 0, "@" }, - { oNoVerbose, "no-verbose", 0, "@"}, + ARGPARSE_s_s (oHomedir, "homedir", "@"), + ARGPARSE_s_s (oBuilddir, "build-prefix", "@"), + ARGPARSE_s_n (oNull, "null", "@"), + ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"), ARGPARSE_s_n (oShowSocket, "show-socket", "@"), ARGPARSE_s_s (oChUid, "chuid", "@"), - ARGPARSE_end(), + ARGPARSE_end () }; @@ -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 {