indent: Fix indentation of read_block in g10/import.c
[gnupg.git] / g10 / gpg.c
index d129769..600f844 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -105,6 +105,7 @@ enum cmd_and_opt_values
     oBatch       = 500,
     oMaxOutput,
     oInputSizeHint,
+    oChunkSize,
     oSigNotation,
     oCertNotation,
     oShowNotation,
@@ -149,6 +150,7 @@ enum cmd_and_opt_values
     aSearchKeys,
     aRefreshKeys,
     aFetchKeys,
+    aShowKeys,
     aExport,
     aExportSecret,
     aExportSecretSub,
@@ -197,10 +199,12 @@ enum cmd_and_opt_values
     oWithSubkeyFingerprint,
     oWithICAOSpelling,
     oWithKeygrip,
+    oWithKeyScreening,
     oWithSecret,
     oWithWKDHash,
     oWithColons,
     oWithKeyData,
+    oWithKeyOrigin,
     oWithTofuInfo,
     oWithSigList,
     oWithSigCheck,
@@ -220,6 +224,7 @@ enum cmd_and_opt_values
     oDebugLevel,
     oDebugAll,
     oDebugIOLBF,
+    oDebugSetIobufSize,
     oStatusFD,
     oStatusFile,
     oAttributeFD,
@@ -236,13 +241,13 @@ enum cmd_and_opt_values
     oRFC4880,
     oRFC4880bis,
     oOpenPGP,
-    oPGP6,
     oPGP7,
     oPGP8,
     oDE_VS,
     oRFC2440Text,
     oNoRFC2440Text,
     oCipherAlgo,
+    oAEADAlgo,
     oDigestAlgo,
     oCertDigestAlgo,
     oCompressAlgo,
@@ -263,7 +268,6 @@ enum cmd_and_opt_values
     oRequireSecmem,
     oNoRequireSecmem,
     oNoPermissionWarn,
-    oNoMDCWarn,
     oNoArmor,
     oNoDefKeyring,
     oNoKeyring,
@@ -297,10 +301,7 @@ enum cmd_and_opt_values
     oShowPhotos,
     oNoShowPhotos,
     oPhotoViewer,
-    oForceMDC,
-    oNoForceMDC,
-    oDisableMDC,
-    oNoDisableMDC,
+    oForceAEAD,
     oS2KMode,
     oS2KDigest,
     oS2KCipher,
@@ -369,10 +370,12 @@ enum cmd_and_opt_values
     oDefaultPreferenceList,
     oDefaultKeyserverURL,
     oPersonalCipherPreferences,
+    oPersonalAEADPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
     oAgentProgram,
     oDirmngrProgram,
+    oDisableDirmngr,
     oDisplay,
     oTTYname,
     oTTYtype,
@@ -399,13 +402,10 @@ enum cmd_and_opt_values
     oNoRequireCrossCert,
     oAutoKeyLocate,
     oNoAutoKeyLocate,
-    oAllowMultisigVerification,
     oEnableLargeRSA,
     oDisableLargeRSA,
     oEnableDSA2,
     oDisableDSA2,
-    oAllowMultipleMessages,
-    oNoAllowMultipleMessages,
     oAllowWeakDigestAlgos,
     oFakedSystemTime,
     oNoAutostart,
@@ -419,6 +419,9 @@ enum cmd_and_opt_values
     oOnlySignTextIDs,
     oDisableSignerUID,
     oSender,
+    oKeyOrigin,
+    oRequestOrigin,
+    oNoSymkeyCache,
 
     oNoop
   };
@@ -498,6 +501,7 @@ static ARGPARSE_OPTS opts[] = {
               N_("update all keys from a keyserver")),
   ARGPARSE_c (aLocateKeys, "locate-keys", "@"),
   ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ),
+  ARGPARSE_c (aShowKeys, "show-keys" , "@" ),
   ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ),
   ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ),
   ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ),
@@ -589,15 +593,13 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
   ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
   ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"),
+  ARGPARSE_s_i (oChunkSize, "chunk-size", "@"),
 
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
   ARGPARSE_s_n (oNoTTY,   "no-tty",  "@"),
 
-  ARGPARSE_s_n (oForceMDC, "force-mdc", "@"),
-  ARGPARSE_s_n (oNoForceMDC, "no-force-mdc", "@"),
-  ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"),
-  ARGPARSE_s_n (oNoDisableMDC, "no-disable-mdc", "@"),
+  ARGPARSE_s_n (oForceAEAD, "force-aead", "@"),
 
   ARGPARSE_s_n (oDisableSignerUID, "disable-signer-uid", "@"),
 
@@ -615,6 +617,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
   ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"),
