1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-28 21:50:02 +02:00

gpg: New option --add-desig-revoker

* g10/gpg.c (oAddDesigRevoker): New.
(opts): Add new option.
* g10/options.h (opt): Add field desig_revokers.
* g10/keygen.c (get_parameter_idx): New.
(get_parameter): Make use of get_parameter_idx.
(prepare_desig_revoker): New.
(get_parameter_revkey): Add arg idx.
(proc_parameter_file): Add designated revokers.
(do_generate_keypair): Write all designated revokers.
--

(cherry picked from commit 3d094e2bcf)

Support for v5 desig revokers has been removed.  However, we should
check whether we can add a longer v4 desig revoker fingerprint in
addition to the regular v4 desig revoker.
This commit is contained in:
Werner Koch 2023-02-16 18:09:22 +01:00
parent 8c8608425a
commit 6c9db01101
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 130 additions and 16 deletions

2
NEWS
View File

@ -22,6 +22,8 @@ Noteworthy changes in version 2.2.42 (unreleased)
* gpg: Detect already compressed data also when using a pipe. Also
detect JPEG and PNG file formats. [T6332]
* gpg: New option --add-desig-revoker.
* gpgsm: Support ECC certificates. [T6253]
* gpgsm: Print PROGRESS status lines. Add new --input-size-hint.

View File

@ -1713,6 +1713,19 @@ recipient's or signator's key. If the given key is not locally
available but an LDAP keyserver is configured the missing key is
imported from that server.
@item --add-desig-revoker [sensitive:]@var{fingerprint}
@opindex add-desig-revoker
Add the key specified by @var{fingerprint} as a designated revoker to
newly created keys. If the fingerprint is prefixed with the keyword
``sensitive:'' that info is normally not exported wit the key. This
option may be given several time to add more than one designated
revoker. If the keyword ``clear'' is used instead of a fingerprint,
all designated options previously encountered are discarded.
Designated revokers are marked on the key as non-revocable. Note that
a designated revoker specified using a parameter file will also be
added to the key.
@item --trust-model @{pgp|classic|tofu|tofu+pgp|direct|always|auto@}
@opindex trust-model
Set what trust model GnuPG should follow. The models are:

View File

