diff options
author | Werner Koch <wk@gnupg.org> | 2023-03-21 16:30:18 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2023-03-21 16:30:18 +0100 |
commit | 9f27e448bf1f825906f3c53e3428087d34bbd8fc (patch) | |
tree | d9df55b3cce7fe31401e9a22d13fa524b99a311b | |
parent | po: Fix German translation regarding the caching of PINs. (diff) | |
download | gnupg2-9f27e448bf1f825906f3c53e3428087d34bbd8fc.tar.xz gnupg2-9f27e448bf1f825906f3c53e3428087d34bbd8fc.zip |
gpg: New command --quick-add-adsk
* g10/gpg.c (enum cmd_and_opt_values): Add aQuickAddADSK.
(opts): Add --quick-add-adsk.
(main): Call the actual function.
* g10/keyedit.c (keyedit_quick_addadsk): New.
(menu_addadsk): Add arg adskfpr and change caller.
--
GnuPG-bug-id: 6395
-rw-r--r-- | doc/gpg.texi | 9 | ||||
-rw-r--r-- | g10/gpg.c | 15 | ||||
-rw-r--r-- | g10/keyedit.c | 109 | ||||
-rw-r--r-- | g10/keyedit.h | 1 |
4 files changed, 120 insertions, 14 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi index a6ab4d57d..7a4935fc6 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -770,6 +770,15 @@ specifying a value, or using ``-'' results in a key expiring in a reasonable default interval. The values ``never'', ``none'' can be used for no expiration date. +@item --quick-add-adsk @var{fpr} @var{adskfpr} +@opindex quick-add-adsk +Directly add an Additional Decryption Subkey to the key identified by +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. + @item --generate-key @opindex generate-key @itemx --gen-key @@ -130,6 +130,7 @@ enum cmd_and_opt_values aQuickRevSig, aQuickAddUid, aQuickAddKey, + aQuickAddADSK, aQuickRevUid, aQuickSetExpire, aQuickSetPrimaryUid, @@ -486,6 +487,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_c (aQuickAddUid, "quick-adduid", "@"), ARGPARSE_c (aQuickAddKey, "quick-add-key", "@"), ARGPARSE_c (aQuickAddKey, "quick-addkey", "@"), + ARGPARSE_c (aQuickAddADSK, "quick-add-adsk", "@"), ARGPARSE_c (aQuickRevUid, "quick-revoke-uid", N_("quickly revoke a user-id")), ARGPARSE_c (aQuickRevUid, "quick-revuid", "@"), @@ -2691,6 +2693,7 @@ main (int argc, char **argv) case aQuickKeygen: case aQuickAddUid: case aQuickAddKey: + case aQuickAddADSK: case aQuickRevUid: case aQuickSetExpire: case aQuickSetPrimaryUid: @@ -4302,6 +4305,7 @@ main (int argc, char **argv) case aQuickKeygen: case aQuickAddUid: case aQuickAddKey: + case aQuickAddADSK: case aQuickRevUid: case aQuickSetPrimaryUid: case aQuickUpdatePref: @@ -4769,6 +4773,17 @@ main (int argc, char **argv) } break; + case aQuickAddADSK: + { + if (argc != 2) + wrong_args ("--quick-add-adsk FINGERPRINT ADSK-FINGERPRINT"); + if (mopt.forbid_gen_key) + gen_key_forbidden (); + else + keyedit_quick_addadsk (ctrl, argv[0], argv[1]); + } + break; + case aQuickRevUid: { const char *uid, *uidtorev; diff --git a/g10/keyedit.c b/g10/keyedit.c index d21064a21..a91cc4447 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -73,7 +73,8 @@ static int menu_delsig (ctrl_t ctrl, kbnode_t pub_keyblock); static int menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only); static void menu_delkey (KBNODE pub_keyblock); static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive); -static int menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock); +static int menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, + const char *adskfpr); static gpg_error_t menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock, int unattended, u32 newexpiration); static int menu_changeusage (ctrl_t ctrl, kbnode_t keyblock); @@ -1310,7 +1311,7 @@ static struct { "addrevoker", cmdADDREVOKER, KEYEDIT_NEED_SK, N_("add a revocation key")}, { "addadsk", cmdADDADSK, KEYEDIT_NEED_SK, - N_("add additional decryption subkeys")}, + N_("add an additional decryption subkey")}, { "delsig", cmdDELSIG, 0, N_("delete signatures from the selected user IDs")}, { "expire", cmdEXPIRE, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK, @@ -2016,7 +2017,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, break; case cmdADDADSK: - if (menu_addadsk (ctrl, keyblock)) + if (menu_addadsk (ctrl, keyblock, NULL)) { redisplay = 1; modified = 1; @@ -3247,6 +3248,69 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, } +/* Unattended ADSK setup function. + * + * FPR is the fingerprint of our key. ADSKFPR is the fingerprint of + * another subkey which we want to add as ADSK to our key. + */ +void +keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) +{ + gpg_error_t err; + kbnode_t keyblock; + KEYDB_HANDLE kdbhd; + int modified = 0; + PKT_public_key *pk; + +#ifdef HAVE_W32_SYSTEM + /* See keyedit_menu for why we need this. */ + check_trustdb_stale (ctrl); +#endif + + /* We require a fingerprint because only this uniquely identifies a + * key and may thus be used to select a key for unattended adsk + * adding. */ + if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd)) + goto leave; + + if (fix_keyblock (ctrl, &keyblock)) + modified++; + + pk = keyblock->pkt->pkt.public_key; + if (pk->flags.revoked) + { + if (!opt.verbose) + show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); + log_error ("%s%s", _("Key is revoked."), "\n"); + goto leave; + } + + /* Locate and add the ADSK. Note that the called function already + * prints error messages. */ + if (menu_addadsk (ctrl, keyblock, adskfpr)) + modified = 1; + else + log_inc_errorcount (); /* (We use log_info in menu_adsk) */ + + es_fflush (es_stdout); + + /* Store. */ + if (modified) + { + err = keydb_update_keyblock (ctrl, kdbhd, keyblock); + if (err) + { + log_error (_("update failed: %s\n"), gpg_strerror (err)); + goto leave; + } + } + + leave: + release_kbnode (keyblock); + keydb_release (kdbhd); +} + + /* Unattended expiration setting function for the main key. If * SUBKEYFPRS is not NULL and SUBKEYSFPRS[0] is neither NULL, it is * expected to be an array of fingerprints for subkeys to change. It @@ -4691,11 +4755,12 @@ fail: /* * Ask for a new additional decryption subkey and add it to the key - * block. Returns true if the keybloxk was changed and false - * otherwise. + * block. Returns true if the keyblock was changed and false + * otherwise. If ADSKFPR is not NULL, this fucntion has been called + * by quick_addadsk and gives the fingerprint of the to be added key. */ static int -menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock) +menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr) { PKT_public_key *pk; PKT_public_key *sub_pk; @@ -4718,18 +4783,26 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock) for (;;) { xfree (answer); - answer = cpr_get_utf8 - ("keyedit.addadsk", - _("Enter the fingerprint of the additional decryption subkey: ")); - if (answer[0] == '\0' || answer[0] == CONTROL_D) + if (adskfpr) + answer = xstrdup (adskfpr); + else { - err = gpg_error (GPG_ERR_CANCELED); - goto leave; + answer = cpr_get_utf8 + ("keyedit.addadsk", + _("Enter the fingerprint of the additional decryption subkey: ")); + if (answer[0] == '\0' || answer[0] == CONTROL_D) + { + err = gpg_error (GPG_ERR_CANCELED); + goto leave; + } } if (classify_user_id (answer, &desc, 1) || desc.mode != KEYDB_SEARCH_MODE_FPR) { log_info (_("\"%s\" is not a fingerprint\n"), answer); + err = gpg_error (GPG_ERR_INV_USER_ID); + if (adskfpr) + goto leave; continue; } @@ -4744,8 +4817,11 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock) { log_info (_("key \"%s\" not found: %s\n"), answer, gpg_strerror (err)); - if (!opt.batch && gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) + if ((!opt.batch || adskfpr) && !opt.quiet + && gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) log_info (_("Did you specify the fingerprint of a subkey?\n")); + if (adskfpr) + goto leave; continue; } @@ -4767,8 +4843,10 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock) err = gpg_error (GPG_ERR_WRONG_KEY_USAGE); log_info (_("key \"%s\" not found: %s\n"), answer, gpg_strerror (err)); - if (!opt.batch) + if ((!opt.batch || adskfpr) && !opt.quiet) log_info (_("Did you specify the fingerprint of a subkey?\n")); + if (adskfpr) + goto leave; continue; } @@ -4788,6 +4866,9 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock) if (node2) { 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/keyedit.h b/g10/keyedit.h index ea4fd253c..3ed0d0fea 100644 --- a/g10/keyedit.h +++ b/g10/keyedit.h @@ -44,6 +44,7 @@ void keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid); void keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, const char *usagestr, const char *expirestr); +void keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr); void keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev); void keyedit_quick_sign (ctrl_t ctrl, const char *fpr, |