aboutsummaryrefslogtreecommitdiffstats
path: root/g10/keyedit.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-06-03 16:52:06 +0000
committerWerner Koch <[email protected]>2024-06-03 16:52:06 +0000
commited118e2ed521d82c1be7765a0a19d5b4f19afe10 (patch)
tree61c2a3b3cdff0907f6b1546a6b74ba5f1bcf660d /g10/keyedit.c
parentcommon: New function tokenize_to_strlist. (diff)
downloadgnupg-ed118e2ed521d82c1be7765a0a19d5b4f19afe10.tar.gz
gnupg-ed118e2ed521d82c1be7765a0a19d5b4f19afe10.zip
gpg: New option --default-new-key-adsk.
* g10/options.h (opt): Add field def_new_key_adsks. * g10/gpg.c (oDefaultNewKeyADSK): New. (opts): Add --default-new-key-adsk. (main): Parse option. * g10/keyedit.c (menu_addadsk): Factor some code out to ... (append_adsk_to_key): new. Add compliance check. * g10/keygen.c (pADSK): New. (para_data_s): Add adsk to the union. (release_parameter_list): Free the adsk. (prepare_adsk): New. (get_parameter_adsk): New. (get_parameter_revkey): Remove unneeded arg key and change callers. (proc_parameter_file): Prepare adsk parameter from the configured fingerprints. (do_generate_keypair): Create adsk. -- GnuPG-bug-id: 6882
Diffstat (limited to 'g10/keyedit.c')
-rw-r--r--g10/keyedit.c119
1 files changed, 81 insertions, 38 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c
index f41e53f6d..303309b79 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -4893,6 +4893,85 @@ fail:
}
+/* Core function to add an ADSK to the KEYBLOCK. Returns 0 on success
+ * or an error code. */
+gpg_error_t
+append_adsk_to_key (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *adsk)
+{
+ gpg_error_t err;
+ PKT_public_key *main_pk; /* The primary key. */
+ PKT_signature *sig = NULL;
+ kbnode_t adsknode = NULL;
+ PACKET *pkt; /* (temp. use; will be put into a kbnode_t) */
+
+ /* First get a copy. */
+ adsk = copy_public_key_basics (NULL, adsk);
+
+ /* Check compliance. */
+ if (!gnupg_pk_is_compliant (opt.compliance, adsk->pubkey_algo, 0,
+ adsk->pkey, nbits_from_pk (adsk), NULL))
+ {
+ char pkhex[MAX_FINGERPRINT_LEN*2+1];
+
+ hexfingerprint (adsk, pkhex, sizeof pkhex);
+ log_error (_("WARNING: key %s is not suitable for encryption"
+ " in %s mode\n"),
+ pkhex, gnupg_compliance_option_string (opt.compliance));
+ err = gpg_error (GPG_ERR_FORBIDDEN);
+ goto leave;
+ }
+
+ /* Get the primary key. */
+ log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+ main_pk = keyblock->pkt->pkt.public_key;
+
+ /* Prepare and append the adsk. */
+ keyid_from_pk (main_pk, adsk->main_keyid); /* Fixup main keyid. */
+ log_assert ((adsk->pubkey_usage & PUBKEY_USAGE_ENC));
+ adsk->pubkey_usage = PUBKEY_USAGE_RENC; /* 'e' -> 'r' */
+ pkt = xtrycalloc (1, sizeof *pkt);
+ if (!pkt)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ pkt->pkttype = PKT_PUBLIC_SUBKEY; /* Make sure it is a subkey. */
+ pkt->pkt.public_key = adsk;
+ adsknode = new_kbnode (pkt);
+
+ /* Make the signature. */
+ err = make_keysig_packet (ctrl, &sig, main_pk, NULL, adsk, main_pk, 0x18,
+ adsk->timestamp, 0,
+ keygen_add_key_flags_and_expire, adsk, NULL);
+ adsk = NULL; /* (owned by adsknode - avoid double free.) */
+ if (err)
+ {
+ write_status_error ("keysig", err);
+ log_error ("creating key binding failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ /* Append the subkey packet and the binding signature. */
+ add_kbnode (keyblock, adsknode);
+ adsknode = NULL;
+ pkt = xtrycalloc (1, sizeof *pkt);
+ if (!pkt)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ pkt->pkttype = PKT_SIGNATURE;
+ pkt->pkt.signature = sig;
+ add_kbnode (keyblock, new_kbnode (pkt));
+
+ leave:
+ release_kbnode (adsknode);
+ free_public_key (adsk); /* Release our copy. */
+ return err;
+}
+
+
+
/*
* Ask for a new additional decryption subkey and add it to the key
* block. Returns true if the keyblock was changed and false
@@ -4903,22 +4982,16 @@ static int
menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr)
{
PKT_public_key *pk;
- PKT_public_key *sub_pk;
- PKT_public_key *main_pk;
PKT_public_key *adsk_pk = NULL;
kbnode_t adsk_keyblock = NULL;
- PKT_signature *sig = NULL;
char *answer = NULL;
gpg_error_t err;
KEYDB_SEARCH_DESC desc;
byte fpr[MAX_FINGERPRINT_LEN];
size_t fprlen;
kbnode_t node, node2;
- kbnode_t subkeynode = NULL;
- PACKET *pkt; /* (temp. use; will be put into a kbnode_t) */
log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
- main_pk = pub_keyblock->pkt->pkt.public_key;
for (;;)
{
@@ -5024,46 +5097,16 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr)
break;
}
- /* Append the subkey.
- * Note that we don't use the ADSK_PK directly because this is the
- * primary key and in general we use a subkey to which NODE points.
- * ADSK_PK has only been used to pass the requested key usage to
- * get_pubkey_byname. SUB_PK will point to the actual adsk. */
+ /* Append the subkey. */
log_assert (node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
- sub_pk = copy_public_key_basics (NULL, node->pkt->pkt.public_key);
- keyid_from_pk (main_pk, sub_pk->main_keyid); /* Fixup main keyid. */
- log_assert ((sub_pk->pubkey_usage & PUBKEY_USAGE_ENC));
- sub_pk->pubkey_usage = PUBKEY_USAGE_RENC; /* 'e' -> 'r' */
- pkt = xcalloc (1, sizeof *pkt);
- pkt->pkttype = PKT_PUBLIC_SUBKEY; /* Make sure it is a subkey. */
- pkt->pkt.public_key = sub_pk;
- subkeynode = new_kbnode (pkt);
-
- /* Make the signature. */
- err = make_keysig_packet (ctrl, &sig, main_pk, NULL, sub_pk, main_pk, 0x18,
- sub_pk->timestamp, 0,
- keygen_add_key_flags_and_expire, sub_pk, NULL);
- if (err)
- {
- write_status_error ("keysig", err);
- log_error ("creating key binding failed: %s\n", gpg_strerror (err));
- goto leave;
- }
+ err = append_adsk_to_key (ctrl, pub_keyblock, node->pkt->pkt.public_key);
- /* Append the subkey packet and the binding signature. */
- add_kbnode (pub_keyblock, subkeynode);
- subkeynode = NULL;
- pkt = xcalloc (1, sizeof *pkt);
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- add_kbnode (pub_keyblock, new_kbnode (pkt));
leave:
xfree (answer);
free_public_key (adsk_pk);
release_kbnode (adsk_keyblock);
- release_kbnode (subkeynode);
if (!err)
return 1; /* The keyblock was modified. */
else