summaryrefslogtreecommitdiff
path: root/g10/gpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/gpg.c')
-rw-r--r--g10/gpg.c259
1 files changed, 198 insertions, 61 deletions
diff --git a/g10/gpg.c b/g10/gpg.c
index e02efe4..c54facb 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -16,7 +16,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <config.h>
@@ -193,6 +193,11 @@ enum cmd_and_opt_values
oWithKeygrip,
oWithSecret,
oWithWKDHash,
+ oWithColons,
+ oWithKeyData,
+ oWithTofuInfo,
+ oWithSigList,
+ oWithSigCheck,
oAnswerYes,
oAnswerNo,
oKeyring,
@@ -219,6 +224,7 @@ enum cmd_and_opt_values
oMarginalsNeeded,
oMaxCertDepth,
oLoadExtension,
+ oCompliance,
oGnuPG,
oRFC2440,
oRFC4880,
@@ -227,6 +233,7 @@ enum cmd_and_opt_values
oPGP6,
oPGP7,
oPGP8,
+ oDE_VS,
oRFC2440Text,
oNoRFC2440Text,
oCipherAlgo,
@@ -259,10 +266,6 @@ enum cmd_and_opt_values
oNoOptions,
oNoBatch,
oHomedir,
- oWithColons,
- oWithKeyData,
- oWithSigList,
- oWithSigCheck,
oSkipVerify,
oSkipHiddenRecipients,
oNoSkipHiddenRecipients,
@@ -340,6 +343,7 @@ enum cmd_and_opt_values
oIgnoreMDCError,
oShowSessionKey,
oOverrideSessionKey,
+ oOverrideSessionKeyFD,
oNoRandomSeedFile,
oAutoKeyRetrieve,
oNoAutoKeyRetrieve,
@@ -612,6 +616,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oLoadExtension, "load-extension", "@"), /* Dummy. */
+ ARGPARSE_s_s (oCompliance, "compliance", "@"),
ARGPARSE_s_n (oGnuPG, "gnupg", "@"),
ARGPARSE_s_n (oGnuPG, "no-pgp2", "@"),
ARGPARSE_s_n (oGnuPG, "no-pgp6", "@"),
@@ -699,6 +704,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_n (oNoBatch, "no-batch", "@"),
ARGPARSE_s_n (oWithColons, "with-colons", "@"),
+ ARGPARSE_s_n (oWithTofuInfo,"with-tofu-info", "@"),
ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"),
ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"),
ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"),
@@ -771,6 +777,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oIgnoreMDCError, "ignore-mdc-error", "@"),
ARGPARSE_s_n (oShowSessionKey, "show-session-key", "@"),
ARGPARSE_s_s (oOverrideSessionKey, "override-session-key", "@"),
+ ARGPARSE_s_i (oOverrideSessionKeyFD, "override-session-key-fd", "@"),
ARGPARSE_s_n (oNoRandomSeedFile, "no-random-seed-file", "@"),
ARGPARSE_s_n (oAutoKeyRetrieve, "auto-key-retrieve", "@"),
ARGPARSE_s_n (oNoAutoKeyRetrieve, "no-auto-key-retrieve", "@"),
@@ -914,6 +921,7 @@ static void add_notation_data( const char *string, int which );
static void add_policy_url( const char *string, int which );
static void add_keyserver_url( const char *string, int which );
static void emergency_cleanup (void);
+static void read_sessionkey_from_fd (int fd);
static char *
@@ -1188,15 +1196,15 @@ set_debug (const char *level)
g10_exit (2);
}
- if (opt.debug & DBG_MEMORY_VALUE )
+ if ((opt.debug & DBG_MEMORY_VALUE))
memory_debug_mode = 1;
- if (opt.debug & DBG_MEMSTAT_VALUE )
+ if ((opt.debug & DBG_MEMSTAT_VALUE))
memory_stat_debug_mode = 1;
- if (opt.debug & DBG_MPI_VALUE)
+ if (DBG_MPI)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
- if (opt.debug & DBG_CRYPTO_VALUE )
+ if (DBG_CRYPTO)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
- if (opt.debug & DBG_IOBUF_VALUE )
+ if ((opt.debug & DBG_IOBUF_VALUE))
iobuf_debug_mode = 1;
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
@@ -2008,7 +2016,7 @@ parse_tofu_policy (const char *policystr)
if (!ascii_strcasecmp (policystr, "help"))
{
- log_info (_("available TOFU policies:\n"));
+ log_info (_("valid values for option '%s':\n"), "--tofu-policy");
for (i=0; i < DIM (list); i++)
log_info (" %s\n", list[i].keyword);
g10_exit (1);
@@ -2025,6 +2033,113 @@ parse_tofu_policy (const char *policystr)
g10_exit (1);
}
+
+/* Parse the value of --compliance. */
+static int
+parse_compliance_option (const char *string)
+{
+ struct { const char *keyword; enum cmd_and_opt_values option; } list[] = {
+ { "gnupg", oGnuPG },
+ { "openpgp", oOpenPGP },
+ { "rfc4880bis", oRFC4880bis },
+ { "rfc4880", oRFC4880 },
+ { "rfc2440", oRFC2440 },
+ { "pgp6", oPGP6 },
+ { "pgp7", oPGP7 },
+ { "pgp8", oPGP8 },
+ { "de-vs", oDE_VS }
+ };
+ int i;
+
+ if (!ascii_strcasecmp (string, "help"))
+ {
+ log_info (_("valid values for option '%s':\n"), "--compliance");
+ 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 (string, list[i].keyword))
+ return list[i].option;
+
+ log_error (_("invalid value for option '%s'\n"), "--compliance");
+ if (!opt.quiet)
+ log_info (_("(use \"help\" to list choices)\n"));
+ g10_exit (1);
+}
+
+
+
+/* Helper to set compliance related options. This is a separte
+ * function so that it can also be used by the --compliance option
+ * parser. */
+static void
+set_compliance_option (enum cmd_and_opt_values option)
+{
+ switch (option)
+ {
+ case oRFC4880bis:
+ opt.flags.rfc4880bis = 1;
+ /* fall through. */
+ case oOpenPGP:
+ case oRFC4880:
+ /* This is effectively the same as RFC2440, but with
+ "--enable-dsa2 --no-rfc2440-text --escape-from-lines
+ --require-cross-certification". */
+ opt.compliance = CO_RFC4880;
+ opt.flags.dsa2 = 1;
+ opt.flags.require_cross_cert = 1;
+ opt.rfc2440_text = 0;
+ opt.allow_non_selfsigned_uid = 1;
+ opt.allow_freeform_uid = 1;
+ opt.escape_from = 1;
+ opt.not_dash_escaped = 0;
+ opt.def_cipher_algo = 0;
+ opt.def_digest_algo = 0;
+ opt.cert_digest_algo = 0;
+ opt.compress_algo = -1;
+ opt.s2k_mode = 3; /* iterated+salted */
+ opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+ opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+ break;
+ case oRFC2440:
+ opt.compliance = CO_RFC2440;
+ opt.flags.dsa2 = 0;
+ opt.rfc2440_text = 1;
+ opt.allow_non_selfsigned_uid = 1;
+ opt.allow_freeform_uid = 1;
+ opt.escape_from = 0;
+ opt.not_dash_escaped = 0;
+ opt.def_cipher_algo = 0;
+ opt.def_digest_algo = 0;
+ opt.cert_digest_algo = 0;
+ opt.compress_algo = -1;
+ opt.s2k_mode = 3; /* iterated+salted */
+ 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;
+
+ case oDE_VS:
+ set_compliance_option (oOpenPGP);
+ opt.compliance = CO_DE_VS;
+ /* Fixme: Change other options. */
+ break;
+
+ default:
+ BUG ();
+ }
+}
+
+
+
+
+
+
/* This function called to initialized a new control object. It is
assumed that this object has been zeroed out before calling this
function. */
@@ -2150,6 +2265,7 @@ main (int argc, char **argv)
int eyes_only=0;
int multifile=0;
int pwfd = -1;
+ int ovrseskeyfd = -1;
int fpr_maybe_cmd = 0; /* --fingerprint maybe a command. */
int any_explicit_recipient = 0;
int require_secmem = 0;
@@ -2315,7 +2431,7 @@ main (int argc, char **argv)
malloc_hooks.free = gcry_free;
assuan_set_malloc_hooks (&malloc_hooks);
assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
- setup_libassuan_logging (&opt.debug);
+ setup_libassuan_logging (&opt.debug, NULL);
/* Try for a version specific config file first */
default_configname = get_default_configname ();
@@ -2375,11 +2491,16 @@ main (int argc, char **argv)
{
switch( pargs.r_opt )
{
- case aCheckKeys:
case aListConfig:
case aListGcryptConfig:
case aGPGConfList:
case aGPGConfTest:
+ set_cmd (&cmd, pargs.r_opt);
+ /* Do not register a keyring for these commands. */
+ default_keyring = -1;
+ break;
+
+ case aCheckKeys:
case aListPackets:
case aImport:
case aFastImport:
@@ -2650,6 +2771,8 @@ main (int argc, char **argv)
case oHomedir: break;
case oNoBatch: opt.batch = 0; break;
+ case oWithTofuInfo: opt.with_tofu_info = 1; break;
+
case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/
case oWithColons: opt.with_colons=':'; break;
@@ -2693,52 +2816,24 @@ main (int argc, char **argv)
/* Dummy so that gpg 1.4 conf files can work. Should
eventually be removed. */
break;
+
+ case oCompliance:
+ set_compliance_option (parse_compliance_option (pargs.r.ret_str));
+ break;
+ case oOpenPGP:
+ case oRFC2440:
+ case oRFC4880:
case oRFC4880bis:
- opt.flags.rfc4880bis = 1;
- /* fall thru. */
- case oOpenPGP:
- case oRFC4880:
- /* This is effectively the same as RFC2440, but with
- "--enable-dsa2 --no-rfc2440-text --escape-from-lines
- --require-cross-certification". */
- opt.compliance = CO_RFC4880;
- opt.flags.dsa2 = 1;
- opt.flags.require_cross_cert = 1;
- opt.rfc2440_text = 0;
- opt.allow_non_selfsigned_uid = 1;
- opt.allow_freeform_uid = 1;
- opt.escape_from = 1;
- opt.not_dash_escaped = 0;
- opt.def_cipher_algo = 0;
- opt.def_digest_algo = 0;
- opt.cert_digest_algo = 0;
- opt.compress_algo = -1;
- opt.s2k_mode = 3; /* iterated+salted */
- opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
- opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
- break;
- case oRFC2440:
- opt.compliance = CO_RFC2440;
- opt.flags.dsa2 = 0;
- opt.rfc2440_text = 1;
- opt.allow_non_selfsigned_uid = 1;
- opt.allow_freeform_uid = 1;
- opt.escape_from = 0;
- opt.not_dash_escaped = 0;
- opt.def_cipher_algo = 0;
- opt.def_digest_algo = 0;
- opt.cert_digest_algo = 0;
- opt.compress_algo = -1;
- opt.s2k_mode = 3; /* iterated+salted */
- 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;
- case oRFC2440Text: opt.rfc2440_text=1; break;
- case oNoRFC2440Text: opt.rfc2440_text=0; break;
+ case oPGP6:
+ case oPGP7:
+ case oPGP8:
+ case oGnuPG:
+ set_compliance_option (pargs.r_opt);
+ break;
+
+ case oRFC2440Text: opt.rfc2440_text=1; break;
+ case oNoRFC2440Text: opt.rfc2440_text=0; break;
+
case oSetFilename:
if(utf8_strings)
opt.set_filename = pargs.r.ret_str;
@@ -3198,6 +3293,9 @@ main (int argc, char **argv)
case oOverrideSessionKey:
opt.override_session_key = pargs.r.ret_str;
break;
+ case oOverrideSessionKeyFD:
+ ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
+ break;
case oMergeOnly:
deprecated_warning(configname,configlineno,"--merge-only",
"--import-options ","merge-only");
@@ -3765,8 +3863,11 @@ main (int argc, char **argv)
g10_exit(0);
- if( pwfd != -1 ) /* Read the passphrase now. */
- read_passphrase_from_fd( pwfd );
+ if (pwfd != -1) /* Read the passphrase now. */
+ read_passphrase_from_fd (pwfd);
+
+ if (ovrseskeyfd != -1 ) /* Read the sessionkey now. */
+ read_sessionkey_from_fd (ovrseskeyfd);
fname = argc? *argv : NULL;
@@ -3785,6 +3886,8 @@ main (int argc, char **argv)
case aGenRandom:
case aDeArmor:
case aEnArmor:
+ case aListConfig:
+ case aListGcryptConfig:
break;
case aFixTrustDB:
case aExportOwnerTrust:
@@ -4660,6 +4763,8 @@ main (int argc, char **argv)
if (! hd)
g10_exit (1);
+ tofu_begin_batch_update (ctrl);
+
for (i = 1; i < argc; i ++)
{
KEYDB_SEARCH_DESC desc;
@@ -4717,8 +4822,9 @@ main (int argc, char **argv)
g10_exit (1);
}
- keydb_release (hd);
+ tofu_end_batch_update (ctrl);
+ keydb_release (hd);
}
#endif /*USE_TOFU*/
break;
@@ -5116,3 +5222,34 @@ add_keyserver_url( const char *string, int which )
if(critical)
sl->flags |= 1;
}
+
+
+static void
+read_sessionkey_from_fd (int fd)
+{
+ int i, len;
+ char *line;
+
+ for (line = NULL, i = len = 100; ; i++ )
+ {
+ if (i >= len-1 )
+ {
+ char *tmp = line;
+ len += 100;
+ line = xmalloc_secure (len);
+ if (tmp)
+ {
+ memcpy (line, tmp, i);
+ xfree (tmp);
+ }
+ else
+ i=0;
+ }
+ if (read (fd, line + i, 1) != 1 || line[i] == '\n')
+ break;
+ }
+ line[i] = 0;
+ log_debug ("seskey: %s\n", line);
+ gpgrt_annotate_leaked_object (line);
+ opt.override_session_key = line;
+}