gpgsm: Add --always-trust feature.

* sm/gpgsm.h (opt): Re-purpose unused flag always_trust.
(struct server_control_s): Add "always_trust".
(VALIDATE_FLAG_BYPASS): New.
* sm/gpgsm.c (oAlwaysTrust): New.
(opts): Add "--always-trust"
(main): Set option.
* sm/server.c (option_handler): Add option "always-trust".
(reset_notify): Clear that option.
(cmd_encrypt): Ditto.
(cmd_getinfo): Add sub-command always-trust.
* sm/certchain.c (gpgsm_validate_chain): Handle VALIDATE_FLAG_BYPASS.
* sm/certlist.c (gpgsm_add_to_certlist): Set that flag for recipients
in always-trust mode.
--

GnuPG-bug-id: 6559
This commit is contained in:
Werner Koch 2023-08-31 11:13:38 +02:00
parent ee27ac18ea
commit 776876ce1c
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 79 additions and 7 deletions

View File

@ -732,6 +732,13 @@ instead to make sure that the gpgsm process exits with a failure if
the compliance rules are not fulfilled. Note that this option has
currently an effect only in "de-vs" mode.
@item --always-trust
@opindex always-trust
Force encryption to the specified certificates without any validation
of the certificate chain. The only requirement is that the
certificate is capable of encryption. Note that this option is
ineffective if @option{--require-compliance} is used.
@item --ignore-cert-with-oid @var{oid}
@opindex ignore-cert-with-oid
Add @var{oid} to the list of OIDs to be checked while reading
@ -1622,6 +1629,10 @@ The leading two dashes usually used with @var{opt} shall not be given.
Return OK if the connection is in offline mode. This may be either
due to a @code{OPTION offline=1} or due to @command{gpgsm} being
started with option @option{--disable-dirmngr}.
@item always-trust
Returns OK of the connection is in always-trust mode. That is either
@option{--always-trust} or @option{GPGSM OPTION always-trust} are
active.
@end table
@node GPGSM OPTION
@ -1728,6 +1739,15 @@ If @var{value} is true or @var{value} is not given all network access
is disabled for this session. This is the same as the command line
option @option{--disable-dirmngr}.
@item always-trust
If @var{value} is true or @var{value} is not given encryption to the
specified certificates is forced without any validation of the
certificate chain. The only requirement is that the certificates are
capable of encryption. If set to false the standard behaviour is
re-established. This option is cleared by a RESET and after each
encrypt operation. Note that this option is ignored if
@option{--always-trust} or @option{--require-compliance} are used.
@item input-size-hint
This is the same as the @option{--input-size-hint} command line option.

View File

