gpg: Add experimental AKL method "wkd" and option --with-wkd-hash.
[gnupg.git] / g10 / gpg.c
index a9d248d..2f687fc 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,7 +1,7 @@
 /* gpg.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- *               2008, 2009, 2010, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2013, 2014 Werner Koch
+ * Copyright (C) 1998-2011 Free Software Foundation, Inc.
+ * Copyright (C) 1997-2016 Werner Koch
+ * Copyright (C) 2015-2016 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -59,6 +59,7 @@
 #include "gc-opt-flags.h"
 #include "asshelp.h"
 #include "call-dirmngr.h"
+#include "tofu.h"
 #include "../common/init.h"
 #include "../common/shareddefs.h"
 
@@ -107,6 +108,7 @@ enum cmd_and_opt_values
     aClearsign,
     aStore,
     aQuickKeygen,
+    aFullKeygen,
     aKeygen,
     aSignEncr,
     aSignEncrSym,
@@ -115,7 +117,9 @@ enum cmd_and_opt_values
     aLSignKey,
     aQuickSignKey,
     aQuickLSignKey,
+    aQuickAddUid,
     aListConfig,
+    aListGcryptConfig,
     aGPGConfList,
     aGPGConfTest,
     aListPackets,
@@ -137,6 +141,7 @@ enum cmd_and_opt_values
     aExport,
     aExportSecret,
     aExportSecretSub,
+    aExportSshKey,
     aCheckKeys,
     aGenRevoke,
     aDesigRevoke,
@@ -159,6 +164,7 @@ enum cmd_and_opt_values
     aChangePIN,
     aPasswd,
     aServer,
+    aTOFUPolicy,
 
     oTextmode,
     oNoTextmode,
@@ -176,8 +182,10 @@ enum cmd_and_opt_values
     oNoAskCertLevel,
     oFingerprint,
     oWithFingerprint,
+    oWithICAOSpelling,
     oWithKeygrip,
     oWithSecret,
+    oWithWKDHash,
     oAnswerYes,
     oAnswerNo,
     oKeyring,
@@ -193,7 +201,7 @@ enum cmd_and_opt_values
     oDebug,
     oDebugLevel,
     oDebugAll,
-    oDebugCCIDDriver,
+    oDebugIOLBF,
     oStatusFD,
     oStatusFile,
     oAttributeFD,
@@ -271,10 +279,6 @@ enum cmd_and_opt_values
     oShowPhotos,
     oNoShowPhotos,
     oPhotoViewer,
-    oForceV3Sigs,
-    oNoForceV3Sigs,
-    oForceV4Certs,
-    oNoForceV4Certs,
     oForceMDC,
     oNoForceMDC,
     oDisableMDC,
@@ -301,6 +305,7 @@ enum cmd_and_opt_values
     oEncryptTo,
     oHiddenEncryptTo,
     oNoEncryptTo,
+    oEncryptToDefaultKey,
     oLoggerFD,
     oLoggerFile,
     oUtf8Strings,
@@ -337,7 +342,6 @@ enum cmd_and_opt_values
     oFixedListMode,
     oLegacyListMode,
     oNoSigCache,
-    oNoSigCreateCheck,
     oAutoCheckTrustDB,
     oNoAutoCheckTrustDB,
     oPreservePermissions,
@@ -366,17 +370,31 @@ enum cmd_and_opt_values
     oKeyidFormat,
     oExitOnStatusWriteError,
     oLimitCardInsertTries,
+    oReaderPort,
+    octapiDriver,
+    opcscDriver,
+    oDisableCCID,
     oRequireCrossCert,
     oNoRequireCrossCert,
     oAutoKeyLocate,
     oNoAutoKeyLocate,
     oAllowMultisigVerification,
+    oEnableLargeRSA,
+    oDisableLargeRSA,
     oEnableDSA2,
     oDisableDSA2,
     oAllowMultipleMessages,
     oNoAllowMultipleMessages,
     oAllowWeakDigestAlgos,
     oFakedSystemTime,
+    oNoAutostart,
+    oPrintPKARecords,
+    oPrintDANERecords,
+    oTOFUDefaultPolicy,
+    oTOFUDBFormat,
+    oWeakDigest,
+    oUnwrap,
+    oOnlySignTextIDs,
 
     oNoop
   };
@@ -403,9 +421,14 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")),
   ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
   ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
-  ARGPARSE_c (aQuickKeygen,  "quick-gen-key" ,
+  ARGPARSE_c (aKeygen,     "gen-key",
+              N_("generate a new key pair")),
+  ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
               N_("quickly generate a new key pair")),
-  ARGPARSE_c (aKeygen,    "gen-key",  N_("generate a new key pair")),
+  ARGPARSE_c (aQuickAddUid,  "quick-adduid",
+              N_("quickly add a new user-id")),
+  ARGPARSE_c (aFullKeygen,  "full-gen-key" ,
+              N_("full featured key pair generation")),
   ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
   ARGPARSE_c (aDeleteKeys,"delete-keys",
               N_("remove keys from the public keyring")),
@@ -432,6 +455,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ),
   ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ),
   ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ),
+  ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ),
   ARGPARSE_c (aImport, "import", N_("import/merge keys")),
   ARGPARSE_c (aFastImport, "fast-import", "@"),
 #ifdef ENABLE_CARD_SUPPORT
@@ -440,6 +464,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aChangePIN,  "change-pin", N_("change a card's PIN")),
 #endif
   ARGPARSE_c (aListConfig, "list-config", "@"),
+  ARGPARSE_c (aListGcryptConfig, "list-gcrypt-config", "@"),
   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@" ),
   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@" ),
   ARGPARSE_c (aListPackets, "list-packets","@"),
@@ -461,6 +486,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aPrimegen, "gen-prime", "@" ),
   ARGPARSE_c (aGenRandom,"gen-random", "@" ),
   ARGPARSE_c (aServer,   "server",  N_("run in server mode")),
+  ARGPARSE_c (aTOFUPolicy, "tofu-policy",
+             N_("|VALUE|set the TOFU policy for a key")),
 
   ARGPARSE_group (301, N_("@\nOptions:\n ")),
 
@@ -479,6 +506,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oEncryptTo,      "encrypt-to", "@"),
   ARGPARSE_s_n (oNoEncryptTo, "no-encrypt-to", "@"),
   ARGPARSE_s_s (oHiddenEncryptTo, "hidden-encrypt-to", "@"),
+  ARGPARSE_s_n (oEncryptToDefaultKey, "encrypt-to-default-key", "@"),
   ARGPARSE_s_s (oLocalUser, "local-user",
                 N_("|USER-ID|use USER-ID to sign or decrypt")),
 
@@ -515,10 +543,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
   ARGPARSE_s_n (oNoTTY,   "no-tty",  "@"),
 
-  ARGPARSE_s_n (oForceV3Sigs,      "force-v3-sigs", "@"),
-  ARGPARSE_s_n (oNoForceV3Sigs, "no-force-v3-sigs", "@"),
-  ARGPARSE_s_n (oForceV4Certs,     "force-v4-certs", "@"),
-  ARGPARSE_s_n (oNoForceV4Certs, "no-force-v4-certs", "@"),
   ARGPARSE_s_n (oForceMDC, "force-mdc", "@"),
   ARGPARSE_s_n (oNoForceMDC, "no-force-mdc", "@"),
   ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"),
@@ -527,10 +551,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
   ARGPARSE_s_n (oInteractive, "interactive", N_("prompt before overwriting")),
 
-  ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
-  ARGPARSE_s_n (oNoUseAgent, "no-use-agent", "@"),
-  ARGPARSE_s_s (oGpgAgentInfo, "gpg-agent-info", "@"),
-
   ARGPARSE_s_n (oBatch, "batch", "@"),
   ARGPARSE_s_n (oAnswerYes, "yes", "@"),
   ARGPARSE_s_n (oAnswerNo, "no", "@"),
@@ -551,9 +571,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDisplayCharset, "charset", "@"),
   ARGPARSE_s_s (oOptions, "options", "@"),
 
-  ARGPARSE_p_u (oDebug, "debug", "@"),
+  ARGPARSE_s_s (oDebug, "debug", "@"),
   ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
+  ARGPARSE_s_n (oDebugIOLBF, "debug-iolbf", "@"),
   ARGPARSE_s_i (oStatusFD, "status-fd", "@"),
   ARGPARSE_s_s (oStatusFile, "status-file", "@"),
   ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"),
@@ -589,15 +610,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
   ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"),
   ARGPARSE_s_s (oCompressAlgo, "compression-algo", "@"), /* Alias */
