diff --git a/Makefile.am b/Makefile.am index f3aa2067f..cfc68a0ad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -189,10 +189,25 @@ release: ./autogen.sh --force; \ cd $(abs_top_builddir); \ rm -rf dist; mkdir dist ; cd dist ; \ + mkopt=""; \ + if [ -n "$$CUSTOM_SWDB" ]; then \ + mkopt="CUSTOM_SWB=1"; \ + x=$$(grep '^OVERRIDE_TARBALLS=' \ + $$HOME/.gnupg-autogen.rc|cut -d= -f2);\ + if [ -f "$$x/swdb.lst" ]; then \ + echo "/* Copying swdb.lst from the overrides directory */"; \ + cp "$$x/swdb.lst" . ; \ + cp "$$x/swdb.lst.sig" . ; \ + fi; \ + fi; \ + echo "/* Running configure */";\ $(abs_top_srcdir)/configure --enable-maintainer-mode; \ + echo "/* Running make distcheck */";\ $(MAKE) distcheck TESTFLAGS=--parallel; \ + echo "/* Unpacking release */";\ $(TAR) xjf $(RELEASE_NAME).tar.bz2 ;\ - $(MAKE) -f $(RELEASE_NAME)/build-aux/speedo.mk w32-release ;\ + echo "/* Running $(MAKE) -f $(RELEASE_NAME)/build-aux/speedo.mk w32-release $$mkopt";\ + $(MAKE) -f $(RELEASE_NAME)/build-aux/speedo.mk w32-release $$mkopt;\ echo "/* Build finished at $$(date -uIseconds) */" ;\ echo "/*" ;\ echo " * Please run the final step interactivly:" ;\ diff --git a/NEWS b/NEWS index 86a1c6cbc..3d28c9925 100644 --- a/NEWS +++ b/NEWS @@ -1,14 +1,22 @@ -Noteworthy changes in version 2.2.41 (unreleased) +Noteworthy changes in version 2.2.42 (unreleased) ------------------------------------------------- * gpg: Support OCB encryption. [T6263] - * gpg: Also import stray revocation certificates. [rGbd825ead36af] + * gpg: New command --quick-update-pref. [rGf16c946be7] * gpg: New list-options show-pref and show-pref-verbose. [rGb6ba7054a0] - * gpg: New command --quick-update-pref. [rGf16c946be7] + * gpgsm: Support ECC certificates. [T6253] + + * gpgsm: Also announce AES256-CBC in signatures. [rGaa397fdcdb21] + + Release-info: https://dev.gnupg.org/T6307 + + +Noteworthy changes in version 2.2.41 (2022-12-09) +------------------------------------------------- * gpg: Add a notation to encryption subkeys in de-vs mode. [T6279] @@ -17,9 +25,20 @@ Noteworthy changes in version 2.2.41 (unreleased) * gpg: Report an error via status-fd for receiving a key from the agent. [T5151] - * gpgsm: Support ECC certificates. [T6253] + * gpg: Make --require-compliance work without the --status-fd + option. [r11f3232716] - * gpgsm: Also announce AES256-CBC in signatures. [rGaa397fdcdb21] + * gpg: Improve signature verification speed by a factor of more than + four. Double detached signing speed. [T5826] + + * gpg: New --export-filter export-revocs. [rGedbe30c152] + + * gpg: Import stray revocation certificates to improve WKD + usability. [rGbd825ead36af] + + * wkd: New option --add-revocs for gpg-wks-client. [rG2f4492f3be] + + * wkd: Ignore expired user-ids in gpg-wks-client. [T6292] * scd: Support the Telesec Signature Card v2.0. [T6252] diff --git a/README b/README index 1ff3f5f67..4f69df9e9 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ - The GNU Privacy Guard 2 - ========================= - Version 2.2 + The GNU Privacy Guard + ======================= + Version 2.2 (LTS) Copyright 1997-2019 Werner Koch Copyright 1998-2021 Free Software Foundation, Inc. @@ -25,9 +25,8 @@ can be freely used, modified and distributed under the terms of the GNU General Public License. - Note that the 2.0 series of GnuPG reached end-of-life on 2017-12-31. - It is not possible to install a 2.2.x version along with any 2.0.x - version. + Note that the 2.2 series of GnuPG is our current long term support + branch. The regular stable series is 2.3 (will be renamed to 2.4). * BUILD INSTRUCTIONS diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index a274fefff..d010d6c3e 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -80,6 +80,9 @@ # AUTHENTICODE_KEY=/home/foo/.gnupg/my-authenticode-key.p12 # AUTHENTICODE_CERTS=/home/foo/.gnupg/my-authenticode-certs.pem # +# If a tarball has not been published while building a release it +# may be stored in a directory specified by: +# OVERRIDE_TARBALLS=/home/foo/override-tarballs #--8<---------------cut here---------------end--------------->8--- @@ -132,7 +135,10 @@ help-wixlib: @echo '' @echo 'Afterwards w32-release will build also a wixlib.' - +# NB: we can't use +$(MAKE) here because we would need to define the +# dependencies of our packages. This does not make much sense given that +# we have a clear order in how they are build and concurrent builds +# would anyway clutter up the logs. SPEEDOMAKE := $(MAKE) -f $(SPEEDO_MK) UPD_SWDB=1 native: check-tools @@ -223,7 +229,7 @@ STATIC=0 # external packages. TARBALLS=$(shell pwd)/../tarballs -# Number of parallel make jobs +# Number of parallel make jobs in each package MAKE_J=3 # Name to use for the w32 installer and sources @@ -246,6 +252,7 @@ $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_CERTS)) $(eval $(call READ_AUTOGEN_template,OSSLSIGNCODE)) $(eval $(call READ_AUTOGEN_template,OSSLPKCS11ENGINE)) $(eval $(call READ_AUTOGEN_template,SCUTEMODULE)) +$(eval $(call READ_AUTOGEN_template,OVERRIDE_TARBALLS)) # All files given in AUTHENTICODE_FILES are signed before # they are put into the installer. @@ -873,17 +880,18 @@ endif # The playground area is our scratch area, where we unpack, build and # install the packages. $(stampdir)/stamp-directories: - $(MKDIR) $(root) || true - $(MKDIR) $(stampdir) || true - $(MKDIR) $(sdir) || true - $(MKDIR) $(bdir) || true - $(MKDIR) $(idir) || true + $(MKDIR) -p $(root) + $(MKDIR) -p $(stampdir) + $(MKDIR) -p $(sdir) + $(MKDIR) -p $(bdir) + $(MKDIR) -p $(idir) ifeq ($(TARGETOS),w32) - $(MKDIR) $(bdir6) || true - $(MKDIR) $(idir6) || true + $(MKDIR) -p $(bdir6) + $(MKDIR) -p $(idir6) endif touch $(stampdir)/stamp-directories + # Frob the name $1 by converting all '-' and '+' characters to '_'. define FROB_macro $(subst +,_,$(subst -,_,$(1))) @@ -977,7 +985,7 @@ endef # define SPKG_template -$(stampdir)/stamp-$(1)-00-unpack: $(stampdir)/stamp-directories +$(stampdir)/stamp-$(1)-00-unpack: @echo "speedo: /*" @echo "speedo: * $(1)" @echo "speedo: */" @@ -999,6 +1007,13 @@ $(stampdir)/stamp-$(1)-00-unpack: $(stampdir)/stamp-directories cd "$$$${pkg}"; \ AUTOGEN_SH_SILENT=1 ./autogen.sh; \ elif [ -n "$$$${tar}" ]; then \ + tar2="$(OVERRIDE_TARBALLS)/$$$$(basename $$$${tar})";\ + if [ -f "$$$${tar2}" ]; then \ + tar="$$$$tar2"; \ + echo "speedo: /*"; \ + echo "speedo: * Note: using an override"; \ + echo "speedo: */"; \ + fi; \ echo "speedo: unpacking $(1) from $$$${tar}"; \ case "$$$${tar}" in \ *.gz) pretar=zcat ;; \ @@ -1245,7 +1260,7 @@ endef # Insert the template for each source package. $(foreach spkg, $(speedo_spkgs), $(eval $(call SPKG_template,$(spkg)))) -$(stampdir)/stamp-final: $(stampdir)/stamp-directories clean-pkg-versions +$(stampdir)/stamp-final: clean-pkg-versions ifeq ($(TARGETOS),w32) $(stampdir)/stamp-final: $(addprefix $(stampdir)/stamp-w64-final-,$(speedo_w64_build_list)) endif @@ -1524,9 +1539,9 @@ endif # -# Check availibility of standard tools +# Check availibility of standard tools and prepare everything. # -check-tools: +check-tools: $(stampdir)/stamp-directories # diff --git a/configure.ac b/configure.ac index 53b804151..52f52951d 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.14" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [2]) -m4_define([mym4_micro], [41]) +m4_define([mym4_micro], [42]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release diff --git a/doc/gpg.texi b/doc/gpg.texi index 61d9089d8..9491dc83f 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2622,6 +2622,11 @@ opposite meaning. The options are: to put into DNS zone files. An ORIGIN line is printed before each record to allow diverting the records to the corresponding zone file. + @item export-revocs + Export only standalone revocation certificates of the key. This + option does not export revocations of 3rd party certificate + revocations. + @item export-dane Instead of outputting the key material output OpenPGP DANE records suitable to put into DNS zone files. An ORIGIN line is printed before diff --git a/doc/wks.texi b/doc/wks.texi index e398ccb4a..897d30d0c 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -222,6 +222,14 @@ operation. The format of @var{file} is one mail address (just the addrspec, e.g. "postel@@isi.edu") per line. Empty lines and lines starting with a '#' are ignored. +@item --add-revocs +@opindex add-revocs +If enabled append revocation certificates for the same addrspec as +used in the WKD to the key. Modern gpg version are able to import and +apply them for existing keys. Note that when used with the +@option{--mirror} command the revocation are searched in the local +keyring and not in an LDAP directory. + @item --verbose @opindex verbose Enable extra informational output. diff --git a/g10/card-util.c b/g10/card-util.c index 25c284e85..cfbe10e75 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -801,7 +801,6 @@ change_name (void) { tty_printf (_("Error: Combined name too long " "(limit is %d characters).\n"), 39); - xfree (isoname); rc = gpg_error (GPG_ERR_TOO_LARGE); goto leave; } diff --git a/g10/export.c b/g10/export.c index 8e17df3ed..ddd94cf05 100644 --- a/g10/export.c +++ b/g10/export.c @@ -62,15 +62,17 @@ struct export_stats_s }; -/* A global variable to store the selector created from +/* Global variables to store the selectors created from * --export-filter keep-uid=EXPR. * --export-filter drop-subkey=EXPR. + * --export-filter select=EXPR. * * FIXME: We should put this into the CTRL object but that requires a * lot more changes right now. */ static recsel_expr_t export_keep_uid; static recsel_expr_t export_drop_subkey; +static recsel_expr_t export_select_filter; /* An object used for a linked list to implement the @@ -80,6 +82,7 @@ struct export_filter_attic_s struct export_filter_attic_s *next; recsel_expr_t export_keep_uid; recsel_expr_t export_drop_subkey; + recsel_expr_t export_select_filter; }; static struct export_filter_attic_s *export_filter_attic; @@ -105,6 +108,8 @@ cleanup_export_globals (void) export_keep_uid = NULL; recsel_release (export_drop_subkey); export_drop_subkey = NULL; + recsel_release (export_select_filter); + export_select_filter = NULL; } @@ -129,6 +134,9 @@ parse_export_options(char *str,unsigned int *options,int noisy) {"export-pka", EXPORT_PKA_FORMAT, NULL, NULL }, {"export-dane", EXPORT_DANE_FORMAT, NULL, NULL }, + {"export-revocs", EXPORT_REVOCS, NULL, + N_("export only revocation certificates") }, + {"backup", EXPORT_BACKUP, NULL, N_("use the GnuPG key backup format")}, {"export-backup", EXPORT_BACKUP, NULL, NULL }, @@ -181,6 +189,8 @@ parse_export_options(char *str,unsigned int *options,int noisy) * * - secret :: 1 for a secret subkey, else 0. * - key_algo :: Public key algorithm id + * + * - select :: The key is only exported if the filter returns true. */ gpg_error_t parse_and_set_export_filter (const char *string) @@ -194,6 +204,8 @@ parse_and_set_export_filter (const char *string) err = recsel_parse_expr (&export_keep_uid, string+9); else if (!strncmp (string, "drop-subkey=", 12)) err = recsel_parse_expr (&export_drop_subkey, string+12); + else if (!strncmp (string, "select=", 7)) + err = recsel_parse_expr (&export_select_filter, string+7); else err = gpg_error (GPG_ERR_INV_NAME); @@ -214,6 +226,8 @@ push_export_filters (void) export_keep_uid = NULL; item->export_drop_subkey = export_drop_subkey; export_drop_subkey = NULL; + item->export_select_filter = export_select_filter; + export_select_filter = NULL; item->next = export_filter_attic; export_filter_attic = item; } @@ -232,6 +246,7 @@ pop_export_filters (void) cleanup_export_globals (); export_keep_uid = item->export_keep_uid; export_drop_subkey = item->export_drop_subkey; + export_select_filter = item->export_select_filter; } @@ -1885,6 +1900,78 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, } +/* Helper for do_export_stream which writes the own revocations + * certificates (if any) from KEYBLOCK to OUT. */ +static gpg_error_t +do_export_revocs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, + iobuf_t out, unsigned int options, int *any) +{ + gpg_error_t err = 0; + kbnode_t kbctx, node; + PKT_signature *sig; + + (void)ctrl; + + /* NB: walk_kbnode skips packets marked as deleted. */ + for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) + { + if (node->pkt->pkttype != PKT_SIGNATURE) + continue; + sig = node->pkt->pkt.signature; + + /* We are only interested in revocation certifcates. */ + if (!(IS_KEY_REV (sig) || IS_UID_REV (sig) || IS_SUBKEY_REV (sig))) + continue; + + if (!(sig->keyid[0] == keyid[0] && sig->keyid[1] == keyid[1])) + continue; /* Not a self-signature. */ + + /* Do not export signature packets which are marked as not + * exportable. */ + if (!(options & EXPORT_LOCAL_SIGS) + && !sig->flags.exportable) + continue; /* not exportable */ + + /* Do not export packets with a "sensitive" revocation key + * unless the user wants us to. */ + if (!(options & EXPORT_SENSITIVE_REVKEYS) + && sig->revkey) + { + int i; + + for (i = 0; i < sig->numrevkeys; i++) + if ((sig->revkey[i].class & 0x40)) + break; + if (i < sig->numrevkeys) + continue; + } + + if (!sig->flags.checked) + { + log_info ("signature not marked as checked - ignored\n"); + continue; + } + if (!sig->flags.valid) + { + log_info ("signature not not valid - ignored\n"); + continue; + } + + err = build_packet (out, node->pkt); + if (err) + { + log_error ("build_packet(%d) failed: %s\n", + node->pkt->pkttype, gpg_strerror (err)); + goto leave; + } + *any = 1; + } + + leave: + return err; +} + + /* Export the keys identified by the list of strings in USERS to the stream OUT. If SECRET is false public keys will be exported. With secret true secret keys will be exported; in this case 1 means the @@ -2070,6 +2157,32 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, NULL, NULL); commit_kbnode (&keyblock); } + else if (export_keep_uid || export_drop_subkey || export_select_filter) + { + /* Need to merge so that for example the "usage" property + * has been setup. */ + merge_keys_and_selfsig (ctrl, keyblock); + } + + + if (export_select_filter) + { + int selected = 0; + struct impex_filter_parm_s parm; + parm.ctrl = ctrl; + + for (parm.node = keyblock; parm.node; parm.node = parm.node->next) + { + if (recsel_select (export_select_filter, + impex_filter_getval, &parm)) + { + selected = 1; + break; + } + } + if (!selected) + continue; /* Skip this keyblock. */ + } if (export_keep_uid) { @@ -2086,10 +2199,15 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, } /* And write it. */ - err = do_export_one_keyblock (ctrl, keyblock, keyid, - out_help? out_help : out, - secret, options, stats, any, - desc, ndesc, descindex, cipherhd); + if ((options & EXPORT_REVOCS)) + err = do_export_revocs (ctrl, keyblock, keyid, + out_help? out_help : out, + options, any); + else + err = do_export_one_keyblock (ctrl, keyblock, keyid, + out_help? out_help : out, + secret, options, stats, any, + desc, ndesc, descindex, cipherhd); if (err) break; @@ -2132,8 +2250,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, keydb_release (kdbhd); if (err || !keyblock_out) release_kbnode( keyblock ); - if( !*any ) - log_info(_("WARNING: nothing exported\n")); + if( !*any && !opt.quiet) + log_info (_("WARNING: nothing exported\n")); return err; } diff --git a/g10/gpg.c b/g10/gpg.c index b50002582..e7180b818 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3804,9 +3804,11 @@ main (int argc, char **argv) set_debug (debug_level); if (opt.verbose) /* Print the compatibility flags. */ parse_compatibility_flags (NULL, &opt.compat_flags, compatibility_flags); + gnupg_set_compliance_extra_info (CO_EXTRA_INFO_MIN_RSA, opt.min_rsa_length); if ((opt.compat_flags & COMPAT_VSD_ALLOW_OCB)) gnupg_set_compliance_extra_info (CO_EXTRA_INFO_VSD_ALLOW_OCB, 1); + if (DBG_CLOCK) log_clock ("start"); diff --git a/g10/mainproc.c b/g10/mainproc.c index 8e4d848bb..096f16c71 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -765,7 +765,7 @@ proc_encrypted (CTX c, PACKET *pkt) result = GPG_ERR_NO_SECKEY; /* Compute compliance with CO_DE_VS. */ - if (!result && is_status_enabled () + if (!result && (is_status_enabled () || opt.flags.require_compliance) /* Overriding session key voids compliance. */ && !opt.override_session_key /* Check symmetric cipher. */ diff --git a/g10/options.h b/g10/options.h index b8bd96006..ccf7397d0 100644 --- a/g10/options.h +++ b/g10/options.h @@ -391,6 +391,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define EXPORT_PKA_FORMAT (1<<6) #define EXPORT_DANE_FORMAT (1<<7) #define EXPORT_BACKUP (1<<10) +#define EXPORT_REVOCS (1<<11) #define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_POLICY_URLS (1<<1) diff --git a/g10/plaintext.c b/g10/plaintext.c index 3bc86968b..10d567a8c 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -584,11 +584,16 @@ do_hash (gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode) } else { - while ((c = iobuf_get (fp)) != -1) + byte *buffer = xmalloc (32768); + int ret; + + while ((ret = iobuf_read (fp, buffer, 32768)) != -1) { if (md) - gcry_md_putc (md, c); + gcry_md_write (md, buffer, ret); } + + xfree (buffer); } } diff --git a/g10/sign.c b/g10/sign.c index f27231950..17c6bcdf8 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1211,8 +1211,8 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, iobuf_push_filter( inp, text_filter, &tfx ); } iobuf_push_filter( inp, md_filter, &mfx ); - while( iobuf_get(inp) != -1 ) - ; + while (iobuf_read (inp, NULL, 1<<30) != -1 ) + ; iobuf_close(inp); inp = NULL; } if( opt.verbose ) @@ -1220,8 +1220,8 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, } else { /* read, so that the filter can calculate the digest */ - while( iobuf_get(inp) != -1 ) - ; + while (iobuf_read (inp, NULL, 1<<30) != -1 ) + ; } } else { diff --git a/po/ca.po b/po/ca.po index fdc93b8b9..262669ec0 100644 --- a/po/ca.po +++ b/po/ca.po @@ -2111,6 +2111,11 @@ msgstr "la clau secreta és inusable" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "genera un certificat de revocació" + msgid "use the GnuPG key backup format" msgstr "" @@ -6875,6 +6880,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Nota: Aquesta clau ha estat desactivada.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/cs.po b/po/cs.po index ae0490199..88060f4ff 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1977,6 +1977,11 @@ msgstr "odstranit nepoužitelné části z klíče při exportu" msgid "remove as much as possible from key during export" msgstr "odstranit při exportu z klíče vše, co lze" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "vytvořit revokační certifikát" + msgid "use the GnuPG key backup format" msgstr "použít záložní formát klíče GnuPG" @@ -6504,6 +6509,11 @@ msgstr "schází RSA modulus nebo nemá velikost %d bitů\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "schází veřejný RSA exponent nebo je delší než %d bitů\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPIN ještě nebyl změněn\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "funkce PIN callback skončila chybou: %s\n" diff --git a/po/da.po b/po/da.po index 5651dd440..965e31a18 100644 --- a/po/da.po +++ b/po/da.po @@ -2123,6 +2123,11 @@ msgstr "fjern nøgledele der ikke kan bruges under eksport" msgid "remove as much as possible from key during export" msgstr "fjern så meget som muligt fra nøglen under eksport" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "opret et tilbagekaldscertifikat" + msgid "use the GnuPG key backup format" msgstr "" @@ -6862,6 +6867,11 @@ msgstr "RSA-modulus mangler eller har ikke størrelsen %d bit\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "RSA offentlig eksponent mangler eller større end %d bit\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPIN'en er endnu ikke ændret\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN-tilbagekald returnerede fejl: %s\n" diff --git a/po/de.po b/po/de.po index 9754b1a9a..a888f1817 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2022-04-25 18:05+0200\n" +"PO-Revision-Date: 2022-12-09 09:06+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "Language: de\n" @@ -1969,6 +1969,9 @@ msgstr "Unbrauchbare Teile des Schlüssel während des Exports entfernen" msgid "remove as much as possible from key during export" msgstr "Während des Exports soviel wie möglich vom Schlüssel entfernen" +msgid "export only revocation certificates" +msgstr "Nur Schlüsselwiderruf-Zertifikate exportieren" + msgid "use the GnuPG key backup format" msgstr "Das GnuPG Datensicherungsformat für Schlüssel benutzen" @@ -6559,13 +6562,16 @@ msgstr "Der RSA Modulus fehlt oder ist nicht %d Bits lang\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "Der öffentliche Exponent fehlt oder ist zu groß (mehr als %d Bit)\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Hinweis: Die Null-PIN wurde noch nicht geändert" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN-Callback meldete Fehler: %s\n" #, c-format msgid "the NullPIN has not yet been changed\n" -msgstr "Die Nullpin wurde noch nicht geändert\n" +msgstr "Die Null-PIN wurde noch nicht geändert\n" msgid "|N|Please enter a new PIN for the standard keys." msgstr "|N|Bitte eine neue PIN für den Standard-Schlüssel eingeben." @@ -9204,10 +9210,9 @@ msgstr "" #~ msgid " using certificate ID 0x%08lX\n" #~ msgstr " mittels Zertifikat ID 0x%08lX\n" -#, fuzzy #~ msgid "" #~ "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -#~ msgstr "Die Schlüsselserveroption \"%s\" ist im %s-Modus nicht erlaubt.\n" +#~ msgstr "Die Schlüsselserveroption \"%s\" ist im Tor-Modus nicht erlaubt.\n" #~ msgid "male" #~ msgstr "männlich" @@ -9224,53 +9229,6 @@ msgstr "" #~ msgid "only SHA-1 is supported for OCSP responses\n" #~ msgstr "Lediglich SHA-1 wird bei OCSP Antworten unterstützt\n" -#, fuzzy -#~| msgid "error creating temporary file: %s\n" -#~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n" -#~ msgstr "Fehler beim Erstellen einer temporären Datei: %s\n" - -#, fuzzy -#~| msgid "error creating temporary file: %s\n" -#~ msgid "error creating 'encryptions' TOFU table: %s\n" -#~ msgstr "Fehler beim Erstellen einer temporären Datei: %s\n" - -#, fuzzy -#~| msgid "error writing key: %s\n" -#~ msgid "resetting keydb: %s\n" -#~ msgstr "Fehler beim Schreiben des Schlüssels: %s\n" - -#, fuzzy -#~| msgid "" -#~| "Verified %ld message signed by \"%s\"\n" -#~| "in the past %s." -#~| msgid_plural "" -#~| "Verified %ld messages signed by \"%s\"\n" -#~| "in the past %s." -#~ msgid "%s: Verified %ld~signature in the past %s." -#~ msgid_plural "%s: Verified %ld~signatures in the past %s." -#~ msgstr[0] "" -#~ "%ld überprüfte Nachricht von \"%s\"\n" -#~ "in den letzten %s." -#~ msgstr[1] "" -#~ "%ld überprüfte Nachrichten von \"%s\"\n" -#~ "in den letzten %s." - -#, fuzzy -#~| msgid "" -#~| "Verified %ld message signed by \"%s\"\n" -#~| "in the past %s." -#~| msgid_plural "" -#~| "Verified %ld messages signed by \"%s\"\n" -#~| "in the past %s." -#~ msgid "Encrypted %ld~message in the past %s." -#~ msgid_plural "Encrypted %ld~messages in the past %s." -#~ msgstr[0] "" -#~ "%ld überprüfte Nachricht von \"%s\"\n" -#~ "in den letzten %s." -#~ msgstr[1] "" -#~ "%ld überprüfte Nachrichten von \"%s\"\n" -#~ "in den letzten %s." - #~ msgid "no keyserver known (use option --keyserver)\n" #~ msgstr "Kein Schlüsselserver bekannt (Option --keyserver verwenden)\n" diff --git a/po/el.po b/po/el.po index a35f85ff2..ff88a2d18 100644 --- a/po/el.po +++ b/po/el.po @@ -2044,6 +2044,11 @@ msgstr "μη χρησιμοποιήσιμο μυστικό κλειδί" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "δημιουργία ενός πιστοποιητικού ανάκλησης" + msgid "use the GnuPG key backup format" msgstr "" @@ -6743,6 +6748,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Σημείωση: Αυτό το κλειδί έχει απενεργοποιηθεί.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/eo.po b/po/eo.po index 3b77e6e94..88697cdde 100644 --- a/po/eo.po +++ b/po/eo.po @@ -2027,6 +2027,11 @@ msgstr "neuzebla sekreta ŝlosilo" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "krei revokatestilon" + msgid "use the GnuPG key backup format" msgstr "" @@ -6661,6 +6666,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Noto: Ĉi tiu ŝlosilo estas malŝaltita.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/es.po b/po/es.po index 7364c83c3..b0a74c2db 100644 --- a/po/es.po +++ b/po/es.po @@ -1990,6 +1990,11 @@ msgstr "borrar partes inutilizables de la clave al exportar" msgid "remove as much as possible from key during export" msgstr "borrar tanto como sea posible de la clave al exportar" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "genera un certificado de revocación" + msgid "use the GnuPG key backup format" msgstr "usar el formato de backup de claves GnuPG" @@ -6503,6 +6508,11 @@ msgstr "falta el módulo RSA o no es de %d bits\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "falta el exponente público RSA o es mayor de %d bits\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "el PIN-Nulo no ha sido cambiado\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "la función de manejo del PIN devolvió un error: %s\n" diff --git a/po/et.po b/po/et.po index 9871c13b5..66de18c22 100644 --- a/po/et.po +++ b/po/et.po @@ -2036,6 +2036,11 @@ msgstr "mittekasutatav salajane võti" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "genereeri tühistamise sertifikaat" + msgid "use the GnuPG key backup format" msgstr "" @@ -6665,6 +6670,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Märkus: See võti on blokeeritud.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/fi.po b/po/fi.po index eaadcbe84..dfedc0602 100644 --- a/po/fi.po +++ b/po/fi.po @@ -2052,6 +2052,11 @@ msgstr "salaista avainta ei voi käyttää" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "luo mitätöintivarmenne" + msgid "use the GnuPG key backup format" msgstr "" @@ -6726,6 +6731,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Huom: Tämä avain on poistettu käytöstä\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/fr.po b/po/fr.po index 7bec71507..2e9d1b95f 100644 --- a/po/fr.po +++ b/po/fr.po @@ -2054,6 +2054,11 @@ msgstr "supprimer les parties inutilisables de la clef pendant l'exportation" msgid "remove as much as possible from key during export" msgstr "supprimer autant que possible de la clef pendant l'exportation" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "générer un certificat de révocation" + msgid "use the GnuPG key backup format" msgstr "" @@ -6778,6 +6783,11 @@ msgstr "le module RSA est manquant ou sa taille n'est pas de %d bits\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "l'exposant public RSA est manquant ou plus grand que %d bits\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "le code personnel nul n'a pas encore été modifié\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "le rappel du code personnel a renvoyé une erreur : %s\n" diff --git a/po/gl.po b/po/gl.po index e79c7b989..4a1d544b7 100644 --- a/po/gl.po +++ b/po/gl.po @@ -2046,6 +2046,11 @@ msgstr "chave secreta non utilizable" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "xerar un certificado de revocación" + msgid "use the GnuPG key backup format" msgstr "" @@ -6729,6 +6734,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Nota: Esta chave está desactivada.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/hu.po b/po/hu.po index 42ca4b67e..4cbde016d 100644 --- a/po/hu.po +++ b/po/hu.po @@ -2035,6 +2035,11 @@ msgstr "használhatatlan titkos kulcs" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "visszavonási igazolás készítése" + msgid "use the GnuPG key backup format" msgstr "" @@ -6690,6 +6695,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Megjegyzés: Ez a kulcs le lett tiltva.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/id.po b/po/id.po index ed12a69f1..6fdd4e25e 100644 --- a/po/id.po +++ b/po/id.po @@ -2040,6 +2040,11 @@ msgstr "kunci rahasia tidak dapat dipakai" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "buat sertifikat revokasi" + msgid "use the GnuPG key backup format" msgstr "" @@ -6688,6 +6693,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Catatan: Kunci ini telah ditiadakan\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/it.po b/po/it.po index c59b9b1ee..6aa906387 100644 --- a/po/it.po +++ b/po/it.po @@ -1960,6 +1960,11 @@ msgstr "rimuovere parti inutilizzabili dalla chiave durante l'esportazione" msgid "remove as much as possible from key during export" msgstr "rimuovere il più possibile dalla chiave durante l'esportazione" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "genera un certificato di revoca" + msgid "use the GnuPG key backup format" msgstr "utilizzare il formato di backup della chiave GnuPG" @@ -6511,6 +6516,11 @@ msgstr "Modulo RSA mancante o non di dimensione %d bit\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "Esponente pubblico RSA mancante o superiore a %d bit\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "il NullPIN non è ancora stato modificato\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "Errore di richiamata PIN: %s\n" diff --git a/po/ja.po b/po/ja.po index f438d963f..78f742a01 100644 --- a/po/ja.po +++ b/po/ja.po @@ -1915,6 +1915,11 @@ msgstr "エクスポートの際、利用できない部分を除去する" msgid "remove as much as possible from key during export" msgstr "エクスポートの際、できるだけ除去する" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "失効証明書を生成" + msgid "use the GnuPG key backup format" msgstr "GnuPGの鍵のバックアップフォーマットを使います" @@ -6256,6 +6261,11 @@ msgstr "RSAのモジュラスがないか、%dビットのものではありま msgid "RSA public exponent missing or larger than %d bits\n" msgstr "RSA公開指数がないか %d ビットより大きすぎます\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPINが変更されていません\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PINコールバックがエラーを返しました: %s\n" diff --git a/po/nb.po b/po/nb.po index 72cb3370b..1da38c520 100644 --- a/po/nb.po +++ b/po/nb.po @@ -1970,6 +1970,11 @@ msgstr "fjern ubrukelige deler fra nøkkelen under eksportering" msgid "remove as much as possible from key during export" msgstr "fjern så mye som mulig fra nøkkelen under eksportering" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "lag opphevelsessertifikat" + msgid "use the GnuPG key backup format" msgstr "bruk GnuPG-format til sikkerhetskopiering av nøkkel" @@ -6448,6 +6453,11 @@ msgstr "RSA-modulus mangler eller er av annen størrelse enn %d bit\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "offentlig RSA-eksponent mangler eller er større enn %d bit\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPIN er ikke blitt endret enda\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN-callback returnerte en feil: %s\n" diff --git a/po/pl.po b/po/pl.po index 6aa8aed74..e055dd590 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1936,6 +1936,11 @@ 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" + msgid "use the GnuPG key backup format" msgstr "użycie formatu kopii zapasowej klucza GnuPG" @@ -6534,6 +6539,11 @@ 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" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "Zapytanie zwrotne o PIN zwróciło błąd: %s\n" diff --git a/po/pt.po b/po/pt.po index d86b2b7f1..39d89c6e8 100644 --- a/po/pt.po +++ b/po/pt.po @@ -2034,6 +2034,11 @@ msgstr "chave secreta não utilizável" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "gerar um certificado de revogação" + msgid "use the GnuPG key backup format" msgstr "" @@ -6683,6 +6688,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Nota: Esta chave foi desactivada.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/ro.po b/po/ro.po index 8b2e04dae..1deba4a79 100644 --- a/po/ro.po +++ b/po/ro.po @@ -2063,6 +2063,11 @@ msgstr "cheie secretă de nefolosit" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "generează un certificat de revocare" + msgid "use the GnuPG key backup format" msgstr "" @@ -6779,6 +6784,11 @@ msgstr "modulus-ul RSA lipseşte sau nu are %d biţi\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "exponentul public RSA lipseşte sau are mai mult de %d biţi\n" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Notă: Această cheie a fost deactivată.\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "apelul PIN a returnat eroare: %s\n" diff --git a/po/ru.po b/po/ru.po index 20272e35f..70a34b136 100644 --- a/po/ru.po +++ b/po/ru.po @@ -1938,6 +1938,11 @@ msgstr "удалить при экспорте непригодные части msgid "remove as much as possible from key during export" msgstr "при экспорте удалить из ключа как можно больше" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "создать сертификат отзыва" + msgid "use the GnuPG key backup format" msgstr "пользоваться архивным форматом ключей GnuPG" @@ -6482,6 +6487,11 @@ msgstr "Модули RSA пропущены, или их размер не ра msgid "RSA public exponent missing or larger than %d bits\n" msgstr "отсутствует открытая экспонента RSA, или ее размер превышает %d бит\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "пустой PIN до сих пор не изменен\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "Функция обработки PIN возвратила ошибку: %s\n" diff --git a/po/sk.po b/po/sk.po index a84d2c099..4cae53578 100644 --- a/po/sk.po +++ b/po/sk.po @@ -2043,6 +2043,11 @@ msgstr "nepoužiteľný tajný kľúč" msgid "remove as much as possible from key during export" msgstr "" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "vytvoriť revokačný certifikát" + msgid "use the GnuPG key backup format" msgstr "" @@ -6717,6 +6722,11 @@ msgstr "" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "" +#, fuzzy +#| msgid "Note: This key has been disabled.\n" +msgid "Note: PIN has not yet been enabled." +msgstr "Poznámka: Tento kľúč bol označený ako neplatný (disabled).\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "" diff --git a/po/sv.po b/po/sv.po index 1cb393d62..e29227df7 100644 --- a/po/sv.po +++ b/po/sv.po @@ -2160,6 +2160,11 @@ msgstr "ta bort oanvändbara delar från nyckeln under exportering" msgid "remove as much as possible from key during export" msgstr "ta bort så mycket som möjligt från nyckeln under exportering" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "generera ett spärrcertifikat" + msgid "use the GnuPG key backup format" msgstr "" @@ -6982,6 +6987,11 @@ msgstr "RSA modulus saknas eller är inte %d bitar stor\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "Publik RSA-exponent saknas eller större än %d bitar\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPIN har ännu inte ändrats\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN-återanrop returnerade fel: %s\n" diff --git a/po/tr.po b/po/tr.po index e6e4530cc..6aac67107 100644 --- a/po/tr.po +++ b/po/tr.po @@ -2099,6 +2099,11 @@ msgstr "ihraç sırasında anahtardan kullanışsız parçalar kaldırılır" msgid "remove as much as possible from key during export" msgstr "ihraç sırasında anahtardan mümkün olduğunca çok şey kaldırılır" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "bir yürürlükten kaldırma sertifikası üretir" + msgid "use the GnuPG key backup format" msgstr "" @@ -6892,6 +6897,11 @@ msgstr "RSA modülü ya eksik ya da %d bitlik değil\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "RSA genel üstel sayısı ya eksik ya da %d bitten büyük\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "BoşPIN henüz değişmedi\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN eylemcisi hata döndürdü: %s\n" diff --git a/po/uk.po b/po/uk.po index 9f1f5f6dc..010548ebe 100644 --- a/po/uk.po +++ b/po/uk.po @@ -1975,6 +1975,11 @@ msgstr "вилучити невикористовувані частини кл msgid "remove as much as possible from key during export" msgstr "вилучити максимум частин з ключа під час експортування" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "створити сертифікат відкликання" + msgid "use the GnuPG key backup format" msgstr "використовувати формат резервних копій ключів GnuPG" @@ -6600,6 +6605,11 @@ msgstr "" "Не вистачає відкритого показника RSA або розмірність показника перевищує %d " "бітів\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPIN ще не було змінено\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "Зворотний виклик пінкоду повернув повідомлення про помилку: %s\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index 82fbe8653..8a277317f 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -1894,6 +1894,11 @@ msgstr "导出时移除密钥中未使用的部分" msgid "remove as much as possible from key during export" msgstr "导出时尽可能移除密钥中的可选部分" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "生成一份吊销证书" + msgid "use the GnuPG key backup format" msgstr "使用 GnuPG 密钥备份格式" @@ -6192,6 +6197,11 @@ msgstr "RSA 余数缺失或者不是 %d 位长\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "RSA 公钥指数缺失或长于 %d 位\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "尚未变更 NullPIN\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN 回调返回错误:%s\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index 720eebbd9..c97ad99e7 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -1979,6 +1979,11 @@ msgstr "匯出時從金鑰中移除無法使用的部分" msgid "remove as much as possible from key during export" msgstr "匯出時盡可能地從金鑰中移除" +#, fuzzy +#| msgid "generate a revocation certificate" +msgid "export only revocation certificates" +msgstr "產生撤銷憑證" + msgid "use the GnuPG key backup format" msgstr "" @@ -6464,6 +6469,11 @@ msgstr "RSA 模組缺漏或者並非 %d 位元大\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "RSA 公用指數缺漏或者大於 %d 位元\n" +#, fuzzy +#| msgid "the NullPIN has not yet been changed\n" +msgid "Note: PIN has not yet been enabled." +msgstr "NullPIN 還沒有變更過\n" + #, c-format msgid "PIN callback returned error: %s\n" msgstr "收回個人識別碼 (PIN) 時傳回錯誤: %s\n" diff --git a/scd/app-p15.c b/scd/app-p15.c index f1f1168ec..4a855b97d 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -744,7 +744,15 @@ select_and_read_record (app_t app, unsigned short efid, int recno, /* On CardOS with a Linear TLV file structure the records starts * with some tag (often the record number) followed by the length * byte for this record. Detect and remove this prefix. */ - if (*buflen > 2 && (*buffer)[0] != 0x30 && (*buffer)[1] == *buflen - 2) + if (*buflen == 2 && !(*buffer)[0] && !(*buffer)[1]) + ; /* deleted record. */ + else if (*buflen > 3 && (*buffer)[0] == 0xff + && buf16_to_uint ((*buffer)+1) == *buflen - 3) + { + memmove (*buffer, *buffer + 3, *buflen - 3); + *buflen = *buflen - 3; + } + else if (*buflen > 2 && (*buffer)[0] != 0x30 && (*buffer)[1] == *buflen - 2) { memmove (*buffer, *buffer + 2, *buflen - 2); *buflen = *buflen - 2; @@ -1771,6 +1779,9 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result) starting with 0x00 or 0xff as these values are commonly used to pad data blocks and are no valid ASN.1 encoding. Note the special handling for record mode at the end of the loop. */ + if (record_mode && buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ + while (n && *p && *p != 0xff) { const unsigned char *pp; @@ -2026,6 +2037,8 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result) err = 0; goto leave; } + if (buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ p = buffer; n = buflen; } @@ -2075,6 +2088,9 @@ read_ef_pukdf (app_t app, unsigned short fid, pukdf_object_t *result) * starting with 0x00 or 0xff as these values are commonly used to * pad data blocks and are no valid ASN.1 encoding. Note the * special handling for record mode at the end of the loop. */ + if (record_mode && buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ + while (n && *p && *p != 0xff) { const unsigned char *pp; @@ -2352,6 +2368,8 @@ read_ef_pukdf (app_t app, unsigned short fid, pukdf_object_t *result) err = 0; goto leave; } + if (buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ p = buffer; n = buflen; } @@ -2402,6 +2420,9 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result) starting with 0x00 or 0xff as these values are commonly used to pad data blocks and are no valid ASN.1 encoding. Note the special handling for record mode at the end of the loop. */ + if (record_mode && buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ + while (n && *p && *p != 0xff) { const unsigned char *pp; @@ -2623,8 +2644,8 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result) err = 0; next_record: - xfree (authid); - xfree (label); + xfree (authid); authid = NULL; + xfree (label); label = NULL; /* If the card uses a record oriented file structure, read the * next record. Otherwise we keep on parsing the current buffer. */ recno++; @@ -2633,11 +2654,14 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result) xfree (buffer); buffer = NULL; err = select_and_read_record (app, 0, recno, "CDF", &buffer, &buflen, NULL); - if (err) { - if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) - err = 0; - goto leave; - } + if (err) + { + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + err = 0; + goto leave; + } + if (buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ p = buffer; n = buflen; } @@ -2726,6 +2750,9 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result) starting with 0x00 or 0xff as these values are commonly used to pad data blocks and are no valid ASN.1 encoding. Note the special handling for record mode at the end of the loop. */ + if (record_mode && buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ + while (n && *p && *p != 0xff) { const unsigned char *pp; @@ -3295,6 +3322,8 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result) err = 0; goto leave; } + if (buflen == 2 && !buffer[0] && !buffer[1]) + goto next_record; /* Deleted record - continue with next */ p = buffer; n = buflen; } diff --git a/sm/certchain.c b/sm/certchain.c index d2a180062..ba9f3ff83 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -350,7 +350,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist) /* With no critical policies this is only a warning */ if (!any_critical) { - if (!opt.quiet) + if (opt.verbose) do_list (0, listmode, fplist, _("Note: non-critical certificate policy not allowed")); return 0; @@ -380,7 +380,8 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist) /* With no critical policies this is only a warning */ if (!any_critical) { - do_list (0, listmode, fplist, + if (opt.verbose) + do_list (0, listmode, fplist, _("Note: non-critical certificate policy not allowed")); return 0; } diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 3aa8f98c4..2139011e0 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -74,6 +74,7 @@ enum cmd_and_opt_values oWithColons, oBlacklist, oNoAutostart, + oAddRevocs, oDummy }; @@ -100,9 +101,9 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aRemoveKey, "remove-key", "remove a key from a directory"), ARGPARSE_c (aPrintWKDHash, "print-wkd-hash", - "Print the WKD identifier for the given user ids"), + "print the WKD identifier for the given user ids"), ARGPARSE_c (aPrintWKDURL, "print-wkd-url", - "Print the WKD URL for the given user id"), + "print the WKD URL for the given user id"), ARGPARSE_group (301, ("@\nOptions:\n ")), @@ -117,6 +118,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_s (oBlacklist, "blacklist", "@"), ARGPARSE_s_s (oDirectory, "directory", "@"), + ARGPARSE_s_n (oAddRevocs, "add-revocs", "add revocation certificates"), ARGPARSE_s_s (oFakeSubmissionAddr, "fake-submission-addr", "@"), @@ -254,6 +256,9 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts) case oBlacklist: add_blacklist (pargs->r.ret_str); break; + case oAddRevocs: + opt.add_revocs = 1; + break; case aSupported: case aCreate: @@ -1090,6 +1095,9 @@ command_check (char *userid) log_info (" created: %s\n", asctimestamp (sl->created)); if (sl->mbox) log_info (" addr-spec: %s\n", sl->mbox); + if (sl->expired || sl->revoked) + log_info (" flags:%s%s\n", + sl->expired? " expired":"", sl->revoked?" revoked":""); } } if (!found) @@ -1128,6 +1136,7 @@ command_send (const char *fingerprint, const char *userid) uidinfo_list_t uidlist = NULL; uidinfo_list_t uid, thisuid; time_t thistime; + int any; if (classify_user_id (fingerprint, &desc, 1) || !(desc.mode == KEYDB_SEARCH_MODE_FPR @@ -1145,7 +1154,7 @@ command_send (const char *fingerprint, const char *userid) err = gpg_error (GPG_ERR_INV_USER_ID); goto leave; } - err = wks_get_key (&key, fingerprint, addrspec, 0); + err = wks_get_key (&key, fingerprint, addrspec, 0, 1); if (err) goto leave; @@ -1189,12 +1198,20 @@ command_send (const char *fingerprint, const char *userid) } thistime = 0; thisuid = NULL; + any = 0; for (uid = uidlist; uid; uid = uid->next) { if (!uid->mbox) continue; /* Should not happen anyway. */ if (policy->mailbox_only && ascii_strcasecmp (uid->uid, uid->mbox)) continue; /* UID has more than just the mailbox. */ + if (uid->expired) + { + if (opt.verbose) + log_info ("ignoring expired user id '%s'\n", uid->uid); + continue; + } + any = 1; if (uid->created > thistime) { thistime = uid->created; @@ -1203,6 +1220,14 @@ command_send (const char *fingerprint, const char *userid) } if (!thisuid) thisuid = uidlist; /* This is the case for a missing timestamp. */ + if (!any) + { + log_error ("public key %s has no mail address '%s'\n", + fingerprint, addrspec); + err = gpg_error (GPG_ERR_INV_USER_ID); + goto leave; + } + if (opt.verbose) log_info ("submitting key with user id '%s'\n", thisuid->uid); @@ -1213,7 +1238,7 @@ command_send (const char *fingerprint, const char *userid) estream_t newkey; es_rewind (key); - err = wks_filter_uid (&newkey, key, thisuid->uid, 0); + err = wks_filter_uid (&newkey, key, thisuid->uid, 1); if (err) { log_error ("error filtering key: %s\n", gpg_strerror (err)); @@ -1238,11 +1263,47 @@ command_send (const char *fingerprint, const char *userid) * the key again. */ es_fclose (key); key = NULL; - err = wks_get_key (&key, fingerprint, addrspec, 1); + err = wks_get_key (&key, fingerprint, addrspec, 1, 1); if (err) goto leave; } + if (opt.add_revocs) + { + if (es_fseek (key, 0, SEEK_END)) + { + err = gpg_error_from_syserror (); + log_error ("error seeking stream: %s\n", gpg_strerror (err)); + goto leave; + } + err = wks_find_add_revocs (key, addrspec); + if (err) + { + log_error ("error finding revocations for '%s': %s\n", + addrspec, gpg_strerror (err)); + goto leave; + } + } + + + /* Now put the armor around the key. */ + { + estream_t newkey; + + es_rewind (key); + err = wks_armor_key (&newkey, key, + no_encrypt? NULL + /* */ : ("Content-Type: application/pgp-keys\n" + "\n")); + if (err) + { + log_error ("error armoring key: %s\n", gpg_strerror (err)); + goto leave; + } + es_fclose (key); + key = newkey; + } + /* Hack to support posteo but let them disable this by setting the * new policy-version flag. */ if (policy->protocol_version < 3 @@ -1287,7 +1348,7 @@ command_send (const char *fingerprint, const char *userid) if (no_encrypt) { void *data; - size_t datalen, n; + size_t datalen; if (posteo_hack) { @@ -1312,16 +1373,7 @@ command_send (const char *fingerprint, const char *userid) goto leave; } key = NULL; - /* We need to skip over the first line which has a content-type - * header not needed here. */ - for (n=0; n < datalen ; n++) - if (((const char *)data)[n] == '\n') - { - n++; - break; - } - - err = mime_maker_add_body_data (mime, (char*)data + n, datalen - n); + err = mime_maker_add_body_data (mime, data, datalen); xfree (data); if (err) goto leave; @@ -1808,7 +1860,7 @@ domain_matches_mbox (const char *domain, const char *mbox) /* Core of mirror_one_key with the goal of mirroring just one uid. * UIDLIST is used to figure out whether the given MBOX occurs several - * times in UIDLIST and then to single out the newwest one. This is + * times in UIDLIST and then to single out the newest one. This is * so that for a key with * uid: Joe Someone * uid: Joe @@ -1849,24 +1901,36 @@ mirror_one_keys_userid (estream_t key, const char *mbox, uidinfo_list_t uidlist, err = gpg_error (GPG_ERR_NO_USER_ID); goto leave; } - /* FIXME: Consult blacklist. */ - - /* Only if we have more than one user id we bother to run the - * filter. In this case the result will be put into NEWKEY*/ + /* Always filter the key so that the result will be non-armored. */ es_rewind (key); - if (uidlist->next) + err = wks_filter_uid (&newkey, key, thisuid->uid, 1); + if (err) { - err = wks_filter_uid (&newkey, key, thisuid->uid, 0); - if (err) - { - log_error ("error filtering key %s: %s\n", fpr, gpg_strerror (err)); - err = gpg_error (GPG_ERR_NO_PUBKEY); - goto leave; - } + log_error ("error filtering key %s: %s\n", fpr, gpg_strerror (err)); + err = gpg_error (GPG_ERR_NO_PUBKEY); + goto leave; } - err = wks_install_key_core (newkey? newkey : key, mbox); + if (opt.add_revocs) + { + if (es_fseek (newkey, 0, SEEK_END)) + { + err = gpg_error_from_syserror (); + log_error ("error seeking stream: %s\n", gpg_strerror (err)); + goto leave; + } + err = wks_find_add_revocs (newkey, mbox); + if (err) + { + log_error ("error finding revocations for '%s': %s\n", + mbox, gpg_strerror (err)); + goto leave; + } + es_rewind (newkey); + } + + err = wks_install_key_core (newkey, mbox); if (opt.verbose) log_info ("key %s published for '%s'\n", fpr, mbox); mirror_one_key_parm.nuids++; @@ -1905,6 +1969,8 @@ mirror_one_key (estream_t key) { if (!uid->mbox || (uid->flags & 1)) continue; /* No mail box or already processed. */ + if (uid->expired) + continue; if (!domain_matches_mbox (domain, uid->mbox)) continue; /* We don't want this one. */ if (is_in_blacklist (uid->mbox)) diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h index 32aa8c328..a7c17ca52 100644 --- a/tools/gpg-wks.h +++ b/tools/gpg-wks.h @@ -39,6 +39,7 @@ struct int use_sendmail; int with_colons; int no_autostart; + int add_revocs; const char *output; const char *gpg_program; const char *directory; @@ -80,6 +81,8 @@ struct uidinfo_list_s time_t created; /* Time the userid was created. */ char *mbox; /* NULL or the malloced mailbox from UID. */ unsigned int flags; /* These flags are cleared on creation. */ + unsigned int expired:1; + unsigned int revoked:1; char uid[1]; }; typedef struct uidinfo_list_s *uidinfo_list_t; @@ -91,11 +94,14 @@ void wks_set_status_fd (int fd); void wks_write_status (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3); void free_uidinfo_list (uidinfo_list_t list); gpg_error_t wks_get_key (estream_t *r_key, const char *fingerprint, - const char *addrspec, int exact); + const char *addrspec, int exact, int binary); gpg_error_t wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes); gpg_error_t wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid, int binary); +gpg_error_t wks_armor_key (estream_t *r_newkey, estream_t key, + const char *prefix); +gpg_error_t wks_find_add_revocs (estream_t key, const char *addrspec); gpg_error_t wks_send_mime (mime_maker_t mime); gpg_error_t wks_parse_policy (policy_flags_t flags, estream_t stream, int ignore_unknown); diff --git a/tools/wks-util.c b/tools/wks-util.c index 3044fe2f8..2e8541491 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -101,7 +101,8 @@ wks_write_status (int no, const char *format, ...) * updated. C-style escaping is removed from UID. On error ERRNO is * set and NULL returned. */ static uidinfo_list_t -append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created) +append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created, + int expired, int revoked) { uidinfo_list_t r, sl; char *plainuid; @@ -121,6 +122,8 @@ append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created) sl->created = created; sl->flags = 0; sl->mbox = mailbox_from_userid (plainuid); + sl->expired = !!expired; + sl->revoked = !!revoked; sl->next = NULL; if (!*list) *list = sl; @@ -150,6 +153,21 @@ free_uidinfo_list (uidinfo_list_t list) } +static void +debug_gpg_invocation (const char *func, const char **argv) +{ + int i; + + if (!(opt.debug & DBG_EXTPROG_VALUE)) + return; + + log_debug ("%s: exec '%s' with", func, opt.gpg_program); + for (i=0; argv[i]; i++) + log_printf (" '%s'", argv[i]); + log_printf ("\n"); +} + + struct get_key_status_parm_s { @@ -164,7 +182,8 @@ get_key_status_cb (void *opaque, const char *keyword, char *args) { struct get_key_status_parm_s *parm = opaque; - /*log_debug ("%s: %s\n", keyword, args);*/ + if (DBG_CRYPTO) + log_debug ("%s: %s\n", keyword, args); if (!strcmp (keyword, "EXPORTED")) { parm->count++; @@ -177,10 +196,11 @@ get_key_status_cb (void *opaque, const char *keyword, char *args) * mail address ADDRSPEC is included in the key. If EXACT is set the * returned user id must match Addrspec exactly and not just in the * addr-spec (mailbox) part. The key is returned as a new memory - * stream at R_KEY. */ + * stream at R_KEY. If BINARY is set the returned key is + * non-armored. */ gpg_error_t wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec, - int exact) + int exact, int binary) { gpg_error_t err; ccparray_t ccp; @@ -202,8 +222,9 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec, } /* Prefix the key with the MIME content type. */ - es_fputs ("Content-Type: application/pgp-keys\n" - "\n", key); + if (!binary) + es_fputs ("Content-Type: application/pgp-keys\n" + "\n", key); filterexp = es_bsprintf ("keep-uid=%s= %s", exact? "uid":"mbox", addrspec); if (!filterexp) @@ -223,7 +244,8 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec, ccparray_put (&ccp, "--batch"); ccparray_put (&ccp, "--status-fd=2"); ccparray_put (&ccp, "--always-trust"); - ccparray_put (&ccp, "--armor"); + if (!binary) + ccparray_put (&ccp, "--armor"); ccparray_put (&ccp, "--export-options=export-minimal"); ccparray_put (&ccp, "--export-filter"); ccparray_put (&ccp, filterexp); @@ -239,6 +261,7 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec, goto leave; } parm.fpr = fingerprint; + debug_gpg_invocation (__func__, argv); err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL, NULL, key, get_key_status_cb, &parm); @@ -276,6 +299,22 @@ key_status_cb (void *opaque, const char *keyword, char *args) } +/* Parse field 1 and set revoked and expired on return. */ +static void +set_expired_revoked (const char *string, int *expired, int *revoked) +{ + *expired = *revoked = 0; + /* Look at letters and stop at the first digit. */ + for ( ;*string && !digitp (string); string++) + { + if (*string == 'e') + *expired = 1; + else if (*string == 'r') + *revoked = 1; + } +} + + /* Run gpg on KEY and store the primary fingerprint at R_FPR and the * list of mailboxes at R_MBOXES. Returns 0 on success; on error NULL * is stored at R_FPR and R_MBOXES and an error code is returned. @@ -296,6 +335,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) int lnr; char *fpr = NULL; uidinfo_list_t mboxes = NULL; + int expired, revoked; if (r_fpr) *r_fpr = NULL; @@ -332,6 +372,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) err = gpg_error_from_syserror (); goto leave; } + debug_gpg_invocation (__func__, argv); err = gnupg_exec_tool_stream (opt.gpg_program, argv, key, NULL, listing, key_status_cb, NULL); @@ -343,6 +384,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) es_rewind (listing); lnr = 0; + expired = revoked = 0; maxlen = 2048; /* Set limit. */ while ((len = es_read_line (listing, &line, &length_of_line, &maxlen)) > 0) { @@ -387,12 +429,20 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) err = gpg_error (GPG_ERR_INV_ENGINE); goto leave; } - if (lnr > 1 && !strcmp (fields[0], "pub")) + if (!strcmp (fields[0], "pub")) { - /* More than one public key. */ - err = gpg_error (GPG_ERR_TOO_MANY); - goto leave; + if (lnr > 1) + { + /* More than one public key. */ + err = gpg_error (GPG_ERR_TOO_MANY); + goto leave; + } + if (nfields > 1) + set_expired_revoked (fields[1], &expired, &revoked); + else + expired = revoked = 0; } + if (!strcmp (fields[0], "sub") || !strcmp (fields[0], "ssb")) break; /* We can stop parsing here. */ @@ -407,8 +457,13 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) } else if (!strcmp (fields[0], "uid") && nfields > 9) { + int uidexpired, uidrevoked; + + set_expired_revoked (fields[1], &uidexpired, &uidrevoked); if (!append_to_uidinfo_list (&mboxes, fields[9], - parse_timestamp (fields[5], NULL))) + parse_timestamp (fields[5], NULL), + expired || uidexpired, + revoked || uidrevoked)) { err = gpg_error_from_syserror (); goto leave; @@ -510,6 +565,7 @@ wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid, err = gpg_error_from_syserror (); goto leave; } + debug_gpg_invocation (__func__, argv); err = gnupg_exec_tool_stream (opt.gpg_program, argv, key, NULL, newkey, key_status_cb, NULL); @@ -531,6 +587,124 @@ wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid, } +/* Put the ascii-armor around KEY and return that as a new estream + * object at R_NEWKEY. Caller must make sure that KEY has been seeked + * to the right position (usually by calling es_rewind). The + * resulting NEWKEY has already been rewound. If PREFIX is not NULL, + * its content is written to NEWKEY propr to the armor; this may be + * used for MIME headers. */ +gpg_error_t +wks_armor_key (estream_t *r_newkey, estream_t key, const char *prefix) +{ + gpg_error_t err; + estream_t newkey; + struct b64state b64state; + char buffer[4096]; + size_t nread; + + *r_newkey = NULL; + + newkey = es_fopenmem (0, "w+b"); + if (!newkey) + { + err = gpg_error_from_syserror (); + return err; + } + + if (prefix) + es_fputs (prefix, newkey); + + err = b64enc_start_es (&b64state, newkey, "PGP PUBLIC KEY BLOCK"); + if (err) + goto leave; + + do + { + nread = es_fread (buffer, 1, sizeof buffer, key); + if (!nread) + break; + err = b64enc_write (&b64state, buffer, nread); + if (err) + goto leave; + } + while (!es_feof (key) && !es_ferror (key)); + if (!es_feof (key) || es_ferror (key)) + { + err = gpg_error_from_syserror (); + goto leave; + } + + err = b64enc_finish (&b64state); + if (err) + goto leave; + + es_rewind (newkey); + *r_newkey = newkey; + newkey = NULL; + + leave: + es_fclose (newkey); + return err; +} + + +/* Run gpg to export the revocation certificates for ADDRSPEC. Add + * them to KEY which is expected to be non-armored keyblock. */ +gpg_error_t +wks_find_add_revocs (estream_t key, const char *addrspec) +{ + gpg_error_t err; + ccparray_t ccp; + const char **argv = NULL; + char *filterexp = NULL; + + filterexp = es_bsprintf ("select=mbox= %s", addrspec); + if (!filterexp) + { + err = gpg_error_from_syserror (); + log_error ("error allocating memory buffer: %s\n", gpg_strerror (err)); + goto leave; + } + + ccparray_init (&ccp, 0); + + ccparray_put (&ccp, "--no-options"); + if (opt.verbose < 2) + ccparray_put (&ccp, "--quiet"); + else + ccparray_put (&ccp, "--verbose"); + ccparray_put (&ccp, "--batch"); + ccparray_put (&ccp, "--status-fd=2"); + ccparray_put (&ccp, "--export-options=export-revocs"); + ccparray_put (&ccp, "--export-filter"); + ccparray_put (&ccp, filterexp); + ccparray_put (&ccp, "--export"); + ccparray_put (&ccp, addrspec); + + ccparray_put (&ccp, NULL); + argv = ccparray_get (&ccp, NULL); + if (!argv) + { + err = gpg_error_from_syserror (); + goto leave; + } + debug_gpg_invocation (__func__, argv); + err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL, + NULL, key, + key_status_cb, NULL); + if (err) + { + log_error ("exporting revocs failed: %s\n", gpg_strerror (err)); + goto leave; + } + + leave: + xfree (filterexp); + xfree (argv); + return err; +} + + /* Helper to write mail to the output(s). */ gpg_error_t wks_send_mime (mime_maker_t mime) @@ -1103,7 +1277,7 @@ wks_cmd_install_key (const char *fname, const char *userid) { /* FNAME looks like a fingerprint. Get the key from the * standard keyring. */ - err = wks_get_key (&fp, fname, addrspec, 0); + err = wks_get_key (&fp, fname, addrspec, 0, 1); if (err) { log_error ("error getting key '%s' (uid='%s'): %s\n", @@ -1140,6 +1314,12 @@ wks_cmd_install_key (const char *fname, const char *userid) continue; /* Should not happen anyway. */ if (ascii_strcasecmp (uid->mbox, addrspec)) continue; /* Not the requested addrspec. */ + if (uid->expired) + { + if (opt.verbose) + log_info ("ignoring expired user id '%s'\n", uid->uid); + continue; + } any = 1; if (uid->created > thistime) { @@ -1175,6 +1355,24 @@ wks_cmd_install_key (const char *fname, const char *userid) fp = fp2; } + if (opt.add_revocs) + { + if (es_fseek (fp, 0, SEEK_END)) + { + err = gpg_error_from_syserror (); + log_error ("error seeking stream: %s\n", gpg_strerror (err)); + goto leave; + } + err = wks_find_add_revocs (fp, addrspec); + if (err) + { + log_error ("error finding revocations for '%s': %s\n", + addrspec, gpg_strerror (err)); + goto leave; + } + es_rewind (fp); + } + err = wks_install_key_core (fp, addrspec); if (!opt.quiet) log_info ("key %s published for '%s'\n", fpr, addrspec);