diff options
author | Werner Koch <wk@gnupg.org> | 2024-06-05 17:04:33 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2024-06-05 17:04:33 +0200 |
commit | 77afc9ee1c75a28083edf6d98888f9b472c3e39d (patch) | |
tree | f1178f2db721cc404602110cf9227deaaa037a98 | |
parent | gpg: Do not show RENC if no key capabilities are found for a key. (diff) | |
download | gnupg2-77afc9ee1c75a28083edf6d98888f9b472c3e39d.tar.xz gnupg2-77afc9ee1c75a28083edf6d98888f9b472c3e39d.zip |
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
-rw-r--r-- | doc/gpg.texi | 4 | ||||
-rw-r--r-- | g10/getkey.c | 27 | ||||
-rw-r--r-- | g10/keydb.h | 4 | ||||
-rw-r--r-- | g10/keyedit.c | 29 | ||||
-rw-r--r-- | g10/keygen.c | 41 | ||||
-rw-r--r-- | g10/main.h | 1 |
6 files changed, 88 insertions, 18 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi index af87064e5..203f3339f 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -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 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 diff --git a/g10/getkey.c b/g10/getkey.c index 49ffe0adb..d97690a83 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -4588,3 +4588,30 @@ have_secret_key_with_kid (ctrl_t ctrl, 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; +} diff --git a/g10/keydb.h b/g10/keydb.h index 9cb63cf73..d96debeb7 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -485,6 +485,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); diff --git a/g10/keyedit.c b/g10/keyedit.c index 7a33c9ef3..0fb19645d 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3389,7 +3389,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) */ @@ -4971,7 +4979,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 * block. Returns true if the keyblock was changed and false @@ -4989,7 +4996,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); @@ -5073,22 +5080,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 == desc.fprlen - && !memcmp (fpr, desc.u.fpr, fprlen)) - break; - } - } - if (node2) + err = has_key_with_fingerprint (pub_keyblock, desc.u.fpr, desc.fprlen); + 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; diff --git a/g10/keygen.c b/g10/keygen.c index f512f640d..66fe681de 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -174,6 +174,8 @@ static int mdc_available; static int 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, @@ -1210,6 +1212,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 PSK. REVKEY is describes the direct key signature and TIMESTAMP is the timestamp to set on the signature. */ diff --git a/g10/main.h b/g10/main.h index 5a84acaba..1c93c96e6 100644 --- a/g10/main.h +++ b/g10/main.h @@ -328,6 +328,7 @@ gpg_error_t make_backsig (ctrl_t ctrl, PKT_public_key *sub_pk, PKT_public_key *sub_psk, u32 timestamp, const char *cache_nonce); 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, const char *algostr, const char *usagestr, |