-  ARGPARSE_s_n (oThrowKeyids, "throw-keyid", "@"),
   ARGPARSE_s_n (oThrowKeyids, "throw-keyids", "@"),
-  ARGPARSE_s_n (oNoThrowKeyids, "no-throw-keyid", "@"),
   ARGPARSE_s_n (oNoThrowKeyids, "no-throw-keyids", "@"),
   ARGPARSE_s_n (oShowPhotos,   "show-photos", "@"),
   ARGPARSE_s_n (oNoShowPhotos, "no-show-photos", "@"),
   ARGPARSE_s_s (oPhotoViewer,  "photo-viewer", "@"),
   ARGPARSE_s_s (oSetNotation,  "set-notation", "@"),
-  ARGPARSE_s_s (oSetNotation,  "notation-data", "@"), /* Alias */
   ARGPARSE_s_s (oSigNotation,  "sig-notation", "@"),
   ARGPARSE_s_s (oCertNotation, "cert-notation", "@"),
 
@@ -664,8 +682,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
   ARGPARSE_s_i (oDefCertLevel, "default-cert-check-level", "@"), /* old */
+#ifndef NO_TRUST_MODELS
   ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"),
+#endif
   ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
+  ARGPARSE_s_s (oTOFUDefaultPolicy, "tofu-default-policy", "@"),
+  ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"),
   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
   ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"),
   ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"),
@@ -697,8 +719,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oUtf8Strings,      "utf8-strings", "@"),
   ARGPARSE_s_n (oNoUtf8Strings, "no-utf8-strings", "@"),
   ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
+  ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
+  ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -707,11 +731,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoAllowFreeformUID, "no-allow-freeform-uid", "@"),
   ARGPARSE_s_n (oNoLiteral, "no-literal", "@"),
   ARGPARSE_p_u (oSetFilesize, "set-filesize", "@"),
-  ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
   ARGPARSE_s_n (oFastListMode, "fast-list-mode", "@"),
   ARGPARSE_s_n (oFixedListMode, "fixed-list-mode", "@"),
   ARGPARSE_s_n (oLegacyListMode, "legacy-list-mode", "@"),
   ARGPARSE_s_n (oListOnly, "list-only", "@"),
+  ARGPARSE_s_n (oPrintPKARecords, "print-pka-records", "@"),
+  ARGPARSE_s_n (oPrintDANERecords, "print-dane-records", "@"),
   ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
   ARGPARSE_s_n (oIgnoreValidFrom,    "ignore-valid-from", "@"),
   ARGPARSE_s_n (oIgnoreCrcError, "ignore-crc-error", "@"),
@@ -722,7 +747,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oAutoKeyRetrieve, "auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoAutoKeyRetrieve, "no-auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoSigCache,         "no-sig-cache", "@"),
-  ARGPARSE_s_n (oNoSigCreateCheck,   "no-sig-create-check", "@"),
   ARGPARSE_s_n (oMergeOnly,      "merge-only", "@" ),
   ARGPARSE_s_n (oAllowSecretKeyImport, "allow-secret-key-import", "@"),
   ARGPARSE_s_n (oTryAllSecrets,  "try-all-secrets", "@"),
@@ -736,6 +760,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oPersonalCompressPreferences,
                                          "personal-compress-preferences", "@"),
   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
+  ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
+  ARGPARSE_s_n (oUnwrap, "unwrap", "@"),
+  ARGPARSE_s_n (oOnlySignTextIDs, "only-sign-text-ids", "@"),
 
   /* Aliases.  I constantly mistype these, and assume other people do
      as well. */
@@ -766,6 +793,8 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_n (oAllowMultisigVerification,
                 "allow-multisig-verification", "@"),
+  ARGPARSE_s_n (oEnableLargeRSA, "enable-large-rsa", "@"),
+  ARGPARSE_s_n (oDisableLargeRSA, "disable-large-rsa", "@"),
   ARGPARSE_s_n (oEnableDSA2, "enable-dsa2", "@"),
   ARGPARSE_s_n (oDisableDSA2, "disable-dsa2", "@"),
   ARGPARSE_s_n (oAllowMultipleMessages,      "allow-multiple-messages", "@"),