+  ARGPARSE_s_s (oKeyOrigin, "key-origin", "@"),
   ARGPARSE_s_s (oImportOptions, "import-options", "@"),
   ARGPARSE_s_s (oImportFilter,  "import-filter", "@"),
   ARGPARSE_s_s (oExportOptions, "export-options", "@"),
@@ -630,6 +633,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
   ARGPARSE_s_n (oDebugIOLBF, "debug-iolbf", "@"),
+  ARGPARSE_s_u (oDebugSetIobufSize, "debug-set-iobuf-size", "@"),
   ARGPARSE_s_i (oStatusFD, "status-fd", "@"),
   ARGPARSE_s_s (oStatusFile, "status-file", "@"),
   ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"),
@@ -652,7 +656,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oRFC4880, "rfc4880", "@"),
   ARGPARSE_s_n (oRFC4880bis, "rfc4880bis", "@"),
   ARGPARSE_s_n (oOpenPGP, "openpgp", N_("use strict OpenPGP behavior")),
-  ARGPARSE_s_n (oPGP6, "pgp6", "@"),
+  ARGPARSE_s_n (oPGP7, "pgp6", "@"),
   ARGPARSE_s_n (oPGP7, "pgp7", "@"),
   ARGPARSE_s_n (oPGP8, "pgp8", "@"),
 
@@ -663,6 +667,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
   ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
   ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
+  ARGPARSE_s_s (oAEADAlgo,   "aead-algo", "@"),
   ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
   ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
   ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"),
@@ -704,6 +709,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
   ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
   ARGPARSE_s_s (oPinentryMode,    "pinentry-mode", "@"),
+  ARGPARSE_s_s (oRequestOrigin,   "request-origin", "@"),
   ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
   ARGPARSE_s_s (oCommandFile, "command-file", "@"),
   ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
@@ -720,7 +726,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oRequireSecmem, "require-secmem", "@"),
   ARGPARSE_s_n (oNoRequireSecmem, "no-require-secmem", "@"),
   ARGPARSE_s_n (oNoPermissionWarn, "no-permission-warning", "@"),
-  ARGPARSE_s_n (oNoMDCWarn, "no-mdc-warning", "@"),
   ARGPARSE_s_n (oNoArmor, "no-armor", "@"),
   ARGPARSE_s_n (oNoArmor, "no-armour", "@"),
   ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"),
@@ -737,6 +742,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aListKeys, "list-key", "@"),   /* alias */
   ARGPARSE_c (aListSigs, "list-sig", "@"),   /* alias */
   ARGPARSE_c (aCheckKeys, "check-sig", "@"), /* alias */
+  ARGPARSE_c (aShowKeys,  "show-key", "@"), /* alias */
   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
@@ -781,8 +787,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
   ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
+  ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
+  ARGPARSE_s_n (oWithKeyOrigin,   "with-key-origin", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -817,6 +825,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDefaultPreferenceList,  "default-preference-list", "@"),
   ARGPARSE_s_s (oDefaultKeyserverURL,  "default-keyserver-url", "@"),
   ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-preferences","@"),
+  ARGPARSE_s_s (oPersonalAEADPreferences, "personal-aead-preferences","@"),
   ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"),
   ARGPARSE_s_s (oPersonalCompressPreferences,
                                          "personal-compress-preferences", "@"),
@@ -828,11 +837,13 @@ static ARGPARSE_OPTS opts[] = {
   /* Aliases.  I constantly mistype these, and assume other people do
      as well. */
   ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-prefs", "@"),
+  ARGPARSE_s_s (oPersonalAEADPreferences,   "personal-aead-prefs", "@"),
   ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-prefs", "@"),
   ARGPARSE_s_s (oPersonalCompressPreferences, "personal-compress-prefs", "@"),
 
   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
   ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
+  ARGPARSE_s_n (oDisableDirmngr, "disable-dirmngr", "@"),
   ARGPARSE_s_s (oDisplay,    "display",    "@"),
   ARGPARSE_s_s (oTTYname,    "ttyname",    "@"),
   ARGPARSE_s_s (oTTYtype,    "ttytype",    "@"),
@@ -852,14 +863,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oExitOnStatusWriteError, "exit-on-status-write-error", "@"),
   ARGPARSE_s_i (oLimitCardInsertTries, "limit-card-insert-tries", "@"),
 
-  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", "@"),
-  ARGPARSE_s_n (oNoAllowMultipleMessages, "no-allow-multiple-messages", "@"),
   ARGPARSE_s_n (oAllowWeakDigestAlgos, "allow-weak-digest-algos", "@"),
 
   ARGPARSE_s_s (oDefaultNewKeyAlgo, "default-new-key-algo", "@"),
