diff options
Diffstat (limited to 'g10/gpg.c')
-rw-r--r-- | g10/gpg.c | 210 |
1 files changed, 153 insertions, 57 deletions
@@ -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; |