@@ -787,17 +816,54 @@ static ARGPARSE_OPTS opts[] = {
   /* New options.  Fixme: Should go more to the top.  */
   ARGPARSE_s_s (oAutoKeyLocate, "auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutoKeyLocate, "no-auto-key-locate", "@"),
+  ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
+
+  /* Dummy options with warnings.  */
+  ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
+  ARGPARSE_s_n (oNoUseAgent, "no-use-agent", "@"),
+  ARGPARSE_s_s (oGpgAgentInfo, "gpg-agent-info", "@"),
+  ARGPARSE_s_s (oReaderPort, "reader-port", "@"),
+  ARGPARSE_s_s (octapiDriver, "ctapi-driver", "@"),
+  ARGPARSE_s_s (opcscDriver, "pcsc-driver", "@"),
+  ARGPARSE_s_n (oDisableCCID, "disable-ccid", "@"),
+  ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
 
   /* Dummy options.  */
   ARGPARSE_s_n (oNoop, "sk-comments", "@"),
   ARGPARSE_s_n (oNoop, "no-sk-comments", "@"),
   ARGPARSE_s_n (oNoop, "compress-keys", "@"),
   ARGPARSE_s_n (oNoop, "compress-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "force-v3-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-v3-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "force-v4-certs", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-v4-certs", "@"),
 
   ARGPARSE_end ()
 };
 
 
+/* The list of supported debug flags.  */
+static struct debug_flags_s debug_flags [] =
+  {
+    { DBG_PACKET_VALUE , "packet"  },
+    { DBG_MPI_VALUE    , "mpi"     },
+    { DBG_CRYPTO_VALUE , "crypto"  },
+    { DBG_FILTER_VALUE , "filter"  },
+    { DBG_IOBUF_VALUE  , "iobuf"   },
+    { DBG_MEMORY_VALUE , "memory"  },
+    { DBG_CACHE_VALUE  , "cache"   },
+    { DBG_MEMSTAT_VALUE, "memstat" },
+    { DBG_TRUST_VALUE  , "trust"   },
+    { DBG_HASHING_VALUE, "hashing" },
+    { DBG_CARD_IO_VALUE, "cardio"  },
+    { DBG_IPC_VALUE    , "ipc"     },
+    { DBG_CLOCK_VALUE  , "clock"   },
+    { DBG_LOOKUP_VALUE , "lookup"  },
+    { DBG_EXTPROG_VALUE, "extprog" },
+    { 0, NULL }
+  };
+
+
 #ifdef ENABLE_SELINUX_HACKS
 #define ALWAYS_ADD_KEYRINGS 1
 #else
@@ -983,7 +1049,7 @@ build_list (const char *text, char letter,
   if (maybe_setuid)
     gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
 
-  indent = utf8_charcount (text);
+  indent = utf8_charcount (text, -1);
   len = 0;
   init_membuf (&mb, 512);
 
@@ -1027,7 +1093,7 @@ build_list (const char *text, char letter,
 static void
 wrong_args( const char *text)
 {
-  fprintf (stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
+  es_fprintf (es_stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
   g10_exit(2);
 }
 
@@ -1055,6 +1121,7 @@ set_opt_session_env (const char *name, const char *value)
                gpg_strerror (err));
 }
 
+
 /* Setup the debugging.  With a LEVEL of NULL only the active debug
    flags are propagated to the subsystems.  With LEVEL set, a specific
    set of debug flags is set; thus overriding all flags already
@@ -1075,7 +1142,7 @@ set_debug (const char *level)
     opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE;
   else if (!strcmp (level, "expert")  || (numok && numlvl <= 8))
     opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE
-                 |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
+                 |DBG_CACHE_VALUE|DBG_LOOKUP|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
   else if (!strcmp (level, "guru") || numok)
     {
       opt.debug = ~0;
@@ -1098,28 +1165,14 @@ set_debug (const char *level)
     memory_stat_debug_mode = 1;
   if (opt.debug & DBG_MPI_VALUE)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
-  if (opt.debug & DBG_CIPHER_VALUE )
+  if (opt.debug & DBG_CRYPTO_VALUE )
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
   if (opt.debug & DBG_IOBUF_VALUE )
     iobuf_debug_mode = 1;
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
   if (opt.debug)
-    log_info ("enabled debug flags:%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-              (opt.debug & DBG_PACKET_VALUE )? " packet":"",
-              (opt.debug & DBG_MPI_VALUE    )? " mpi":"",
-              (opt.debug & DBG_CIPHER_VALUE )? " cipher":"",
-              (opt.debug & DBG_FILTER_VALUE )? " filter":"",
-              (opt.debug & DBG_IOBUF_VALUE  )? " iobuf":"",
-              (opt.debug & DBG_MEMORY_VALUE )? " memory":"",
-              (opt.debug & DBG_CACHE_VALUE  )? " cache":"",
-              (opt.debug & DBG_MEMSTAT_VALUE)? " memstat":"",
-              (opt.debug & DBG_TRUST_VALUE  )? " trust":"",
-              (opt.debug & DBG_HASHING_VALUE)? " hashing":"",
-              (opt.debug & DBG_EXTPROG_VALUE)? " extprog":"",
-              (opt.debug & DBG_CARD_IO_VALUE)? " cardio":"",
-              (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"",
-              (opt.debug & DBG_CLOCK_VALUE  )? " clock":"");
+    parse_debug_flag (NULL, &opt.debug, debug_flags);
 }
 
 
@@ -1563,8 +1616,11 @@ print_algo_names(int (*checker)(int),const char *(*mapper)(int))
 static void
 list_config(char *items)
 {
-  int show_all=(items==NULL);
-  char *name=NULL;
+  int show_all = !items;
+  char *name = NULL;
+  const char *s;
+  struct groupitem *giter;
+  int first, iter;
 
   if(!opt.with_colons)
     return;
@@ -1575,20 +1631,19 @@ list_config(char *items)
 
       if(show_all || ascii_strcasecmp(name,"group")==0)
        {
-         struct groupitem *iter;
-
-         for(iter=opt.grouplist;iter;iter=iter->next)
+         for (giter = opt.grouplist; giter; giter = giter->next)
            {
              strlist_t sl;
 
              es_fprintf (es_stdout, "cfg:group:");
-             es_write_sanitized (es_stdout, iter->name, strlen(iter->name),
+             es_write_sanitized (es_stdout, giter->name, strlen(giter->name),
                                   ":", NULL);
              es_putc (':', es_stdout);
 
-             for(sl=iter->values;sl;sl=sl->next)
+             for(sl=giter->values; sl; sl=sl->next)
                {
-                 print_sanitized_string2 (stdout, sl->d, ':',';');
+                 es_write_sanitized (es_stdout, sl->d, strlen (sl->d),
+                                      ":;", NULL);
                  if(sl->next)
                     es_printf(";");
                }
@@ -1670,20 +1725,31 @@ list_config(char *items)
          any=1;
        }
 
-      if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0)
+      if (show_all || !ascii_strcasecmp(name,"ccid-reader-id"))
        {
-#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB) \
-    && GNUPG_MAJOR_VERSION == 1
+          /* We ignore this for GnuPG 1.4 backward compatibility.  */
+         any=1;
+       }
 
-          char *p, *p2, *list = ccid_get_reader_list ();
+      if (show_all || !ascii_strcasecmp (name,"curve"))
+       {
+         es_printf ("cfg:curve:");
+          for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first=0)
+            es_printf ("%s%s", first?"":";", s);
+         es_printf ("\n");
+         any=1;
+       }
 
-          for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
+      /* Curve OIDs are rarely useful and thus only printed if requested.  */
+      if (name && !ascii_strcasecmp (name,"curveoid"))
+       {
+         es_printf ("cfg:curveoid:");
+          for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first = 0)
             {
-              *p2 = 0;
-              es_printf ("cfg:ccid-reader-id:%s\n", p);
+              s = openpgp_curve_to_oid (s, NULL);
+              es_printf ("%s%s", first?"":";", s? s:"[?]");
             }
-          free (list);
-#endif
+         es_printf ("\n");
          any=1;
        }
 
@@ -1832,7 +1898,7 @@ parse_list_options(char *str)
      compile everywhere, so fill in the show-sig-subpackets argument
      here.  Note that if the parse_options array changes, we'll have
      to change the subscript here. */
-  lopts[12].value=&subpackets;
+  lopts[13].value=&subpackets;
 
   if(parse_options(str,&opt.list_options,lopts,1))
     {
@@ -1895,6 +1961,12 @@ parse_trust_model(const char *model)
     opt.trust_model=TM_ALWAYS;
   else if(ascii_strcasecmp(model,"direct")==0)
     opt.trust_model=TM_DIRECT;
+#ifdef USE_TOFU
+  else if(ascii_strcasecmp(model,"tofu")==0)
+    opt.trust_model=TM_TOFU;
+  else if(ascii_strcasecmp(model,"tofu+pgp")==0)
+    opt.trust_model=TM_TOFU_PGP;
+#endif /*USE_TOFU*/
   else if(ascii_strcasecmp(model,"auto")==0)
     opt.trust_model=TM_AUTO;
   else
@@ -1903,7 +1975,64 @@ parse_trust_model(const char *model)
 #endif /*NO_TRUST_MODELS*/
 
 
-/* This fucntion called to initialized a new control object.  It is
+static int
+parse_tofu_policy (const char *policystr)
+{
+#ifdef USE_TOFU
+  struct { const char *keyword; int policy; } list[] = {
+    { "auto",    TOFU_POLICY_AUTO },
+    { "good",    TOFU_POLICY_GOOD },
+    { "unknown", TOFU_POLICY_UNKNOWN },
+    { "bad",     TOFU_POLICY_BAD },
+    { "ask",     TOFU_POLICY_ASK }
+  };
+  int i;
+
+  if (!ascii_strcasecmp (policystr, "help"))
+    {
+      log_info (_("available TOFU policies:\n"));
+      for (i=0; i < DIM (list); i++)
+        log_info ("  %s\n", list[i].keyword);
+      g10_exit (1);
+    }
+
+  for (i=0; i < DIM (list); i++)
+    if (!ascii_strcasecmp (policystr, list[i].keyword))
+      return list[i].policy;
+#endif /*USE_TOFU*/
+
+  log_error (_("unknown TOFU policy '%s'\n"), policystr);
+  if (!opt.quiet)
+    log_info (_("(use \"help\" to list choices)\n"));
+  g10_exit (1);
+}
+
+static int
+parse_tofu_db_format (const char *db_format)
+{
+#ifdef USE_TOFU
+  if (ascii_strcasecmp (db_format, "auto") == 0)
+    return TOFU_DB_AUTO;
+  else if (ascii_strcasecmp (db_format, "split") == 0)
+    return TOFU_DB_SPLIT;
+  else if (ascii_strcasecmp (db_format, "flat") == 0)
+    return TOFU_DB_FLAT;
+  else if (ascii_strcasecmp (db_format, "help") == 0)
+    {
+      log_info ("available TOFU DB fomats: auto, split, flat\n");
+      g10_exit (1);
+    }
+  else
+#endif /*USE_TOFU*/
+    {
+      log_error (_("unknown TOFU DB format '%s'\n"), db_format);
+      if (!opt.quiet)
+        log_info (_("(use \"help\" to list choices)\n"));
+      g10_exit (1);
+    }
+}
+
+/* This function called to initialized a new control object.  It is
    assumed that this object has been zeroed out before calling this
    function. */
 static void
@@ -1959,7 +2088,7 @@ get_default_configname (void)
       /* Print a warning when both config files are present.  */
       char *p = make_filename (opt.homedir, "options", NULL);
       if (! access (p, R_OK))
-       log_info (_("NOTE: old default options file '%s' ignored\n"), p);
+       log_info (_("Note: old default options file '%s' ignored\n"), p);
       xfree (p);
     }
   else