@@ -880,6 +887,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oAutoKeyLocate, "auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutoKeyLocate, "no-auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
+  ARGPARSE_s_n (oNoSymkeyCache, "no-symkey-cache", "@"),
 
   /* Dummy options with warnings.  */
   ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
@@ -901,6 +909,14 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoop, "no-force-v3-sigs", "@"),
   ARGPARSE_s_n (oNoop, "force-v4-certs", "@"),
   ARGPARSE_s_n (oNoop, "no-force-v4-certs", "@"),
+  ARGPARSE_s_n (oNoop, "no-mdc-warning", "@"),
+  ARGPARSE_s_n (oNoop, "force-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "disable-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "no-disable-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "allow-multisig-verification", "@"),
+  ARGPARSE_s_n (oNoop, "allow-multiple-messages", "@"),
+  ARGPARSE_s_n (oNoop, "no-allow-multiple-messages", "@"),
 
   ARGPARSE_end ()
 };
@@ -938,6 +954,8 @@ int g10_errors_seen = 0;
 
 static int utf8_strings = 0;
 static int maybe_setuid = 1;
+static unsigned int opt_set_iobuf_size;
+static unsigned int opt_set_iobuf_size_used;
 
 static char *build_list( const char *text, char letter,
                         const char *(*mapf)(int), int (*chkf)(int) );
@@ -1000,6 +1018,18 @@ build_list_cipher_algo_name (int algo)
 }
 
 static int
