1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-02 12:01:32 +01: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 3d094e2bcf6c9ed2cd405623f2dbc6131d04366f)

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 * gpg: Detect already compressed data also when using a pipe. Also
detect JPEG and PNG file formats. [T6332] detect JPEG and PNG file formats. [T6332]
* gpg: New option --add-desig-revoker.
* gpgsm: Support ECC certificates. [T6253] * gpgsm: Support ECC certificates. [T6253]
* gpgsm: Print PROGRESS status lines. Add new --input-size-hint. * 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 available but an LDAP keyserver is configured the missing key is
imported from that server. 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@} @item --trust-model @{pgp|classic|tofu|tofu+pgp|direct|always|auto@}
@opindex trust-model @opindex trust-model
Set what trust model GnuPG should follow. The models are: Set what trust model GnuPG should follow. The models are:

View File

@ -437,7 +437,7 @@ enum cmd_and_opt_values
oForbidGenKey, oForbidGenKey,
oRequireCompliance, oRequireCompliance,
oCompatibilityFlags, oCompatibilityFlags,
oKbxBufferSize, oAddDesigRevoker,
oNoop oNoop
}; };
@ -693,6 +693,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"), ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"),
ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"), ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
#endif #endif
ARGPARSE_s_s (oAddDesigRevoker, "add-desig-revoker", "@"),
ARGPARSE_header ("Input", N_("Options controlling the input")), ARGPARSE_header ("Input", N_("Options controlling the input")),
@ -910,7 +911,6 @@ static ARGPARSE_OPTS opts[] = {
/* Esoteric compatibility options. */ /* Esoteric compatibility options. */
ARGPARSE_s_n (oRFC2440Text, "rfc2440-text", "@"), ARGPARSE_s_n (oRFC2440Text, "rfc2440-text", "@"),
ARGPARSE_s_n (oNoRFC2440Text, "no-rfc2440-text", "@"), ARGPARSE_s_n (oNoRFC2440Text, "no-rfc2440-text", "@"),
ARGPARSE_p_u (oKbxBufferSize, "kbx-buffer-size", "@"),
ARGPARSE_header (NULL, ""), /* Stop the header group. */ ARGPARSE_header (NULL, ""), /* Stop the header group. */
@ -3655,9 +3655,12 @@ main (int argc, char **argv)
opt.flags.require_compliance = 1; opt.flags.require_compliance = 1;
break; break;
case oKbxBufferSize: case oAddDesigRevoker:
keybox_set_buffersize (pargs.r.ret_ulong, 0); if (!strcmp (pargs.r.ret_str, "clear"))
break; FREE_STRLIST (opt.desig_revokers);
else
append_to_strlist (&opt.desig_revokers, pargs.r.ret_str);
break;
case oNoop: 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 * 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 ) for(r = para; r; r = r->next)
; if (r->key == key)
return r; {
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 * 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 static int
parse_revocation_key (const char *fname, parse_revocation_key (const char *fname,
struct para_data_s *para, enum para_name key) 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 * 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 ); struct para_data_s *r = get_parameter_idx (para, key, idx);
return r? &r->u.revkey : NULL; return r? &r->u.revkey : NULL;
} }
static int 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; const char *s1, *s2, *s3;
size_t n; size_t n;
char *p; char *p;
strlist_t sl;
int is_default = 0; int is_default = 0;
int have_user_id = 0; int have_user_id = 0;
int err, algo; 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)) if (parse_revocation_key (fname, para, pREVOKER))
return -1; 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. */ /* Make KEYCREATIONDATE from Creation-Date. */
r = get_parameter (para, pCREATIONDATE); r = get_parameter (para, pCREATIONDATE);
@ -5104,6 +5193,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
int algo; int algo;
u32 expire; u32 expire;
const char *key_from_hexgrip = NULL; const char *key_from_hexgrip = NULL;
unsigned int idx;
if (outctrl->dryrun) 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); 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, err = write_direct_sig (ctrl, pub_root, pri_psk,
revkey, timestamp, cache_nonce); revkey, timestamp, cache_nonce);

View File

@ -105,6 +105,9 @@ struct
* the option --sender. */ * the option --sender. */
strlist_t sender_list; strlist_t sender_list;
/* A list of fingerprints added as designated revokers to new keys. */
strlist_t desig_revokers;
int def_cert_level; int def_cert_level;
int min_cert_level; int min_cert_level;
int ask_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 /* Some users have conf files with entries like
* trusted-key 0x1234567812345678 # foo * trusted-key 0x1234567812345678 # foo
* That is obviously wrong. Before fixing bug#1206 trailing garbage * 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. */ * here and cut off the junk-looking-like-a comment. */
if (strchr (string, '#')) if (strchr (string, '#'))
{ {