@@ -1978,7 +2107,6 @@ get_default_configname (void)
   return configname;
 }
 
-
 int
 main (int argc, char **argv)
 {
@@ -1990,7 +2118,9 @@ main (int argc, char **argv)
     const char *fname;
     char *username;
     int may_coredump;
-    strlist_t sl, remusr= NULL, locusr=NULL;
+    strlist_t sl;
+    strlist_t remusr = NULL;
+    strlist_t locusr = NULL;
     strlist_t nrings = NULL;
     armor_filter_context_t *afx = NULL;
     int detached_sig = 0;
@@ -2037,6 +2167,7 @@ main (int argc, char **argv)
     /* Please note that we may running SUID(ROOT), so be very CAREFUL
        when adding any stuff between here and the call to
        secmem_init() somewhere after the option parsing. */
+    early_system_init ();
     gnupg_reopen_std (GPG_NAME);
     trap_unaligned ();
     gnupg_rl_initialize ();
@@ -2068,6 +2199,7 @@ main (int argc, char **argv)
 
     dotlock_create (NULL, 0); /* Register lock file cleanup. */
 
+    opt.autostart = 1;
     opt.session_env = session_env_new ();
     if (!opt.session_env)
       log_fatal ("error allocating session environment block: %s\n",
@@ -2087,25 +2219,26 @@ main (int argc, char **argv)
     opt.completes_needed = 1;
     opt.marginals_needed = 3;
     opt.max_cert_depth = 5;
-    opt.pgp2_workarounds = 1;
     opt.escape_from = 1;
     opt.flags.require_cross_cert = 1;
     opt.import_options = 0;
     opt.export_options = EXPORT_ATTRIBUTES;
     opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
     opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
-    opt.keyserver_options.options = (KEYSERVER_HONOR_KEYSERVER_URL
-                                     | KEYSERVER_HONOR_PKA_RECORD );
+    opt.keyserver_options.options = KEYSERVER_HONOR_PKA_RECORD;
     opt.verify_options = (LIST_SHOW_UID_VALIDITY
                           | VERIFY_SHOW_POLICY_URLS
                           | VERIFY_SHOW_STD_NOTATIONS
                           | VERIFY_SHOW_KEYSERVER_URLS);
-    opt.list_options   = LIST_SHOW_UID_VALIDITY;
+    opt.list_options   = (LIST_SHOW_UID_VALIDITY
+                          | LIST_SHOW_USAGE);
 #ifdef NO_TRUST_MODELS
     opt.trust_model = TM_ALWAYS;
 #else
     opt.trust_model = TM_AUTO;
 #endif
+    opt.tofu_default_policy = TOFU_POLICY_AUTO;
+    opt.tofu_db_format = TOFU_DB_AUTO;
     opt.mangle_dos_filenames = 0;
     opt.min_cert_level = 2;
     set_screen_dimensions ();
@@ -2115,6 +2248,8 @@ main (int argc, char **argv)
     set_homedir (default_homedir ());
     opt.passphrase_repeat = 1;
     opt.emit_version = 1; /* Limit to the major number.  */
+    opt.weak_digests = NULL;
+    additional_weak_digest("MD5");
 
     /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
@@ -2125,6 +2260,8 @@ main (int argc, char **argv)
     while( arg_parse( &pargs, opts) ) {
        if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
            parse_debug++;
+       else if (pargs.r_opt == oDebugIOLBF)
+            es_setvbuf (es_stdout, NULL, _IOLBF, 0);
        else if( pargs.r_opt == oOptions ) {
            /* yes there is one, so we do not try the default one, but
             * read the option file when it is encountered at the commandline
@@ -2168,7 +2305,7 @@ main (int argc, char **argv)
 #endif
 
     /* Initialize the secure memory. */
-    if (!gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0))
+    if (!gcry_control (GCRYCTL_INIT_SECMEM, SECMEM_BUFFER_SIZE, 0))
       got_secmem = 1;
 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
     /* There should be no way to get to this spot while still carrying
@@ -2226,7 +2363,7 @@ main (int argc, char **argv)
        if( !configfp ) {
            if( default_config ) {
                if( parse_debug )
-                   log_info(_("NOTE: no default option file '%s'\n"),
+                   log_info(_("Note: no default option file '%s'\n"),
                                                            configname );
            }
            else {
@@ -2248,6 +2385,7 @@ main (int argc, char **argv)
          {
          case aCheckKeys:
          case aListConfig:
+         case aListGcryptConfig:
           case aGPGConfList:
           case aGPGConfTest:
          case aListPackets:
@@ -2269,6 +2407,7 @@ main (int argc, char **argv)
          case aListSigs:
          case aExportSecret:
          case aExportSecretSub:
+         case aExportSshKey:
          case aSym:
          case aClearsign:
          case aGenRevoke:
@@ -2291,6 +2430,7 @@ main (int argc, char **argv)
          case aLSignKey:
          case aStore:
          case aQuickKeygen:
+         case aQuickAddUid:
          case aExportOwnerTrust:
          case aImportOwnerTrust:
           case aRebuildKeydbCaches:
@@ -2298,6 +2438,7 @@ main (int argc, char **argv)
             break;
 
          case aKeygen:
+         case aFullKeygen:
          case aEditKey:
          case aDeleteSecretKeys:
          case aDeleteSecretAndPublicKeys:
@@ -2323,6 +2464,10 @@ main (int argc, char **argv)
             opt.batch = 1;
             break;
 
+          case aTOFUPolicy:
+            set_cmd (&cmd, pargs.r_opt);
+            break;
+
          case oArmor: opt.armor = 1; opt.no_armor=0; break;
          case oOutput: opt.outfile = pargs.r.ret_str; break;
          case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
@@ -2344,11 +2489,27 @@ main (int argc, char **argv)
 
           case oUseAgent: /* Dummy. */
             break;
+
           case oNoUseAgent:
-           obsolete_option (configname, configlineno, "--no-use-agent");
+           obsolete_option (configname, configlineno, "no-use-agent");
             break;
          case oGpgAgentInfo:
-           obsolete_option (configname, configlineno, "--gpg-agent-info");
+           obsolete_option (configname, configlineno, "gpg-agent-info");
+            break;
+          case oReaderPort:
+           obsolete_scdaemon_option (configname, configlineno, "reader-port");
+            break;
+          case octapiDriver:
+           obsolete_scdaemon_option (configname, configlineno, "ctapi-driver");
+            break;
+          case opcscDriver:
+           obsolete_scdaemon_option (configname, configlineno, "pcsc-driver");
+            break;
+          case oDisableCCID:
+           obsolete_scdaemon_option (configname, configlineno, "disable-ccid");
+            break;
+          case oHonorHttpProxy:
+           obsolete_option (configname, configlineno, "honor-http-proxy");
             break;
 
          case oAnswerYes: opt.answer_yes = 1; break;
@@ -2364,10 +2525,19 @@ main (int argc, char **argv)
            opt.list_options|=LIST_SHOW_KEYRING;
            break;
 
-         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
+         case oDebug:
+            if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
+              {
+                pargs.r_opt = ARGPARSE_INVALID_ARG;
+                pargs.err = ARGPARSE_PRINT_ERROR;
+              }
+            break;
+
          case oDebugAll: opt.debug = ~0; break;
           case oDebugLevel: debug_level = pargs.r.ret_str; break;
 
+          case oDebugIOLBF: break; /* Already set in pre-parse step.  */
+
          case oStatusFD:
             set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
             break;
@@ -2391,6 +2561,9 @@ main (int argc, char **argv)
             opt.with_fingerprint = 1;
             opt.fingerprint++;
             break;
+         case oWithICAOSpelling:
+            opt.with_icao_spelling = 1;
+            break;
          case oFingerprint:
             opt.fingerprint++;
             fpr_maybe_cmd = 1;
@@ -2404,6 +2577,10 @@ main (int argc, char **argv)
             opt.with_secret = 1;
             break;
 
+         case oWithWKDHash:
+            opt.with_wkd_hash = 1;
+            break;
+
          case oSecretKeyring:
             /* Ignore this old option.  */
             break;
@@ -2437,10 +2614,18 @@ main (int argc, char **argv)
          case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
 
 #endif /*!NO_TRUST_MODELS*/
-         case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
+         case oDefaultKey:
+            sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str);
+            sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
+            break;
          case oDefRecipient:
             if( *pargs.r.ret_str )
-              opt.def_recipient = make_username(pargs.r.ret_str);
+             {
+               xfree (opt.def_recipient);
+               opt.def_recipient = make_username(pargs.r.ret_str);
+             }
             break;
          case oDefRecipientSelf:
             xfree(opt.def_recipient); opt.def_recipient = NULL;
@@ -2476,9 +2661,15 @@ main (int argc, char **argv)
            parse_trust_model(pargs.r.ret_str);
            break;
 #endif /*!NO_TRUST_MODELS*/
+         case oTOFUDefaultPolicy:
+           opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str);
+           break;
+         case oTOFUDBFormat:
+           opt.tofu_db_format = parse_tofu_db_format (pargs.r.ret_str);
+           break;
 
          case oForceOwnertrust:
-           log_info(_("NOTE: %s is not for normal use!\n"),
+           log_info(_("Note: %s is not for normal use!\n"),
                     "--force-ownertrust");
            opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
            if(opt.force_ownertrust==-1)
@@ -2502,9 +2693,7 @@ main (int argc, char **argv)
            opt.rfc2440_text = 0;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
-           opt.pgp2_workarounds = 0;
            opt.escape_from = 1;
-           opt.force_v3_sigs = 0;
            opt.not_dash_escaped = 0;
            opt.def_cipher_algo = 0;
            opt.def_digest_algo = 0;
@@ -2520,9 +2709,7 @@ main (int argc, char **argv)
            opt.rfc2440_text = 1;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
-           opt.pgp2_workarounds = 0;
            opt.escape_from = 0;
-           opt.force_v3_sigs = 0;
            opt.not_dash_escaped = 0;
            opt.def_cipher_algo = 0;
            opt.def_digest_algo = 0;
@@ -2587,8 +2774,8 @@ main (int argc, char **argv)
            free_strlist(opt.comments);
            opt.comments=NULL;
            break;
-         case oThrowKeyids: opt.throw_keyid = 1; break;
-         case oNoThrowKeyids: opt.throw_keyid = 0; break;
+         case oThrowKeyids: opt.throw_keyids = 1; break;
+         case oNoThrowKeyids: opt.throw_keyids = 0; break;
          case oShowPhotos:
            deprecated_warning(configname,configlineno,"--show-photos",
                               "--list-options ","show-photos");
@@ -2606,10 +2793,7 @@ main (int argc, char **argv)
            opt.verify_options&=~VERIFY_SHOW_PHOTOS;
            break;
          case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
-         case oForceV3Sigs: opt.force_v3_sigs = 1; break;
-         case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
-          case oForceV4Certs: opt.force_v4_certs = 1; break;
-          case oNoForceV4Certs: opt.force_v4_certs = 0; break;
+
          case oForceMDC: opt.force_mdc = 1; break;
          case oNoForceMDC: opt.force_mdc = 0; break;
          case oDisableMDC: opt.disable_mdc = 1; break;
@@ -2626,19 +2810,32 @@ main (int argc, char **argv)
          case oNoEncryptTo: opt.no_encrypt_to = 1; break;
          case oEncryptTo: /* store the recipient in the second list */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = 1;
+           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
            break;
          case oHiddenEncryptTo: /* store the recipient in the second list */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = 1|2;
+           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT)
+                         | PK_LIST_ENCRYPT_TO|PK_LIST_HIDDEN);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
            break;