@ -2199,9 +2199,15 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
memset (&rootca_flags, 0, sizeof rootca_flags);
rc = do_validate_chain (ctrl, cert, checktime,
r_exptime, listmode, listfp, flags,
&rootca_flags);
if ((flags & VALIDATE_FLAG_BYPASS))
{
*retflags |= VALIDATE_FLAG_BYPASS;
rc = 0;
}
else
rc = do_validate_chain (ctrl, cert, checktime,
r_exptime, listmode, listfp, flags,
&rootca_flags);
if (!rc && (flags & VALIDATE_FLAG_STEED))
{
*retflags |= VALIDATE_FLAG_STEED;
@ -2223,6 +2229,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
if (opt.verbose)
do_list (0, listmode, listfp, _("validation model used: %s"),
(*retflags & VALIDATE_FLAG_BYPASS)?
"bypass" :
(*retflags & VALIDATE_FLAG_STEED)?
"steed" :
(*retflags & VALIDATE_FLAG_CHAIN_MODEL)?

View File

@ -448,6 +448,11 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
if (!rc && !is_cert_in_certlist (cert, *listaddr))
{
unsigned int valflags = 0;
if (!secret && (opt.always_trust || ctrl->always_trust))
valflags |= VALIDATE_FLAG_BYPASS;
if (!rc && secret)
{
char *p;
@ -461,9 +466,10 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
xfree (p);
}
}
if (!rc)
rc = gpgsm_validate_chain (ctrl, cert, GNUPG_ISOTIME_NONE, NULL,
0, NULL, 0, NULL);
0, NULL, valflags, NULL);
if (!rc)
{
certlist_t cl = xtrycalloc (1, sizeof *cl);

View File

@ -215,6 +215,7 @@ enum cmd_and_opt_values {
oRequireCompliance,
oCompatibilityFlags,
oKbxBufferSize,
oAlwaysTrust,
oNoAutostart
};
@ -417,6 +418,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
ARGPARSE_s_n (oNoRandomSeedFile, "no-random-seed-file", "@"),
ARGPARSE_s_n (oRequireCompliance, "require-compliance", "@"),
ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"),
ARGPARSE_header (NULL, N_("Options for unattended use")),
@ -1499,6 +1501,7 @@ main ( int argc, char **argv)
case oMinRSALength: opt.min_rsa_length = pargs.r.ret_ulong; break;
case oRequireCompliance: opt.require_compliance = 1; break;
case oAlwaysTrust: opt.always_trust = 1; break;
case oKbxBufferSize:
keybox_set_buffersize (pargs.r.ret_ulong, 0);
@ -1588,10 +1591,20 @@ main ( int argc, char **argv)
if (may_coredump && !opt.quiet)
log_info (_("WARNING: program may create a core file!\n"));
if (opt.require_compliance && opt.always_trust)
{
opt.always_trust = 0;
if (opt.quiet)
log_info (_("WARNING: %s overrides %s\n"),
"--require-compliance","--always-trust");
}
npth_init ();
assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
/* if (opt.qualsig_approval && !opt.quiet) */
/* log_info (_("This software has officially been approved to " */
/* "create and verify\n" */

View File

@ -116,8 +116,6 @@ struct
int extra_digest_algo; /* A digest algorithm also used for
verification of signatures. */
int always_trust; /* Trust the given keys even if there is no
valid certification chain */
int skip_verify; /* do not check signatures on data */
int lock_once; /* Keep lock once they are set */
@ -164,6 +162,10 @@ struct
* mode. */
int require_compliance;
/* Enable always-trust mode - note that there is also server option
* for this. */
int always_trust;
/* Enable creation of authenticode signatures. */
int authenticode;
@ -269,6 +271,9 @@ struct server_control_s
2 := STEED model. */
int offline; /* If true gpgsm won't do any network access. */
int always_trust; /* True in always-trust mode; see also
* opt.always-trust. */
/* The current time. Used as a helper in certchain.c. */
ksba_isotime_t current_time;
@ -388,6 +393,7 @@ int gpgsm_create_cms_signature (ctrl_t ctrl,
#define VALIDATE_FLAG_NO_DIRMNGR 1
#define VALIDATE_FLAG_CHAIN_MODEL 2
#define VALIDATE_FLAG_STEED 4
#define VALIDATE_FLAG_BYPASS 8 /* No actual validation. */
gpg_error_t gpgsm_walk_cert_chain (ctrl_t ctrl,
ksba_cert_t start, ksba_cert_t *r_next);

View File

@ -287,6 +287,17 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
ctrl->offline = i;
}
}
else if (!strcmp (key, "always-trust"))
{
/* We ignore this option if gpgsm has been started with
--always-trust (which also sets offline) and if
--require-compliance is active */
if (!opt.always_trust && !opt.require_compliance)
{
int i = *value? !!atoi (value) : 1;
ctrl->always_trust = i;
}
}
else if (!strcmp (key, "request-origin"))
{
if (!opt.request_origin)
@ -320,6 +331,7 @@ reset_notify (assuan_context_t ctx, char *line)
gpgsm_release_certlist (ctrl->server_local->signerlist);
ctrl->server_local->recplist = NULL;
ctrl->server_local->signerlist = NULL;
ctrl->always_trust = 0;
close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
@ -488,6 +500,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
gpgsm_release_certlist (ctrl->server_local->recplist);
ctrl->server_local->recplist = NULL;
ctrl->always_trust = 0;
/* Close and reset the fd */
close_message_fd (ctrl);
assuan_close_input_fd (ctx);
@ -1189,7 +1202,8 @@ static const char hlp_getinfo[] =
" agent-check - Return success if the agent is running.\n"
" cmd_has_option CMD OPT\n"
" - Returns OK if the command CMD implements the option OPT.\n"
" offline - Returns OK if the connection is in offline mode.";
" offline - Returns OK if the connection is in offline mode."
" always-trust- Returns OK if the connection is in always-trust mode.";
static gpg_error_t
cmd_getinfo (assuan_context_t ctx, char *line)
{
@ -1248,6 +1262,11 @@ cmd_getinfo (assuan_context_t ctx, char *line)
{
rc = ctrl->offline? 0 : gpg_error (GPG_ERR_FALSE);
}
else if (!strcmp (line, "always-trust"))
{
rc = (ctrl->always_trust || opt.always_trust)? 0
/**/ : gpg_error (GPG_ERR_FALSE);
}
else
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");