1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: Add magic parameter "default" to --quick-add-adsk.

* g10/getkey.c (has_key_with_fingerprint): New.
* g10/keyedit.c (menu_addadsk): Replace code by new function.
(keyedit_quick_addadsk): Handle magic arg "default".
* g10/keygen.c (append_all_default_adsks): New.
--

GnuPG-bug-id: 6882
(cherry picked from commit 77afc9ee1c75a28083edf6d98888f9b472c3e39d)
This commit is contained in:
Werner Koch 2024-06-05 17:04:33 +02:00
parent 45ae027ce4
commit ecda4b1e16
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 117 additions and 17 deletions

View File

@ -772,7 +772,9 @@ the fingerprint @var{fpr}. @var{adskfpr} is the fingerprint of
another key's encryption subkey. A subkey is commonly used here
because by default a primary key has no encryption capability. Use
the option @option{--with-subkey-fingerprint} with a list command to
display the subkey fingerprints.
display the subkey fingerprints. If the string "default" is used for
@var{adskfpr} all missing ADSKs configured with
@option{--default-new-key-adsk} are added.
@item --generate-key
@opindex generate-key

View File

@ -4603,3 +4603,30 @@ have_secret_key_with_kid (u32 *keyid)
keydb_release (kdbhd);
return result;
}
/* Return an error if KEYBLOCK has a primary or subkey with the given
* fingerprint (FPR,FPRLEN). */
gpg_error_t
has_key_with_fingerprint (kbnode_t keyblock, const byte *fpr, size_t fprlen)
{
kbnode_t node;
PKT_public_key *pk;
byte pkfpr[MAX_FINGERPRINT_LEN];
size_t pkfprlen;
for (node = keyblock; node; node = node->next)
{
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| node->pkt->pkttype == PKT_SECRET_KEY
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
{
pk = node->pkt->pkt.public_key;
fingerprint_from_pk (pk, pkfpr, &pkfprlen);
if (pkfprlen == fprlen && !memcmp (pkfpr, fpr, fprlen))
return gpg_error (GPG_ERR_DUP_KEY);
}
}
return 0;
}

View File

@ -472,6 +472,10 @@ int parse_auto_key_locate(const char *options);
int parse_key_origin (char *string);
const char *key_origin_string (int origin);
/* Return an error if KEYBLOCK has a primary or subkey with the fpr. */
gpg_error_t has_key_with_fingerprint (kbnode_t keyblock,
const byte *fpr, size_t fprlen);
/*-- keyid.c --*/
int pubkey_letter( int algo );
char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize);

View File

@ -3253,7 +3253,15 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr)
/* Locate and add the ADSK. Note that the called function already
* prints error messages. */
if (menu_addadsk (ctrl, keyblock, adskfpr))
if (adskfpr && !ascii_strcasecmp (adskfpr, "default"))
{
err = append_all_default_adsks (ctrl, keyblock);
if (!err)
modified = 1;
else if (gpg_err_code (err) == GPG_ERR_FALSE)
err = 0;
}
else if (menu_addadsk (ctrl, keyblock, adskfpr))
modified = 1;
else
log_inc_errorcount (); /* (We use log_info in menu_adsk) */
@ -4810,7 +4818,7 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr)
KEYDB_SEARCH_DESC desc;
byte fpr[MAX_FINGERPRINT_LEN];
size_t fprlen;
kbnode_t node, node2;
kbnode_t node;
log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
@ -4895,22 +4903,10 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr)
}
/* Check that the selected subkey is not yet on our keyblock. */
for (node2 = pub_keyblock; node2; node2 = node2->next)
{
if (node2->pkt->pkttype == PKT_PUBLIC_KEY
|| node2->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
pk = node2->pkt->pkt.public_key;
fingerprint_from_pk (pk, fpr, &fprlen);
if (fprlen == 20
&& !memcmp (fpr, desc.u.fpr, 20))
break;
}
}
if (node2)
err = has_key_with_fingerprint (pub_keyblock, desc.u.fpr, 20);
if (err)
{
log_info (_("key \"%s\" is already on this keyblock\n"), answer);
err = gpg_error (GPG_ERR_DUP_KEY);
if (adskfpr)
goto leave;
continue;

View File

@ -142,6 +142,8 @@ static int mdc_available,ks_modify;
static int aead_available;
static void release_parameter_list (struct para_data_s *r);
static struct para_data_s *prepare_adsk (ctrl_t ctrl, const char *name);
static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
const char *algostr, const char *usagestr,
const char *expirestr,
@ -1087,6 +1089,74 @@ make_backsig (ctrl_t ctrl, PKT_signature *sig, PKT_public_key *pk,
}
/* This function should be called to make sure that
* opt.def_new_key_adsks has no duplicates and that tehre is no '!'
* suffix. We don't do this during normal option processing because
* this list is only needed for a very few operations. Callingit
* twice does not harm. Users of the option list should skip empty
* items. */
static void
keygen_prepare_new_key_adsks (void)
{
strlist_t sl, slr;
char *p;
for (sl = opt.def_new_key_adsks; sl; sl = sl->next)
{
if (!*sl->d)
continue;
p = strchr (sl->d, '!');
if (p)
*p = 0;
for (slr = opt.def_new_key_adsks; slr != sl; slr = slr->next)
if (!ascii_strcasecmp (sl->d, slr->d))
{
*sl->d = 0; /* clear fpr to mark this as a duplicate. */
break;
}
}
}
/* Append all default ADSKs to the KEYBLOCK but ignore those which are
* already on that keyblock. Returns 0 if any key has been added;
* GPG_ERR_FALSE if no key was added or any other error code. */
gpg_error_t
append_all_default_adsks (ctrl_t ctrl, kbnode_t keyblock)
{
gpg_error_t err = 0;
int any_done = 0;
strlist_t sl;
struct para_data_s *para;
byte adskfpr[MAX_FINGERPRINT_LEN];
size_t adskfprlen;
keygen_prepare_new_key_adsks ();
for (sl = opt.def_new_key_adsks; sl && !err; sl = sl->next)
{
if (!*sl->d)
continue;
para = prepare_adsk (ctrl, sl->d);
if (para)
{
fingerprint_from_pk (para->u.adsk, adskfpr, &adskfprlen);
if (!has_key_with_fingerprint (keyblock, adskfpr, adskfprlen))
{
err = append_adsk_to_key (ctrl, keyblock, para->u.adsk);
if (!err)
any_done = 1;
}
release_parameter_list (para);
}
}
if (!err && !any_done)
err = gpg_error (GPG_ERR_FALSE);
return err;
}
/* Write a direct key signature to the first key in ROOT using the key
PSK. REVKEY is describes the direct key signature and TIMESTAMP is
the timestamp to set on the signature. */

View File

@ -320,6 +320,7 @@ gpg_error_t make_backsig (ctrl_t ctrl,
PKT_signature *sig, PKT_public_key *pk,
PKT_public_key *sub_pk, PKT_public_key *sub_psk,
u32 timestamp, const char *cache_nonce);
gpg_error_t append_all_default_adsks (ctrl_t ctrl, kbnode_t pub_root);
gpg_error_t generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock,
const char *algostr,
const char *usagestr,