+          case oEncryptToDefaultKey:
+            opt.encrypt_to_default_key = configfp ? 2 : 1;
+            break;
          case oRecipient: /* store the recipient */
-           add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
+           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
+           sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
             any_explicit_recipient = 1;
            break;
          case oHiddenRecipient: /* store the recipient with a flag */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = 2;
+           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_HIDDEN);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
             any_explicit_recipient = 1;
            break;
 
@@ -2681,7 +2878,10 @@ main (int argc, char **argv)
          case oAskCertLevel: opt.ask_cert_level = 1; break;
          case oNoAskCertLevel: opt.ask_cert_level = 0; break;
          case oLocalUser: /* store the local users */
-           add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
+           sl = add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
+            sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
            break;
          case oCompress:
            /* this is the -z command line option */
@@ -2779,13 +2979,18 @@ main (int argc, char **argv)
          case oKeyServer:
            {
              keyserver_spec_t keyserver;
-             keyserver = parse_keyserver_uri (pargs.r.ret_str,0,
-                                               configname,configlineno);
+             keyserver = parse_keyserver_uri (pargs.r.ret_str, 0);
              if (!keyserver)
                log_error (_("could not parse keyserver URL\n"));
              else
                {
-                 keyserver->next = opt.keyserver;
+                 /* We only support a single keyserver.  Later ones
+                    override earlier ones.  (Since we parse the
+                    config file first and then the command line
+                    arguments, the command line takes
+                    precedence.)  */
+                 if (opt.keyserver)
+                   free_keyserver_spec (opt.keyserver);
                  opt.keyserver = keyserver;
                }
            }
@@ -2915,22 +3120,17 @@ main (int argc, char **argv)
             }
             break;
           case oNoSigCache: opt.no_sig_cache = 1; break;
-          case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
          case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
          case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
          case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
          case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
          case oNoLiteral: opt.no_literal = 1; break;
          case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
-         case oHonorHttpProxy:
-               add_to_strlist(&opt.keyserver_options.other,"http-proxy");
-               deprecated_warning(configname,configlineno,
-                                  "--honor-http-proxy",
-                                  "--keyserver-options ","http-proxy");
-               break;
          case oFastListMode: opt.fast_list_mode = 1; break;
          case oFixedListMode: /* Dummy */ break;
           case oLegacyListMode: opt.legacy_list_mode = 1; break;
+         case oPrintPKARecords: opt.print_pka_records = 1; break;
+         case oPrintDANERecords: opt.print_dane_records = 1; break;
          case oListOnly: opt.list_only=1; break;
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
@@ -2975,8 +3175,7 @@ main (int argc, char **argv)
          case oDefaultKeyserverURL:
            {
              keyserver_spec_t keyserver;
-             keyserver = parse_keyserver_uri (pargs.r.ret_str,1,
-                                               configname,configlineno);
+             keyserver = parse_keyserver_uri (pargs.r.ret_str,1 );
              if (!keyserver)
                log_error (_("could not parse keyserver URL\n"));
              else
@@ -2996,6 +3195,15 @@ main (int argc, char **argv)
            break;
           case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
           case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
+          case oWeakDigest:
+           additional_weak_digest(pargs.r.ret_str);
+           break;
+          case oUnwrap:
+            opt.unwrap_encryption = 1;
+            break;
+          case oOnlySignTextIDs:
+            opt.only_sign_text_ids = 1;
+            break;
 
           case oDisplay:
             set_opt_session_env ("DISPLAY", pargs.r.ret_str);
@@ -3072,6 +3280,22 @@ main (int argc, char **argv)
            release_akl();
            break;
 
+         case oEnableLargeRSA:
+#if SECMEM_BUFFER_SIZE >= 65536
+            opt.flags.large_rsa=1;
+#else
+            if (configname)
+              log_info("%s:%d: WARNING: gpg not built with large secure "
+                         "memory buffer.  Ignoring enable-large-rsa\n",
+                        configname,configlineno);
+            else
+              log_info("WARNING: gpg not built with large secure "
+                         "memory buffer.  Ignoring --enable-large-rsa\n");
+#endif /* SECMEM_BUFFER_SIZE >= 65536 */
+            break;
+         case oDisableLargeRSA: opt.flags.large_rsa=0;
+            break;
+
          case oEnableDSA2: opt.flags.dsa2=1; break;
          case oDisableDSA2: opt.flags.dsa2=0; break;
 
@@ -3097,6 +3321,8 @@ main (int argc, char **argv)
             }
             break;
 
