summaryrefslogtreecommitdiffstats
path: root/g10/gpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/gpg.c')
-rw-r--r--g10/gpg.c210
1 files changed, 153 insertions, 57 deletions
diff --git a/g10/gpg.c b/g10/gpg.c
index bd65612..2296351 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,7 +1,7 @@
/* gpg.c - The GnuPG utility (main for gpg)
* Copyright (C) 1998-2020 Free Software Foundation, Inc.
* Copyright (C) 1997-2019 Werner Koch
- * Copyright (C) 2015-2021 g10 Code GmbH
+ * Copyright (C) 2015-2022 g10 Code GmbH
*
* This file is part of GnuPG.
*
@@ -62,8 +62,11 @@
#include "tofu.h"
#include "../common/init.h"
#include "../common/mbox-util.h"
+#include "../common/zb32.h"
#include "../common/shareddefs.h"
#include "../common/compliance.h"
+#include "../kbx/keybox.h"
+
#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
#define MY_O_BINARY O_BINARY
@@ -128,6 +131,7 @@ enum cmd_and_opt_values
aQuickRevUid,
aQuickSetExpire,
aQuickSetPrimaryUid,
+ aQuickUpdatePref,
aListConfig,
aListGcryptConfig,
aGPGConfList,
@@ -248,6 +252,7 @@ enum cmd_and_opt_values
oCipherAlgo,
oDigestAlgo,
oCertDigestAlgo,
+ oNoCompress,
oCompressAlgo,
oCompressLevel,
oBZ2CompressLevel,
@@ -299,6 +304,7 @@ enum cmd_and_opt_values
oShowPhotos,
oNoShowPhotos,
oPhotoViewer,
+ oForceOCB,
oS2KMode,
oS2KDigest,
oS2KCipher,
@@ -348,7 +354,6 @@ enum cmd_and_opt_values
oShowSessionKey,
oOverrideSessionKey,
oOverrideSessionKeyFD,
- oOverrideComplianceCheck,
oNoRandomSeedFile,
oAutoKeyRetrieve,
oNoAutoKeyRetrieve,
@@ -431,6 +436,8 @@ enum cmd_and_opt_values
oForceSignKey,
oForbidGenKey,
oRequireCompliance,
+ oCompatibilityFlags,
+ oAddDesigRevoker,
oNoop
};
@@ -478,6 +485,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aQuickSetExpire, "quick-set-expire",
N_("quickly set a new expiration date")),
ARGPARSE_c (aQuickSetPrimaryUid, "quick-set-primary-uid", "@"),
+ ARGPARSE_c (aQuickUpdatePref, "quick-update-pref", "@"),
ARGPARSE_c (aFullKeygen, "full-generate-key" ,
N_("full featured key pair generation")),
ARGPARSE_c (aFullKeygen, "full-gen-key", "@"),
@@ -672,6 +680,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oLockOnce, "lock-once", "@"),
ARGPARSE_s_n (oLockMultiple, "lock-multiple", "@"),
ARGPARSE_s_n (oLockNever, "lock-never", "@"),
+ ARGPARSE_s_n (oNoCompress, "no-compress", "@"),
ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"),
ARGPARSE_s_s (oCompressAlgo, "compression-algo", "@"), /* Alias */
ARGPARSE_s_n (oBZ2DecompressLowmem, "bzip2-decompress-lowmem", "@"),
@@ -684,6 +693,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"),
ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
#endif
+ ARGPARSE_s_s (oAddDesigRevoker, "add-desig-revoker", "@"),
ARGPARSE_header ("Input", N_("Options controlling the input")),
@@ -834,6 +844,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"),
ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
+ ARGPARSE_s_n (oForceOCB, "force-ocb", "@"),
ARGPARSE_s_n (oRequireCrossCert, "require-backsigs", "@"),
ARGPARSE_s_n (oRequireCrossCert, "require-cross-certification", "@"),
ARGPARSE_s_n (oNoRequireCrossCert, "no-require-backsigs", "@"),
@@ -851,7 +862,6 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
- ARGPARSE_s_n (oOverrideComplianceCheck, "override-compliance-check", "@"),
/* Options to override new security defaults. */
ARGPARSE_s_n (oAllowWeakKeySignatures, "allow-weak-key-signatures", "@"),
ARGPARSE_s_n (oAllowWeakDigestAlgos, "allow-weak-digest-algos", "@"),
@@ -894,6 +904,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
ARGPARSE_s_n (oForbidGenKey, "forbid-gen-key", "@"),
ARGPARSE_s_n (oRequireCompliance, "require-compliance", "@"),
+ ARGPARSE_s_s (oCompatibilityFlags, "compatibility-flags", "@"),
/* Options which can be used in special circumstances. They are not
* published and we hope they are never required. */
ARGPARSE_s_n (oUseOnlyOpenPGPCard, "use-only-openpgp-card", "@"),
@@ -947,6 +958,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoop, "no-force-mdc", "@"),
ARGPARSE_s_n (oNoop, "disable-mdc", "@"),
ARGPARSE_s_n (oNoop, "no-disable-mdc", "@"),
+ ARGPARSE_s_n (oNoop, "override-compliance-check", "@"),
ARGPARSE_group (302, N_(
@@ -986,6 +998,14 @@ static struct debug_flags_s debug_flags [] =
};
+/* The list of compatibility flags. */
+static struct compatibility_flags_s compatibility_flags [] =
+ {
+ { COMPAT_VSD_ALLOW_OCB, "vsd-allow-ocb" },
+ { 0, NULL }
+ };
+
+
#ifdef ENABLE_SELINUX_HACKS
#define ALWAYS_ADD_KEYRINGS 1
#else
@@ -2005,6 +2025,8 @@ parse_list_options(char *str)
char *subpackets=""; /* something that isn't NULL */
struct parse_options lopts[]=
{
+ {"show-sig-subpackets",LIST_SHOW_SIG_SUBPACKETS,NULL,
+ NULL},
{"show-photos",LIST_SHOW_PHOTOS,NULL,
N_("display photo IDs during key listings")},
{"show-usage",LIST_SHOW_USAGE,NULL,
@@ -2031,18 +2053,27 @@ parse_list_options(char *str)
N_("show the keyring name in key listings")},
{"show-sig-expire",LIST_SHOW_SIG_EXPIRE,NULL,
N_("show expiration dates during signature listings")},
- {"show-sig-subpackets",LIST_SHOW_SIG_SUBPACKETS,NULL,
- NULL},
+ {"show-pref", LIST_SHOW_PREF, NULL,
+ N_("show preferences")},
+ {"show-pref-verbose", LIST_SHOW_PREF_VERBOSE, NULL,
+ N_("show preferences")},
{"show-only-fpr-mbox",LIST_SHOW_ONLY_FPR_MBOX, NULL,
NULL},
{NULL,0,NULL,NULL}
};
+ int i;
/* C99 allows for non-constant initializers, but we'd like to
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[13].value=&subpackets;
+ to change the subscript here. We use a loop here in case the
+ list above is reordered. */
+ for (i=0; lopts[i].name; i++)
+ if (lopts[i].bit == LIST_SHOW_SIG_SUBPACKETS)
+ {
+ lopts[i].value = &subpackets;
+ break;
+ }
if(parse_options(str,&opt.list_options,lopts,1))
{
@@ -2609,6 +2640,7 @@ main (int argc, char **argv)
case aQuickRevUid:
case aQuickSetExpire:
case aQuickSetPrimaryUid:
+ case aQuickUpdatePref:
case aExportOwnerTrust:
case aImportOwnerTrust:
case aRebuildKeydbCaches:
@@ -2736,6 +2768,15 @@ main (int argc, char **argv)
case oDebugIOLBF: break; /* Already set in pre-parse step. */
+ case oCompatibilityFlags:
+ if (parse_compatibility_flags (pargs.r.ret_str, &opt.compat_flags,
+ compatibility_flags))
+ {
+ pargs.r_opt = ARGPARSE_INVALID_ARG;
+ pargs.err = ARGPARSE_PRINT_ERROR;
+ }
+ break;
+
case oStatusFD:
set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
break;
@@ -2981,6 +3022,8 @@ main (int argc, char **argv)
break;
case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
+ case oForceOCB: opt.force_ocb = 1; break;
+
case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break;
case oIncludeKeyBlock: opt.flags.include_key_block = 1; break;
case oNoIncludeKeyBlock: opt.flags.include_key_block = 0; break;
@@ -3096,6 +3139,12 @@ main (int argc, char **argv)
case oCompress:
/* this is the -z command line option */
opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
+ opt.explicit_compress_option = 1;
+ break;
+ case oNoCompress:
+ /* --no-compress is the same as -z0 */
+ opt.compress_level = opt.bz2_compress_level = 0;
+ opt.explicit_compress_option = 1;
break;
case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
@@ -3335,7 +3384,7 @@ main (int argc, char **argv)
break;
case oUtf8Strings: utf8_strings = 1; break;
case oNoUtf8Strings:
-#ifdef HAVE_W32_SYSTEM
+#ifndef HAVE_W32_SYSTEM
utf8_strings = 0;
#endif
break;
@@ -3357,7 +3406,13 @@ main (int argc, char **argv)
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 oSetFilesize:
+ /* There are restricts on the value (e.g. < 2^32); you
+ * need to check the entire code to understand this. */
+ opt.set_filesize = pargs.r.ret_ulong;
+ break;
+
case oFastListMode: opt.fast_list_mode = 1; break;
case oFixedListMode: /* Dummy */ break;
case oLegacyListMode: opt.legacy_list_mode = 1; break;
@@ -3562,10 +3617,6 @@ main (int argc, char **argv)
opt.flags.allow_weak_key_signatures = 1;
break;
- case oOverrideComplianceCheck:
- opt.flags.override_compliance_check = 1;
- break;
-
case oFakedSystemTime:
{
size_t len = strlen (pargs.r.ret_str);
@@ -3604,6 +3655,13 @@ main (int argc, char **argv)
opt.flags.require_compliance = 1;
break;
+ case oAddDesigRevoker:
+ if (!strcmp (pargs.r.ret_str, "clear"))
+ FREE_STRLIST (opt.desig_revokers);
+ else
+ append_to_strlist (&opt.desig_revokers, pargs.r.ret_str);
+ break;
+
case oNoop: break;
default:
@@ -3762,17 +3820,14 @@ main (int argc, char **argv)
g10_exit(2);
}
- /* We allow overriding the compliance check only in non-batch mode
- * so that the user has a chance to see the message. */
- if (opt.flags.override_compliance_check && opt.batch)
- {
- opt.flags.override_compliance_check = 0;
- log_info ("Note: '%s' ignored due to batch mode\n",
- "--override-compliance-check");
- }
-
set_debug (debug_level);
- gnupg_set_compliance_extra_info (opt.min_rsa_length);
+ if (opt.verbose) /* Print the compatibility flags. */
+ parse_compatibility_flags (NULL, &opt.compat_flags, compatibility_flags);
+
+ gnupg_set_compliance_extra_info (CO_EXTRA_INFO_MIN_RSA, opt.min_rsa_length);
+ if ((opt.compat_flags & COMPAT_VSD_ALLOW_OCB))
+ gnupg_set_compliance_extra_info (CO_EXTRA_INFO_VSD_ALLOW_OCB, 1);
+
if (DBG_CLOCK)
log_clock ("start");
@@ -4154,6 +4209,7 @@ main (int argc, char **argv)
case aQuickAddKey:
case aQuickRevUid:
case aQuickSetPrimaryUid:
+ case aQuickUpdatePref:
case aFullKeygen:
case aKeygen:
case aImport:
@@ -4654,6 +4710,14 @@ main (int argc, char **argv)
}
break;
+ case aQuickUpdatePref:
+ {
+ if (argc != 1)
+ wrong_args ("--quick-update-pref USER-ID");
+ keyedit_quick_update_pref (ctrl, *argv);
+ }
+ break;
+
case aFastImport:
opt.import_options |= IMPORT_FAST; /* fall through */
case aImport:
@@ -4863,42 +4927,74 @@ main (int argc, char **argv)
case aGenRandom:
{
- int level = argc ? atoi(*argv):0;
- int count = argc > 1 ? atoi(argv[1]): 0;
- int endless = !count;
-
- if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
- wrong_args("--gen-random 0|1|2 [count]");
-
- while( endless || count ) {
- byte *p;
- /* Wee need a multiple of 3, so that in case of
- armored output we get a correct string. No
- linefolding is done, as it is best to levae this to
- other tools */
- size_t n = !endless && count < 99? count : 99;
-
- p = gcry_random_bytes (n, level);
-#ifdef HAVE_DOSISH_SYSTEM
- setmode ( fileno(stdout), O_BINARY );
-#endif
- if (opt.armor) {
- char *tmp = make_radix64_string (p, n);
- es_fputs (tmp, es_stdout);
- xfree (tmp);
- if (n%3 == 1)
- es_putc ('=', es_stdout);
- if (n%3)
- es_putc ('=', es_stdout);
- } else {
- es_fwrite( p, n, 1, es_stdout );
+ int level = argc ? atoi(*argv):0;
+ int count = argc > 1 ? atoi(argv[1]): 0;
+ int endless = !count;
+ int hexhack = (level == 16);
+
+ if (hexhack)
+ level = 1;
+
+ /* Level 30 uses the same algorithm as our magic wand in
+ * pinentry/gpg-agent. */
+ if (level == 30)
+ {
+ unsigned int nbits = 150;
+ size_t nbytes = (nbits + 7) / 8;
+ void *rand;
+ char *generated;
+
+ rand = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
+ if (!rand)
+ log_fatal ("failed to generate random password\n");
+
+ generated = zb32_encode (rand, nbits);
+ gcry_free (rand);
+ es_fputs (generated, es_stdout);
+ es_putc ('\n', es_stdout);
+ xfree (generated);
+ break;
+ }
+
+ if (argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0)
+ wrong_args ("--gen-random 0|1|2|16|30 [count]");
+
+ while (endless || count)
+ {
+ byte *p;
+ /* We need a multiple of 3, so that in case of armored
+ * output we get a correct string. No linefolding is
+ * done, as it is best to leave this to other tools */
+ size_t n = !endless && count < 99? count : 99;
+ size_t nn;
+
+ p = gcry_random_bytes (n, level);
+ if (hexhack)
+ {
+ for (nn = 0; nn < n; nn++)
+ es_fprintf (es_stdout, "%02x", p[nn]);
+ }
+ else if (opt.armor)
+ {
+ char *tmp = make_radix64_string (p, n);
+ es_fputs (tmp, es_stdout);
+ xfree (tmp);
+ if (n%3 == 1)
+ es_putc ('=', es_stdout);
+ if (n%3)
+ es_putc ('=', es_stdout);
}
- xfree(p);
- if( !endless )
- count -= n;
+ else
+ {
+ es_set_binary (es_stdout);
+ es_fwrite( p, n, 1, es_stdout );
+ }
+ xfree(p);
+ if (!endless)
+ count -= n;
}
- if (opt.armor)
- es_putc ('\n', es_stdout);
+ if (opt.armor || hexhack)
+ es_putc ('\n', es_stdout);
}
break;