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 222045d850
commit ce75af47eb
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 88 additions and 18 deletions

View File

@ -779,7 +779,9 @@ the fingerprint @var{fpr}. @var{adskfpr} is the fingerprint of
another key's encryption subkey. A subkey is commonly used here another key's encryption subkey. A subkey is commonly used here
because by default a primary key has no encryption capability. Use because by default a primary key has no encryption capability. Use
the option @option{--with-subkey-fingerprint} with a list command to 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 @item --generate-key
@opindex generate-key @opindex generate-key

View File

@ -4574,3 +4574,30 @@ have_secret_key_with_kid (ctrl_t ctrl, u32 *keyid)
keydb_release (kdbhd); keydb_release (kdbhd);
return result; 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

@ -485,6 +485,10 @@ int parse_auto_key_locate(const char *options);
int parse_key_origin (char *string); int parse_key_origin (char *string);
const char *key_origin_string (int origin); 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 --*/ /*-- keyid.c --*/
int pubkey_letter( int algo ); int pubkey_letter( int algo );
char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize); char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize);

View File

@ -3388,7 +3388,15 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr)
/* Locate and add the ADSK. Note that the called function already /* Locate and add the ADSK. Note that the called function already
* prints error messages. */ * 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; modified = 1;
else else
log_inc_errorcount (); /* (We use log_info in menu_adsk) */ log_inc_errorcount (); /* (We use log_info in menu_adsk) */
@ -4970,7 +4978,6 @@ append_adsk_to_key (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *adsk)
} }
/* /*
* Ask for a new additional decryption subkey and add it to the key * Ask for a new additional decryption subkey and add it to the key
* block. Returns true if the keyblock was changed and false * block. Returns true if the keyblock was changed and false
@ -4988,7 +4995,7 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr)
KEYDB_SEARCH_DESC desc; KEYDB_SEARCH_DESC desc;
byte fpr[MAX_FINGERPRINT_LEN]; byte fpr[MAX_FINGERPRINT_LEN];
size_t fprlen; size_t fprlen;
kbnode_t node, node2; kbnode_t node;
log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY); log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
@ -5072,22 +5079,10 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr)
} }
/* Check that the selected subkey is not yet on our keyblock. */ /* Check that the selected subkey is not yet on our keyblock. */
for (node2 = pub_keyblock; node2; node2 = node2->next) err = has_key_with_fingerprint (pub_keyblock, desc.u.fpr, desc.fprlen);
{ if (err)
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 == desc.fprlen
&& !memcmp (fpr, desc.u.fpr, fprlen))
break;
}
}
if (node2)
{ {
log_info (_("key \"%s\" is already on this keyblock\n"), answer); log_info (_("key \"%s\" is already on this keyblock\n"), answer);
err = gpg_error (GPG_ERR_DUP_KEY);
if (adskfpr) if (adskfpr)
goto leave; goto leave;
continue; continue;

View File

@ -161,6 +161,8 @@ static int mdc_available;
static int ks_modify; static int ks_modify;
static int aead_available; 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, static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
const char *algostr, const char *usagestr, const char *algostr, const char *usagestr,
const char *expirestr, const char *expirestr,
@ -1141,6 +1143,45 @@ keygen_prepare_new_key_adsks (void)
} }
/* 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 /* 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 PSK. REVKEY is describes the direct key signature and TIMESTAMP is
the timestamp to set on the signature. */ the timestamp to set on the signature. */

View File

@ -328,6 +328,7 @@ gpg_error_t make_backsig (ctrl_t ctrl,
PKT_public_key *sub_pk, PKT_public_key *sub_psk, PKT_public_key *sub_pk, PKT_public_key *sub_psk,
u32 timestamp, const char *cache_nonce); u32 timestamp, const char *cache_nonce);
void keygen_prepare_new_key_adsks (void); void keygen_prepare_new_key_adsks (void);
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, gpg_error_t generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock,
const char *algostr, const char *algostr,
const char *usagestr, const char *usagestr,