+          case oNoAutostart: opt.autostart = 0; break;
+
          case oNoop: break;
 
          default:
@@ -3164,15 +3390,6 @@ main (int argc, char **argv)
         log_set_prefix (NULL, 1|2|4);
       }
 
-    /* Older Libgcrypts fail with an assertion during DSA key
-       generation.  Better disable DSA2 entirely. */
-    if (opt.flags.dsa2 && !gcry_check_version ("1.4.0") )
-      {
-        log_info ("WARNING: "
-                  "DSA2 is only available with Libgcrypt 1.4 and later\n");
-        opt.flags.dsa2 = 0;
-      }
-
     if (opt.verbose > 2)
         log_info ("using character set '%s'\n", get_native_charset ());
 
@@ -3188,7 +3405,7 @@ main (int argc, char **argv)
     }
 
     if (opt.no_literal) {
-       log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
+       log_info(_("Note: %s is not for normal use!\n"), "--no-literal");
        if (opt.textmode)
            log_error(_("%s not allowed with %s!\n"),
                       "--textmode", "--no-literal" );
@@ -3200,7 +3417,7 @@ main (int argc, char **argv)
 
 
     if (opt.set_filesize)
-       log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
+       log_info(_("Note: %s is not for normal use!\n"), "--set-filesize");
     if( opt.batch )
        tty_batchmode( 1 );
 
@@ -3221,7 +3438,7 @@ main (int argc, char **argv)
 
         for (i=0; i < argc; i++)
           if (argv[i][0] == '-' && argv[i][1] == '-')
-            log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
+            log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
       }
 
 
@@ -3241,15 +3458,17 @@ main (int argc, char **argv)
     /* Do these after the switch(), so they can override settings. */
     if(PGP6)
       {
+        /* That does not anymore work because we have no more support
+           for v3 signatures.  */
        opt.disable_mdc=1;
        opt.escape_from=1;
-       opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
       }
     else if(PGP7)
       {
+        /* That does not anymore work because we have no more support
+           for v3 signatures.  */
        opt.escape_from=1;
-       opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
       }
     else if(PGP8)
@@ -3306,7 +3525,7 @@ main (int argc, char **argv)
       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
     switch( opt.s2k_mode ) {
       case 0:
-       log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
+       log_info(_("Note: simple S2K mode (0) is strongly discouraged\n"));
        break;
       case 1: case 3: break;
       default:
@@ -3341,6 +3560,9 @@ main (int argc, char **argv)
          case aSign:
            cmdname="--sign";
            break;
+         case aSignEncr:
+           cmdname="--sign --encrypt";
+           break;
          case aClearsign:
            cmdname="--clearsign";
            break;
@@ -3466,6 +3688,13 @@ main (int argc, char **argv)
       }
     FREE_STRLIST(nrings);
 
+    if (opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
+      /* In loopback mode, never ask for the password multiple
+        times.  */
+      {
+       opt.passphrase_repeat = 0;
+      }
+
     if (cmd == aGPGConfTest)
       g10_exit(0);
 
@@ -3505,7 +3734,8 @@ main (int argc, char **argv)
         break;
       }
     if (rc)
-      log_error (_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
+      log_error (_("failed to initialize the TrustDB: %s\n"),
+                 gpg_strerror (rc));
 #endif /*!NO_TRUST_MODELS*/
 
     switch (cmd)
@@ -3542,6 +3772,8 @@ main (int argc, char **argv)
       case aDeleteSecretKeys:
       case aDeleteSecretAndPublicKeys:
       case aQuickKeygen:
+      case aQuickAddUid:
+      case aFullKeygen:
       case aKeygen:
       case aImport:
       case aExportSecret:
@@ -3571,15 +3803,21 @@ main (int argc, char **argv)
        if( argc > 1 )
            wrong_args(_("--store [filename]"));
        if( (rc = encrypt_store(fname)) )
+          {
+            write_status_failure ("store", rc);
            log_error ("storing '%s' failed: %s\n",
-                       print_fname_stdin(fname),g10_errstr(rc) );
+                       print_fname_stdin(fname),gpg_strerror (rc) );
+          }
        break;
       case aSym: /* encrypt the given file only with the symmetric cipher */
        if( argc > 1 )
            wrong_args(_("--symmetric [filename]"));
        if( (rc = encrypt_symmetric(fname)) )
+          {
+            write_status_failure ("symencrypt", rc);
             log_error (_("symmetric encryption of '%s' failed: %s\n"),
-                        print_fname_stdin(fname),g10_errstr(rc) );
+                        print_fname_stdin(fname),gpg_strerror (rc) );
+          }
        break;
 
       case aEncr: /* encrypt the given file */
@@ -3590,8 +3828,11 @@ main (int argc, char **argv)
            if( argc > 1 )
              wrong_args(_("--encrypt [filename]"));
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) )
-             log_error("%s: encryption failed: %s\n",
-                       print_fname_stdin(fname), g10_errstr(rc) );
+              {
+                write_status_failure ("encrypt", rc);
+                log_error("%s: encryption failed: %s\n",
+                          print_fname_stdin(fname), gpg_strerror (rc) );
+              }
          }
        break;
 
@@ -3611,8 +3852,11 @@ main (int argc, char **argv)
        else
          {
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
-             log_error("%s: encryption failed: %s\n",
-                       print_fname_stdin(fname), g10_errstr(rc) );
+              {
+                write_status_failure ("encrypt", rc);
+                log_error ("%s: encryption failed: %s\n",
+                           print_fname_stdin(fname), gpg_strerror (rc) );
+              }
          }
        break;
 
@@ -3630,8 +3874,11 @@ main (int argc, char **argv)
                strcpy(sl->d, fname);
            }
        }
-       if( (rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)) )
-           log_error("signing failed: %s\n", g10_errstr(rc) );
+       if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)))
+          {
+            write_status_failure ("sign", rc);
+           log_error ("signing failed: %s\n", gpg_strerror (rc) );
+          }
        free_strlist(sl);
        break;
 
@@ -3645,8 +3892,11 @@ main (int argc, char **argv)
        else
            sl = NULL;
        if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 1, remusr, NULL)))
+          {
+            write_status_failure ("sign-encrypt", rc);
            log_error("%s: sign+encrypt failed: %s\n",
-                     print_fname_stdin(fname), g10_errstr(rc) );
+                     print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        free_strlist(sl);
        break;
 
@@ -3670,8 +3920,11 @@ main (int argc, char **argv)
              sl = NULL;
            if ((rc = sign_file (ctrl, sl, detached_sig, locusr,
                                  2, remusr, NULL)))
-             log_error("%s: symmetric+sign+encrypt failed: %s\n",
-                       print_fname_stdin(fname), g10_errstr(rc) );
+              {
+                write_status_failure ("sign-encrypt", rc);
+                log_error("%s: symmetric+sign+encrypt failed: %s\n",
+                          print_fname_stdin(fname), gpg_strerror (rc) );
+              }
            free_strlist(sl);
          }
        break;
@@ -3679,31 +3932,39 @@ main (int argc, char **argv)
       case aSignSym: /* sign and conventionally encrypt the given file */
        if (argc > 1)
            wrong_args(_("--sign --symmetric [filename]"));
-       rc = sign_symencrypt_file (fname, locusr);
+       rc = sign_symencrypt_file (ctrl, fname, locusr);
         if (rc)