+build_list_aead_test_algo (int algo)
+{
+  return openpgp_aead_test_algo (algo);
+}
+
+static const char *
+build_list_aead_algo_name (int algo)
+{
+  return openpgp_aead_algo_name (algo);
+}
+
+static int
 build_list_md_test_algo (int algo)
 {
   /* By default we do not accept MD5 based signatures.  To avoid
@@ -1020,7 +1050,7 @@ build_list_md_algo_name (int algo)
 static const char *
 my_strusage( int level )
 {
-  static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry;
+  static char *digests, *pubkeys, *ciphers, *zips, *aeads, *ver_gcry;
   const char *p;
 
     switch( level ) {
@@ -1080,13 +1110,20 @@ my_strusage( int level )
        p = ciphers;
        break;
       case 36:
+       if (!aeads)
+          aeads = build_list ("AEAD: ", 'A',
+                              build_list_aead_algo_name,
+                              build_list_aead_test_algo);
+       p = aeads;
+       break;
+      case 37:
        if( !digests )
            digests = build_list(_("Hash: "), 'H',
                                  build_list_md_algo_name,
                                  build_list_md_test_algo );
        p = digests;
        break;
-      case 37:
+      case 38:
        if( !zips )
            zips = build_list(_("Compression: "),'Z',
                               compress_algo_to_string,
@@ -1107,6 +1144,7 @@ build_list (const char *text, char letter,
   membuf_t mb;
   int indent;
   int i, j, len;
+  int limit;
   const char *s;
   char *string;
 
@@ -1117,7 +1155,8 @@ build_list (const char *text, char letter,
   len = 0;
   init_membuf (&mb, 512);
 
-  for (i=0; i <= 110; i++ )
+  limit = (letter == 'A')? 4 : 110;
+  for (i=0; i <= limit; i++ )
     {
       if (!chkf (i) && (s = mapf (i)))
         {
@@ -1158,6 +1197,7 @@ static void
 wrong_args( const char *text)
 {
   es_fprintf (es_stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
+  log_inc_errorcount ();
   g10_exit(2);
 }
 
@@ -1237,6 +1277,10 @@ set_debug (const char *level)
 
   if (opt.debug)
     parse_debug_flag (NULL, &opt.debug, debug_flags);
+
+  if (opt_set_iobuf_size || opt_set_iobuf_size_used)
+    log_debug ("iobuf buffer size is %uk\n",
+               iobuf_set_buffer_size (opt_set_iobuf_size));
 }
 
 
@@ -1853,6 +1897,10 @@ gpgconf_list (const char *configfile)
   es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
   es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("trust-model:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("max-cert-depth:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("completes-needed:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("marginals-needed:%lu:\n", GC_OPT_FLAG_NONE);
 
   /* The next one is an info only item and should match the macros at
      the top of keygen.c  */
@@ -2081,7 +2129,7 @@ static struct gnupg_compliance_option compliance_options[] =
     { "rfc4880bis", oRFC4880bis },
     { "rfc4880",    oRFC4880 },
     { "rfc2440",    oRFC2440 },
-    { "pgp6",       oPGP6 },
+    { "pgp6",       oPGP7 },
     { "pgp7",       oPGP7 },
     { "pgp8",       oPGP8 },
     { "de-vs",      oDE_VS }
@@ -2113,6 +2161,7 @@ set_compliance_option (enum cmd_and_opt_values option)
       opt.escape_from = 1;
       opt.not_dash_escaped = 0;
       opt.def_cipher_algo = 0;
+      opt.def_aead_algo = 0;
       opt.def_digest_algo = 0;
       opt.cert_digest_algo = 0;
       opt.compress_algo = -1;
@@ -2129,6 +2178,7 @@ set_compliance_option (enum cmd_and_opt_values option)
       opt.escape_from = 0;
       opt.not_dash_escaped = 0;
       opt.def_cipher_algo = 0;
+      opt.def_aead_algo = 0;
       opt.def_digest_algo = 0;
       opt.cert_digest_algo = 0;
       opt.compress_algo = -1;
@@ -2136,7 +2186,6 @@ set_compliance_option (enum cmd_and_opt_values option)
       opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
       opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
       break;
-    case oPGP6:  opt.compliance = CO_PGP6;  break;
     case oPGP7:  opt.compliance = CO_PGP7;  break;
     case oPGP8:  opt.compliance = CO_PGP8;  break;
     case oGnuPG: opt.compliance = CO_GNUPG; break;
@@ -2144,7 +2193,7 @@ set_compliance_option (enum cmd_and_opt_values option)
     case oDE_VS:
       set_compliance_option (oOpenPGP);
       opt.compliance = CO_DE_VS;
-      opt.force_mdc = 1;
+      opt.def_aead_algo = 0;
       /* Fixme: Change other options.  */
       break;
 
@@ -2274,12 +2323,14 @@ main (int argc, char **argv)
     const char *trustdb_name = NULL;
 #endif /*!NO_TRUST_MODELS*/
     char *def_cipher_string = NULL;
+    char *def_aead_string = NULL;
     char *def_digest_string = NULL;
     char *compress_algo_string = NULL;
     char *cert_digest_string = NULL;
     char *s2k_cipher_string = NULL;
     char *s2k_digest_string = NULL;
     char *pers_cipher_list = NULL;
+    char *pers_aead_list = NULL;
     char *pers_digest_list = NULL;
     char *pers_compress_list = NULL;
     int eyes_only=0;
@@ -2288,6 +2339,7 @@ main (int argc, char **argv)
     int ovrseskeyfd = -1;
     int fpr_maybe_cmd = 0; /* --fingerprint maybe a command.  */
     int any_explicit_recipient = 0;
+    int default_akl = 1;
     int require_secmem = 0;
     int got_secmem = 0;
     struct assuan_malloc_hooks malloc_hooks;
@@ -2342,6 +2394,7 @@ main (int argc, char **argv)
     opt.bz2_compress_level = -1; /* defaults to standard compress level */
     /* note: if you change these lines, look at oOpenPGP */
     opt.def_cipher_algo = 0;
+    opt.def_aead_algo = 0;
     opt.def_digest_algo = 0;
     opt.cert_digest_algo = 0;
     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
@@ -2381,7 +2434,6 @@ main (int argc, char **argv)
     opt.passphrase_repeat = 1;
     opt.emit_version = 0;
     opt.weak_digests = NULL;
-    additional_weak_digest("MD5");
 
     /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
@@ -2457,6 +2509,10 @@ main (int argc, char **argv)
     assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
     setup_libassuan_logging (&opt.debug, NULL);
 
+    /* Set default options which require that malloc stuff is ready.  */
+    additional_weak_digest ("MD5");
+    parse_auto_key_locate ("local,wkd");
+
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
     if (default_config)
@@ -2589,6 +2645,17 @@ main (int argc, char **argv)
             greeting=1;
             break;
 
+         case aShowKeys:
+            set_cmd (&cmd, pargs.r_opt);
+            opt.import_options |= IMPORT_SHOW;
+            opt.import_options |= IMPORT_DRY_RUN;
+            opt.import_options &= ~IMPORT_REPAIR_KEYS;
+            opt.list_options |= LIST_SHOW_UNUSABLE_UIDS;
+            opt.list_options |= LIST_SHOW_UNUSABLE_SUBKEYS;
+            opt.list_options |= LIST_SHOW_NOTATIONS;
+            opt.list_options |= LIST_SHOW_POLICY_URLS;
+            break;
+
          case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
 
          case aDecryptFiles: multifile=1; /* fall through */
@@ -2618,6 +2685,10 @@ main (int argc, char **argv)
             opt.input_size_hint = string_to_u64 (pargs.r.ret_str);
             break;
 
+          case oChunkSize:
+            opt.chunk_size = pargs.r.ret_int;
+            break;
+
          case oQuiet: opt.quiet = 1; break;
          case oNoTTY: tty_no_terminal(1); break;
          case oDryRun: opt.dry_run = 1; break;
@@ -2685,6 +2756,11 @@ main (int argc, char **argv)
 
           case oDebugIOLBF: break; /* Already set in pre-parse step.  */
 
+          case oDebugSetIobufSize:
+            opt_set_iobuf_size = pargs.r.ret_ulong;
+            opt_set_iobuf_size_used = 1;
+            break;
+
          case oStatusFD:
             set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
             break;
@@ -2723,6 +2799,10 @@ main (int argc, char **argv)
             opt.with_keygrip = 1;
             break;
 
+         case oWithKeyScreening:
+            opt.with_key_screening = 1;
+            break;
+
          case oWithSecret:
             opt.with_secret = 1;
             break;
@@ -2731,6 +2811,10 @@ main (int argc, char **argv)
             opt.with_wkd_hash = 1;
             break;
 
+         case oWithKeyOrigin:
+            opt.with_key_origin = 1;
+            break;
+
          case oSecretKeyring:
             /* Ignore this old option.  */
             break;
@@ -2845,10 +2929,10 @@ main (int argc, char **argv)
 
           case oCompliance:
            {
-             int compliance = gnupg_parse_compliance_option (pargs.r.ret_str,
-                                                             compliance_options,
-                                                             DIM (compliance_options),
-                                                             opt.quiet);
+             int compliance = gnupg_parse_compliance_option
+                (pargs.r.ret_str,
+                 compliance_options, DIM (compliance_options),
+                 opt.quiet);
              if (compliance < 0)
                g10_exit (1);
              set_compliance_option (compliance);
@@ -2858,7 +2942,6 @@ main (int argc, char **argv)
           case oRFC2440:
           case oRFC4880:
           case oRFC4880bis:
-          case oPGP6:
           case oPGP7:
           case oPGP8:
           case oGnuPG:
@@ -2937,10 +3020,7 @@ main (int argc, char **argv)
            break;
          case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
 
-         case oForceMDC: opt.force_mdc = 1; break;
-         case oNoForceMDC: opt.force_mdc = 0; break;
-         case oDisableMDC: opt.disable_mdc = 1; break;
-         case oNoDisableMDC: opt.disable_mdc = 0; break;
+         case oForceAEAD: opt.force_aead = 1; break;
 
           case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break;
 
@@ -3078,10 +3158,16 @@ main (int argc, char **argv)
               log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
            break;
 
+          case oRequestOrigin:
+           opt.request_origin = parse_request_origin (pargs.r.ret_str);
+           if (opt.request_origin == -1)
+              log_error (_("invalid request origin '%s'\n"), pargs.r.ret_str);
+           break;
+
          case oCommandFD:
             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
            if (! gnupg_fd_valid (opt.command_fd))
-             log_fatal ("command-fd is invalid: %s\n", strerror (errno));
+             log_error ("command-fd is invalid: %s\n", strerror (errno));
             break;
          case oCommandFile:
             opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1);
@@ -3089,6 +3175,9 @@ main (int argc, char **argv)
          case oCipherAlgo:
             def_cipher_string = xstrdup(pargs.r.ret_str);
             break;
+         case oAEADAlgo:
+            def_aead_string = xstrdup (pargs.r.ret_str);
+            break;
          case oDigestAlgo:
             def_digest_string = xstrdup(pargs.r.ret_str);
             break;
@@ -3127,7 +3216,6 @@ main (int argc, char **argv)
          case oRequireSecmem: require_secmem=1; break;
          case oNoRequireSecmem: require_secmem=0; break;
          case oNoPermissionWarn: opt.no_perm_warn=1; break;
-         case oNoMDCWarn: opt.no_mdc_warn=1; break;
           case oDisplayCharset:
            if( set_native_charset( pargs.r.ret_str ) )
                log_error(_("'%s' is not a valid character set\n"),
@@ -3318,13 +3406,14 @@ main (int argc, char **argv)
          case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
          case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
          case oNoRandomSeedFile: use_random_seed = 0; break;
+
          case oAutoKeyRetrieve:
+            opt.keyserver_options.options |= KEYSERVER_AUTO_KEY_RETRIEVE;
+            break;
          case oNoAutoKeyRetrieve:
-               if(pargs.r_opt==oAutoKeyRetrieve)
-                 opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
-               else
-                 opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
-               break;
+            opt.keyserver_options.options &= ~KEYSERVER_AUTO_KEY_RETRIEVE;
+            break;
+
          case oShowSessionKey: opt.show_session_key = 1; break;
          case oOverrideSessionKey:
                opt.override_session_key = pargs.r.ret_str;
@@ -3367,6 +3456,9 @@ main (int argc, char **argv)
           case oPersonalCipherPreferences:
            pers_cipher_list=pargs.r.ret_str;
            break;
+          case oPersonalAEADPreferences:
+           pers_aead_list = pargs.r.ret_str;
+           break;
           case oPersonalDigestPreferences:
            pers_digest_list=pargs.r.ret_str;
            break;
@@ -3375,6 +3467,7 @@ 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 oDisableDirmngr: opt.disable_dirmngr = 1;  break;
           case oWeakDigest:
            additional_weak_digest(pargs.r.ret_str);
            break;
@@ -3449,6 +3542,13 @@ main (int argc, char **argv)
          case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
 
          case oAutoKeyLocate:
+            if (default_akl)
+              {
+                /* This is the first time --aito-key-locate is seen.
+                 * We need to reset the default akl.  */
+                default_akl = 0;
+                release_akl();
+              }
            if(!parse_auto_key_locate(pargs.r.ret_str))
              {
                if(configname)
@@ -3462,6 +3562,12 @@ main (int argc, char **argv)
            release_akl();
            break;
 
+         case oKeyOrigin:
+           if(!parse_key_origin (pargs.r.ret_str))
+              log_error (_("invalid argument for option \"%.50s\"\n"),
+                         "--key-origin");
+           break;
+
          case oEnableLargeRSA:
 #if SECMEM_BUFFER_SIZE >= 65536
             opt.flags.large_rsa=1;
@@ -3481,15 +3587,6 @@ main (int argc, char **argv)
          case oEnableDSA2: opt.flags.dsa2=1; break;
          case oDisableDSA2: opt.flags.dsa2=0; break;
 
-          case oAllowMultisigVerification:
-         case oAllowMultipleMessages:
-           opt.flags.allow_multiple_messages=1;
-           break;
-
-         case oNoAllowMultipleMessages:
-           opt.flags.allow_multiple_messages=0;
-           break;
-
           case oAllowWeakDigestAlgos:
             opt.flags.allow_weak_digest_algos = 1;
             break;
@@ -3514,6 +3611,7 @@ main (int argc, char **argv)
             break;
 
           case oNoAutostart: opt.autostart = 0; break;
+          case oNoSymkeyCache: opt.no_symkey_cache = 1; break;
 
          case oDefaultNewKeyAlgo:
             opt.def_new_key_algo = pargs.r.ret_str;
@@ -3522,7 +3620,16 @@ main (int argc, char **argv)
          case oNoop: break;
 
          default:
-            pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
+            if (configfp)
+              pargs.err = ARGPARSE_PRINT_WARNING;
+            else
+              {
+                pargs.err = ARGPARSE_PRINT_ERROR;
+                /* The argparse function calls a plain exit and thus
+                 * we need to print a status here.  */
+                write_status_failure ("option-parser",
+                                      gpg_error(GPG_ERR_GENERAL));
+              }
             break;
          }
       }
@@ -3541,7 +3648,10 @@ main (int argc, char **argv)
       }
     xfree(configname); configname = NULL;
     if (log_get_errorcount (0))