@ -437,7 +437,7 @@ enum cmd_and_opt_values
oForbidGenKey,
oRequireCompliance,
oCompatibilityFlags,
oKbxBufferSize,
oAddDesigRevoker,
oNoop
};
@ -693,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")),
@ -910,7 +911,6 @@ static ARGPARSE_OPTS opts[] = {
/* Esoteric compatibility options. */
ARGPARSE_s_n (oRFC2440Text, "rfc2440-text", "@"),
ARGPARSE_s_n (oNoRFC2440Text, "no-rfc2440-text", "@"),
ARGPARSE_p_u (oKbxBufferSize, "kbx-buffer-size", "@"),
ARGPARSE_header (NULL, ""), /* Stop the header group. */
@ -3655,9 +3655,12 @@ main (int argc, char **argv)
opt.flags.require_compliance = 1;
break;
case oKbxBufferSize:
keybox_set_buffersize (pargs.r.ret_ulong, 0);
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;

View File

@ -3671,14 +3671,29 @@ release_parameter_list (struct para_data_s *r)
}
}
/* Return the N-th parameter of name KEY from PARA. An IDX of 0
* returns the first and so on. */
static struct para_data_s *
get_parameter( struct para_data_s *para, enum para_name key )
get_parameter_idx (struct para_data_s *para, enum para_name key,
unsigned int idx)
{
struct para_data_s *r;
struct para_data_s *r;
for( r = para; r && r->key != key; r = r->next )
;
return r;
for(r = para; r; r = r->next)
if (r->key == key)
{
if (!idx)
return r;
idx--;
}
return NULL;
}
/* Return the first parameter of name KEY from PARA. */
static struct para_data_s *
get_parameter (struct para_data_s *para, enum para_name key)
{
return get_parameter_idx (para, key, 0);
}
static const char *
@ -3826,6 +3841,68 @@ parse_parameter_usage (const char *fname,
}
/* Parse the revocation key specified by NAME, check that the public
* key exists (so that we can get the required public key algorithm),
* and return a parameter wit the revocation key information. On
* error print a diagnostic and return NULL. */
static struct para_data_s *
prepare_desig_revoker (ctrl_t ctrl, const char *name)
{
gpg_error_t err;
struct para_data_s *para = NULL;
KEYDB_SEARCH_DESC desc;
int sensitive = 0;
struct revocation_key revkey;
PKT_public_key *revoker_pk = NULL;
size_t fprlen;
if (!ascii_strncasecmp (name, "sensitive:", 10) && !spacep (name+10))
{
name += 10;
sensitive = 1;
}
if (classify_user_id (name, &desc, 1)
|| desc.mode != KEYDB_SEARCH_MODE_FPR)
{
log_info (_("\"%s\" is not a fingerprint\n"), name);
err = gpg_error (GPG_ERR_INV_NAME);
goto leave;
}
revoker_pk = xcalloc (1, sizeof *revoker_pk);
revoker_pk->req_usage = PUBKEY_USAGE_CERT;
err = get_pubkey_byname (ctrl, GET_PUBKEY_NO_AKL,
NULL, revoker_pk, name, NULL, NULL, 1);
if (err)
goto leave;
fingerprint_from_pk (revoker_pk, revkey.fpr, &fprlen);
if (fprlen != 20)
{
log_info (_("cannot appoint a PGP 2.x style key as a "
"designated revoker\n"));
err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
goto leave;
}
revkey.class = 0x80;
if (sensitive)
revkey.class |= 0x40;
revkey.algid = revoker_pk->pubkey_algo;
para = xcalloc (1, sizeof *para);
para->key = pREVOKER;
memcpy (&para->u.revkey, &revkey, sizeof revkey);
leave:
if (err)
log_error ("invalid revocation key '%s': %s\n", name, gpg_strerror (err));
free_public_key (revoker_pk);
return para;
}
/* Parse a pREVOKER parameter into its dedicated parts. */
static int
parse_revocation_key (const char *fname,
struct para_data_s *para, enum para_name key)
@ -3904,10 +3981,11 @@ get_parameter_uint( struct para_data_s *para, enum para_name key )
}
static struct revocation_key *
get_parameter_revkey( struct para_data_s *para, enum para_name key )
get_parameter_revkey (struct para_data_s *para, enum para_name key,
unsigned int idx)
{
struct para_data_s *r = get_parameter( para, key );
return r? &r->u.revkey : NULL;
struct para_data_s *r = get_parameter_idx (para, key, idx);
return r? &r->u.revkey : NULL;
}
static int
@ -3918,6 +3996,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname,
const char *s1, *s2, *s3;
size_t n;
char *p;
strlist_t sl;
int is_default = 0;
int have_user_id = 0;
int err, algo;
@ -4063,10 +4142,20 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname,
}
}
/* Set revoker, if any. */
/* Set revoker from parameter file, if any. Must be done first so
* that we don't find a parameter set via prepare_desig_revoker. */
if (parse_revocation_key (fname, para, pREVOKER))
return -1;
/* Check and append revokers from the config file. */
for (sl = opt.desig_revokers; sl; sl = sl->next)
{
r = prepare_desig_revoker (ctrl, sl->d);
if (!r)
return -1;
append_to_parameter (para, r);
}
/* Make KEYCREATIONDATE from Creation-Date. */
r = get_parameter (para, pCREATIONDATE);
@ -5104,6 +5193,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
int algo;
u32 expire;
const char *key_from_hexgrip = NULL;
unsigned int idx;
if (outctrl->dryrun)
{
@ -5205,7 +5295,10 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
keyid_copy (pri_psk->main_keyid, pri_psk->keyid);
}
if (!err && (revkey = get_parameter_revkey (para, pREVOKER)))
/* Write all signatures specifying designated revokers. */
for (idx=0;
!err && (revkey = get_parameter_revkey (para, pREVOKER, idx));
idx++)
err = write_direct_sig (ctrl, pub_root, pri_psk,
revkey, timestamp, cache_nonce);

View File

@ -105,6 +105,9 @@ struct
* the option --sender. */
strlist_t sender_list;
/* A list of fingerprints added as designated revokers to new keys. */
strlist_t desig_revokers;
int def_cert_level;
int min_cert_level;
int ask_cert_level;

View File

@ -59,7 +59,7 @@ register_trusted_key (const char *string)
/* Some users have conf files with entries like
* trusted-key 0x1234567812345678 # foo
* That is obviously wrong. Before fixing bug#1206 trailing garbage
* on a key specification if was ignored. We detect the above use case
* on a key specification was ignored. We detect the above use case
* here and cut off the junk-looking-like-a comment. */
if (strchr (string, '#'))
{