+          {
+            write_status_failure ("sign-symencrypt", rc);
            log_error("%s: sign+symmetric failed: %s\n",
-                      print_fname_stdin(fname), g10_errstr(rc) );
+                      print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        break;
 
       case aClearsign: /* make a clearsig */
        if( argc > 1 )
            wrong_args(_("--clearsign [filename]"));
-       if( (rc = clearsign_file(fname, locusr, NULL)) )
+       if( (rc = clearsign_file (ctrl, fname, locusr, NULL)) )
+          {
+            write_status_failure ("sign", rc);
            log_error("%s: clearsign failed: %s\n",
-                      print_fname_stdin(fname), g10_errstr(rc) );
+                      print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        break;
 
       case aVerify:
        if (multifile)
          {
            if ((rc = verify_files (ctrl, argc, argv)))
-             log_error("verify files failed: %s\n", g10_errstr(rc) );
+             log_error("verify files failed: %s\n", gpg_strerror (rc) );
          }
        else
          {
            if ((rc = verify_signatures (ctrl, argc, argv)))
-             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
+             log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
          }
+        if (rc)
+          write_status_failure ("verify", rc);
        break;
 
       case aDecrypt:
@@ -3714,7 +3975,10 @@ main (int argc, char **argv)
            if( argc > 1 )
              wrong_args(_("--decrypt [filename]"));
            if( (rc = decrypt_message (ctrl, fname) ))
-             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
+              {
+                write_status_failure ("decrypt", rc);
+                log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+              }
          }
        break;
 
@@ -3829,7 +4093,7 @@ main (int argc, char **argv)
         if (argc != 1 )
           wrong_args("--gen-key user-id");
         username = make_username (fname);
-        quick_generate_keypair (username);
+        quick_generate_keypair (ctrl, username);
         xfree (username);
         break;
 
@@ -3837,15 +4101,51 @@ main (int argc, char **argv)
        if( opt.batch ) {
            if( argc > 1 )
                wrong_args("--gen-key [parameterfile]");
-           generate_keypair (ctrl, argc? *argv : NULL, NULL, 0);
+           generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
        }
        else {
-           if( argc )
-               wrong_args("--gen-key");
-           generate_keypair (ctrl, NULL, NULL, 0);
+            if (opt.command_fd != -1 && argc)
+              {
+                if( argc > 1 )
+                  wrong_args("--gen-key [parameterfile]");
+
+                opt.batch = 1;
+                generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
+              }
+            else if (argc)
+              wrong_args ("--gen-key");
+            else
+              generate_keypair (ctrl, 0, NULL, NULL, 0);
+       }
+       break;
+
+      case aFullKeygen: /* Generate a key with all options. */
+       if (opt.batch)
+          {
+           if (argc > 1)
+              wrong_args ("--full-gen-key [parameterfile]");
+           generate_keypair (ctrl, 1, argc? *argv : NULL, NULL, 0);
+          }
+       else
+          {
+           if (argc)
+              wrong_args("--full-gen-key");
+           generate_keypair (ctrl, 1, NULL, NULL, 0);
        }
        break;
 
+      case aQuickAddUid:
+        {
+          const char *uid, *newuid;
+
+          if (argc != 2)
+            wrong_args ("--quick-adduid USER-ID NEW-USER-ID");
+          uid = *argv++; argc--;
+          newuid = *argv++; argc--;
+          keyedit_quick_adduid (ctrl, uid, newuid);
+        }
+       break;
+
       case aFastImport:
         opt.import_options |= IMPORT_FAST;
       case aImport:
@@ -3868,26 +4168,55 @@ main (int argc, char **argv)
        else if( cmd == aRecvKeys )
             rc = keyserver_import (ctrl, sl );
        else
-            rc = export_pubkeys (ctrl, sl, opt.export_options);
+          {
+            export_stats_t stats = export_new_stats ();
+            rc = export_pubkeys (ctrl, sl, opt.export_options, stats);
+            export_print_stats (stats);
+            export_release_stats (stats);
+          }
        if(rc)
          {
            if(cmd==aSendKeys)
-             log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
+              {
+                write_status_failure ("send-keys", rc);
+                log_error(_("keyserver send failed: %s\n"),gpg_strerror (rc));
+              }
            else if(cmd==aRecvKeys)
-             log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
+              {
+                write_status_failure ("recv-keys", rc);
+                log_error (_("keyserver receive failed: %s\n"),
+                           gpg_strerror (rc));
+              }
            else
-             log_error(_("key export failed: %s\n"),g10_errstr(rc));
+              {
+                write_status_failure ("export", rc);
+                log_error (_("key export failed: %s\n"), gpg_strerror (rc));
+              }
          }
        free_strlist(sl);
        break;
 
+      case aExportSshKey:
+        if (argc != 1)
+          wrong_args ("--export-ssh-key <user-id>");
+        rc = export_ssh_key (ctrl, argv[0]);
+        if (rc)
+          {
+            write_status_failure ("export-ssh-key", rc);
+            log_error (_("export as ssh key failed: %s\n"), gpg_strerror (rc));
+          }
+       break;
+
      case aSearchKeys:
        sl = NULL;
        for (; argc; argc--, argv++)
          append_to_strlist2 (&sl, *argv, utf8_strings);
        rc = keyserver_search (ctrl, sl);
        if (rc)
-         log_error (_("keyserver search failed: %s\n"), gpg_strerror (rc));
+          {
+            write_status_failure ("search-keys", rc);
+            log_error (_("keyserver search failed: %s\n"), gpg_strerror (rc));
+          }
        free_strlist (sl);
        break;
 
@@ -3897,7 +4226,10 @@ main (int argc, char **argv)
            append_to_strlist2( &sl, *argv, utf8_strings );
        rc = keyserver_refresh (ctrl, sl);
        if(rc)
-         log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
+          {
+            write_status_failure ("refresh-keys", rc);
+            log_error (_("keyserver refresh failed: %s\n"),gpg_strerror (rc));
+          }
        free_strlist(sl);
        break;
 
@@ -3907,7 +4239,10 @@ main (int argc, char **argv)
            append_to_strlist2( &sl, *argv, utf8_strings );
        rc = keyserver_fetch (ctrl, sl);
        if(rc)
-         log_error("key fetch failed: %s\n",g10_errstr(rc));
+          {
+            write_status_failure ("fetch-keys", rc);
+            log_error ("key fetch failed: %s\n",gpg_strerror (rc));
+          }
        free_strlist(sl);
        break;
 
@@ -3915,7 +4250,12 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       export_seckeys (ctrl, sl);
+        {
+          export_stats_t stats = export_new_stats ();
+          export_seckeys (ctrl, sl, stats);
+          export_print_stats (stats);
+          export_release_stats (stats);
+        }
        free_strlist(sl);
        break;
 
@@ -3923,7 +4263,12 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       export_secsubkeys (ctrl, sl);
+        {
+          export_stats_t stats = export_new_stats ();
+          export_secsubkeys (ctrl, sl, stats);
+          export_print_stats (stats);
+          export_release_stats (stats);
+        }
        free_strlist(sl);
        break;
 
@@ -3936,11 +4281,11 @@ main (int argc, char **argv)
        break;
 
       case aDesigRevoke:
-       if( argc != 1 )
-           wrong_args("--desig-revoke user-id");
-       username =  make_username(*argv);
-       gen_desig_revoke( username, locusr );
-       xfree( username );
+       if (argc != 1)
+           wrong_args ("--desig-revoke user-id");
+       username = make_username (*argv);
+       gen_desig_revoke (ctrl, username, locusr);
+       xfree (username);
        break;
 
       case aDeArmor:
@@ -3948,7 +4293,10 @@ main (int argc, char **argv)
            wrong_args("--dearmor [file]");
        rc = dearmor_file( argc? *argv: NULL );
        if( rc )
-           log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
+          {
+            write_status_failure ("dearmor", rc);
+            log_error (_("dearmoring failed: %s\n"), gpg_strerror (rc));
+          }
        break;
 
       case aEnArmor:
@@ -3956,7 +4304,10 @@ main (int argc, char **argv)
            wrong_args("--enarmor [file]");
        rc = enarmor_file( argc? *argv: NULL );
        if( rc )
-           log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
+          {
+            write_status_failure ("enarmor", rc);
+           log_error (_("enarmoring failed: %s\n"), gpg_strerror (rc));
+          }
        break;
 
 
@@ -3978,7 +4329,7 @@ main (int argc, char **argv)
                mpi_print (es_stdout, generate_elg_prime(
                                             1, atoi(argv[1]),
                                             atoi(argv[2]), NULL,&factors ), 1);
-               putchar('\n');
+               es_putc ('\n', es_stdout);
                mpi_print (es_stdout, factors[0], 1 ); /* print q */
            }
            else if( mode == 4 && argc == 3 ) {
@@ -3986,13 +4337,13 @@ main (int argc, char **argv)
                mpi_print (es_stdout, generate_elg_prime(
                                                 0, atoi(argv[1]),
                                                 atoi(argv[2]), g, NULL ), 1);
-               putchar('\n');
+               es_putc ('\n', es_stdout);
                mpi_print (es_stdout, g, 1 );
                mpi_free (g);
            }
            else
                wrong_args("--gen-prime mode bits [qbits] ");