-      g10_exit(2);
+      {
+        write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL));
+        g10_exit(2);
+      }
 
     /* The command --gpgconf-list is pretty simple and may be called
        directly after the option parsing. */
@@ -3562,7 +3672,10 @@ main (int argc, char **argv)
                  "--print-pks-records",
                  "--export-options export-pka");
     if (log_get_errorcount (0))
-      g10_exit(2);
+      {
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
+        g10_exit(2);
+      }
 
 
     if( nogreeting )
@@ -3663,6 +3776,7 @@ main (int argc, char **argv)
       {
        log_info(_("will not run with insecure memory due to %s\n"),
                 "--require-secmem");
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
        g10_exit(2);
       }
 
@@ -3671,15 +3785,7 @@ main (int argc, char **argv)
       log_clock ("start");
 
     /* 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.ask_sig_expire=0;
-      }
-    else if(PGP7)
+    if (PGP7)
       {
         /* That does not anymore work because we have no more support
            for v3 signatures.  */
@@ -3698,6 +3804,13 @@ main (int argc, char **argv)
        if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
            log_error(_("selected cipher algorithm is invalid\n"));
     }
+    if (def_aead_string)
+      {
+       opt.def_aead_algo = string_to_aead_algo (def_aead_string);
+       xfree (def_aead_string); def_aead_string = NULL;
+       if (openpgp_aead_test_algo (opt.def_aead_algo))
+          log_error(_("selected AEAD algorithm is invalid\n"));
+      }
     if( def_digest_string ) {
        opt.def_digest_algo = string_to_digest_algo (def_digest_string);
        xfree(def_digest_string); def_digest_string = NULL;
@@ -3757,6 +3870,9 @@ main (int argc, char **argv)
        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
       log_error(_("invalid personal cipher preferences\n"));
 
+    if (pers_aead_list && keygen_set_std_prefs (pers_aead_list, PREFTYPE_AEAD))
+      log_error(_("invalid personal AEAD preferences\n"));
+
     if(pers_digest_list &&
        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
       log_error(_("invalid personal digest preferences\n"));
@@ -3765,6 +3881,21 @@ main (int argc, char **argv)
        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
       log_error(_("invalid personal compress preferences\n"));
 
+    /* Check chunk size.  Please fix also the man page if you chnage
+     * the default.  The limits are given by the specs.  */
+    if (!opt.chunk_size)
+      opt.chunk_size = 30; /* Default to 1 GiB chunks.  */
+    else if (opt.chunk_size < 6)
+      {
+        opt.chunk_size = 6;
+        log_info (_("chunk size invalid - using %d\n"), opt.chunk_size);
+      }
+    else if (opt.chunk_size > 62)
+      {
+        opt.chunk_size = 62;
+        log_info (_("chunk size invalid - using %d\n"), opt.chunk_size);
+      }
+
     /* We don't support all possible commands with multifile yet */
     if(multifile)
       {
@@ -3803,7 +3934,11 @@ main (int argc, char **argv)
       }
 
     if( log_get_errorcount(0) )
-       g10_exit(2);
+      {
+        write_status_failure ("option-postprocessing",
+                              gpg_error(GPG_ERR_GENERAL));
+       g10_exit (2);
+      }
 
     if(opt.compress_level==0)
       opt.compress_algo=COMPRESS_ALGO_NONE;
@@ -3811,7 +3946,7 @@ main (int argc, char **argv)
     /* Check our chosen algorithms against the list of legal
        algorithms. */
 
-    if(!GNUPG)
+    if(!GNUPG && !opt.flags.rfc4880bis)
       {
        const char *badalg=NULL;
        preftype_t badtype=PREFTYPE_NONE;
@@ -3822,6 +3957,12 @@ main (int argc, char **argv)
            badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
            badtype = PREFTYPE_SYM;
          }
+       else if(opt.def_aead_algo
+          && !algo_available(PREFTYPE_AEAD, opt.def_aead_algo, NULL))
+         {
+           badalg = openpgp_aead_algo_name (opt.def_aead_algo);
+           badtype = PREFTYPE_AEAD;
+         }
        else if(opt.def_digest_algo
                && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
          {
@@ -3846,19 +3987,28 @@ main (int argc, char **argv)
            switch(badtype)
              {
              case PREFTYPE_SYM:
-               log_info(_("you may not use cipher algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg, gnupg_compliance_option_string (opt.compliance));
+               log_info (_("cipher algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                        badalg,
+                          gnupg_compliance_option_string (opt.compliance));
+               break;
+             case PREFTYPE_AEAD:
+               log_info (_("AEAD algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              case PREFTYPE_HASH:
-               log_info(_("you may not use digest algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg, gnupg_compliance_option_string (opt.compliance));
+               log_info (_("digest algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              case PREFTYPE_ZIP:
-               log_info(_("you may not use compression algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg, gnupg_compliance_option_string (opt.compliance));
+               log_info (_("compression algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              default:
                BUG();
@@ -3873,6 +4023,7 @@ main (int argc, char **argv)
      * is not.  This is us being nice to the user informing her early
      * that the chosen algorithms are not available.  We also check
      * and enforce this right before the actual operation.  */
+    /* FIXME: We also need to check the AEAD algo. */
     if (opt.def_cipher_algo
        && ! gnupg_cipher_is_allowed (opt.compliance,
                                      cmd == aEncr
@@ -3883,8 +4034,7 @@ main (int argc, char **argv)
                                      || cmd == aSignEncrSym,
                                      opt.def_cipher_algo,
                                      GCRY_CIPHER_MODE_NONE))
-      log_error (_ ("you may not use cipher algorithm '%s'"
-                   " while in %s mode\n"),
+      log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
                 openpgp_cipher_algo_name (opt.def_cipher_algo),
                 gnupg_compliance_option_string (opt.compliance));
 
@@ -3896,14 +4046,16 @@ main (int argc, char **argv)
                                      || cmd == aSignSym
                                      || cmd == aClearsign,
                                      opt.def_digest_algo))
-      log_error (_ ("you may not use digest algorithm '%s'"
-                   " while in %s mode\n"),
+      log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
                 gcry_md_algo_name (opt.def_digest_algo),
                 gnupg_compliance_option_string (opt.compliance));
 
     /* Fail hard.  */
     if (log_get_errorcount (0))
+      {
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
        g10_exit (2);
+      }
 
     /* Set the random seed file. */
     if( use_random_seed ) {
@@ -4112,9 +4264,9 @@ main (int argc, char **argv)
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --encrypt"
                      " with --s2k-mode 0\n"));
-       else if(PGP6 || PGP7)
+       else if (PGP7)
          log_error(_("you cannot use --symmetric --encrypt"
-                     " while in %s mode\n"),
+                     " in %s mode\n"),
                    gnupg_compliance_option_string (opt.compliance));
        else
          {
@@ -4173,9 +4325,9 @@ main (int argc, char **argv)
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --sign --encrypt"
                      " with --s2k-mode 0\n"));
-       else if(PGP6 || PGP7)
+       else if (PGP7)
          log_error(_("you cannot use --symmetric --sign --encrypt"
-                     " while in %s mode\n"),
+                     " in %s mode\n"),
                    gnupg_compliance_option_string (opt.compliance));
        else
          {
@@ -4477,11 +4629,11 @@ main (int argc, char **argv)
         {
           const char *x_fpr, *x_expire;
 
-          if (argc != 2)
-            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
+          if (argc < 2)
+            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE [SUBKEY-FPRS]");
           x_fpr = *argv++; argc--;
           x_expire = *argv++; argc--;
-          keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
+          keyedit_quick_set_expire (ctrl, x_fpr, x_expire, argv);
         }
        break;
 
@@ -4500,7 +4652,9 @@ main (int argc, char **argv)
       case aFastImport:
         opt.import_options |= IMPORT_FAST; /* fall through */
       case aImport:
-       import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options);
+      case aShowKeys:
+       import_keys (ctrl, argc? argv:NULL, argc, NULL,
+                     opt.import_options, opt.key_origin, opt.key_origin_url);
        break;
 
        /* TODO: There are a number of command that use this same
@@ -4588,7 +4742,7 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            append_to_strlist2( &sl, *argv, utf8_strings );
-       rc = keyserver_fetch (ctrl, sl);
+       rc = keyserver_fetch (ctrl, sl, opt.key_origin);
        if(rc)
           {
             write_status_failure ("fetch-keys", rc);
@@ -4886,7 +5040,10 @@ main (int argc, char **argv)
 
          hd = keydb_new ();
          if (! hd)
-            g10_exit (1);
+            {
+              write_status_failure ("tofu-driver", gpg_error(GPG_ERR_GENERAL));
+              g10_exit (1);
+            }
 
           tofu_begin_batch_update (ctrl);
 
@@ -4900,6 +5057,7 @@ main (int argc, char **argv)
                {
                  log_error (_("error parsing key specification '%s': %s\n"),
                              argv[i], gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4913,6 +5071,8 @@ main (int argc, char **argv)
                  log_error (_("'%s' does not appear to be a valid"
                               " key ID, fingerprint or keygrip\n"),
                             argv[i]);
+                  write_status_failure ("tofu-driver",
+                                        gpg_error(GPG_ERR_GENERAL));
                  g10_exit (1);
                }
 
@@ -4923,6 +5083,7 @@ main (int argc, char **argv)
                      the string.  */
                   log_error ("keydb_search_reset failed: %s\n",
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4931,6 +5092,7 @@ main (int argc, char **argv)
                {
                  log_error (_("key \"%s\" not found: %s\n"), argv[i],
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4939,12 +5101,16 @@ main (int argc, char **argv)
                {
                  log_error (_("error reading keyblock: %s\n"),
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
              merge_keys_and_selfsig (ctrl, kb);
              if (tofu_set_policy (ctrl, kb, policy))
-               g10_exit (1);
+                {
+                  write_status_failure ("tofu-driver", rc);
+                  g10_exit (1);
+                }
 
               release_kbnode (kb);
            }
@@ -5026,6 +5192,12 @@ emergency_cleanup (void)
 void
 g10_exit( int rc )
 {
+  /* If we had an error but not printed an error message, do it now.
+   * Note that write_status_failure will never print a second failure
+   * status line. */
+  if (rc)
+    write_status_failure ("gpg-exit", gpg_error (GPG_ERR_GENERAL));
+
   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
   if (DBG_CLOCK)
     log_clock ("stop");