-           putchar('\n');
+           es_putc ('\n', es_stdout);
        }
 #endif
         wrong_args("--gen-prime not yet supported ");
@@ -4021,21 +4372,21 @@ main (int argc, char **argv)
 #endif
                 if (opt.armor) {
                     char *tmp = make_radix64_string (p, n);
-                    fputs (tmp, stdout);
+                    es_fputs (tmp, es_stdout);
                     xfree (tmp);
                     if (n%3 == 1)
-                      putchar ('=');
+                      es_putc ('=', es_stdout);
                     if (n%3)
-                      putchar ('=');
+                      es_putc ('=', es_stdout);
                 } else {
-                    fwrite( p, n, 1, stdout );
+                    es_fwrite( p, n, 1, es_stdout );
                 }
                xfree(p);
                if( !endless )
                    count -= n;
            }
             if (opt.armor)
-                putchar ('\n');
+              es_putc ('\n', es_stdout);
        }
        break;
 
@@ -4072,10 +4423,10 @@ main (int argc, char **argv)
 #ifndef NO_TRUST_MODELS
       case aListTrustDB:
        if( !argc )
-           list_trustdb(NULL);
+          list_trustdb (es_stdout, NULL);
        else {
            for( ; argc; argc--, argv++ )
-               list_trustdb( *argv );
+              list_trustdb (es_stdout, *argv );
        }
        break;
 
@@ -4148,7 +4499,7 @@ main (int argc, char **argv)
         else if (argc == 1)
             change_pin (atoi (*argv),1);
         else
-        wrong_args ("--change-pin [no]");
+            wrong_args ("--change-pin [no]");
         break;
 #endif /* ENABLE_CARD_SUPPORT*/
 
@@ -4160,6 +4511,92 @@ main (int argc, char **argv)
        }
        break;
 
+      case aListGcryptConfig:
+        /* Fixme: It would be nice to integrate that with
+           --list-config but unfortunately there is no way yet to have
+           libgcrypt print it to an estream for further parsing.  */
+        gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
+        break;
+
+      case aTOFUPolicy:
+#ifdef USE_TOFU
+       {
+         int policy;
+         int i;
+         KEYDB_HANDLE hd;
+
+         if (argc < 2)
+           wrong_args ("--tofu-policy POLICY KEYID [KEYID...]");
+
+         policy = parse_tofu_policy (argv[0]);
+
+         hd = keydb_new ();
+         if (! hd)
+            g10_exit (1);
+
+         for (i = 1; i < argc; i ++)
+           {
+             KEYDB_SEARCH_DESC desc;
+             kbnode_t kb;
+
+             rc = classify_user_id (argv[i], &desc, 0);
+             if (rc)
+               {
+                 log_error (_("error parsing key specification '%s': %s\n"),
+                             argv[i], gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             if (! (desc.mode == KEYDB_SEARCH_MODE_SHORT_KID
+                    || desc.mode == KEYDB_SEARCH_MODE_LONG_KID
+                    || desc.mode == KEYDB_SEARCH_MODE_FPR16
+                    || desc.mode == KEYDB_SEARCH_MODE_FPR20
+                    || desc.mode == KEYDB_SEARCH_MODE_FPR
+                    || desc.mode == KEYDB_SEARCH_MODE_KEYGRIP))
+               {
+                 log_error (_("'%s' does not appear to be a valid"
+                              " key ID, fingerprint or keygrip\n"),
+                            argv[i]);
+                 g10_exit (1);
+               }
+
+             rc = keydb_search_reset (hd);
+             if (rc)
+               {
+                  /* This should not happen, thus no need to tranalate
+                     the string.  */
+                  log_error ("keydb_search_reset failed: %s\n",
+                             gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             rc = keydb_search (hd, &desc, 1, NULL);
+             if (rc)
+               {
+                 log_error (_("key \"%s\" not found: %s\n"), argv[i],
+                             gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             rc = keydb_get_keyblock (hd, &kb);
+             if (rc)
+               {
+                 log_error (_("error reading keyblock: %s\n"),
+                             gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             merge_keys_and_selfsig (kb);
+             if (tofu_set_policy (kb, policy))
+               g10_exit (1);
+           }
+
+         keydb_release (hd);
+
+       }
+#endif /*USE_TOFU*/
+       break;
+
       case aListPackets:
        opt.list_packets=2;
       default:
@@ -4195,7 +4632,11 @@ main (int argc, char **argv)
            }
            rc = proc_packets (ctrl, NULL, a );
            if( rc )
-               log_error("processing message failed: %s\n", g10_errstr(rc) );
+              {
+                write_status_failure ("-", rc);
+                log_error ("processing message failed: %s\n",
+                           gpg_strerror (rc));
+              }
            iobuf_close(a);
        }
        break;
@@ -4226,8 +4667,10 @@ g10_exit( int rc )
   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
   if (DBG_CLOCK)
     log_clock ("stop");
+
   if ( (opt.debug & DBG_MEMSTAT_VALUE) )
     {
+      keydb_dump_stats ();
       gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
       gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
     }
@@ -4255,7 +4698,7 @@ print_hex (gcry_md_hd_t md, int algo, const char *fname)
 
   if (indent>40)
     {
-      printf("\n");
+      es_printf ("\n");
       indent=0;
     }
 
@@ -4353,24 +4796,22 @@ print_hashline( gcry_md_hd_t md, int algo, const char *fname )
 static void
 print_mds( const char *fname, int algo )
 {
-  FILE *fp;
+  estream_t fp;
   char buf[1024];
   size_t n;
   gcry_md_hd_t md;
 
   if (!fname)
     {
-      fp = stdin;
-#ifdef HAVE_DOSISH_SYSTEM
-      setmode ( fileno(fp) , O_BINARY );
-#endif
+      fp = es_stdin;
+      es_set_binary (fp);
     }
   else
     {
-      fp = fopen (fname, "rb" );
-      if (fp && is_secured_file (fileno (fp)))
+      fp = es_fopen (fname, "rb" );
+      if (fp && is_secured_file (es_fileno (fp)))
         {
-          fclose (fp);
+          es_fclose (fp);
           fp = NULL;
           gpg_err_set_errno (EPERM);
         }
@@ -4401,10 +4842,10 @@ print_mds( const char *fname, int algo )
         gcry_md_enable (md, GCRY_MD_SHA512);
     }
 
-  while ((n=fread (buf, 1, DIM(buf), fp)))
+  while ((n=es_fread (buf, 1, DIM(buf), fp)))
     gcry_md_write (md, buf, n);
 
-  if (ferror(fp))
+  if (es_ferror(fp))
     log_error ("%s: %s\n", fname?fname:"[stdin]", strerror(errno));
   else
     {
@@ -4454,8 +4895,8 @@ print_mds( const char *fname, int algo )
     }
   gcry_md_close (md);
 
-  if (fp != stdin)
-    fclose (fp);
+  if (fp != es_stdin)
+    es_fclose (fp);
 }