gpg: Actually encrypt to ADSKs.

* g10/getkey.c (get_pubkey_fromfile): Add optional arg r_keyblock.
* g10/pkclist.c (find_and_check_key): Also encrypt to RENC subkeys.
--

GnuPG-bug-id: 6395
This commit is contained in:
Werner Koch 2023-03-01 18:56:29 +01:00
parent 3a18378a92
commit ef5a48dd51
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 39 additions and 14 deletions

View File

@ -1718,7 +1718,8 @@ get_best_pubkey_byname (ctrl_t ctrl, enum get_pubkey_modes mode,
* *
* This function returns 0 on success. Otherwise, an error code is * This function returns 0 on success. Otherwise, an error code is
* returned. In particular, GPG_ERR_NO_PUBKEY is returned if the key * returned. In particular, GPG_ERR_NO_PUBKEY is returned if the key
* is not found. * is not found. If R_KEYBLOCK is not NULL and a key was found the
* keyblock is stored there; otherwiese NULL is stored there.
* *
* The self-signed data has already been merged into the public key * The self-signed data has already been merged into the public key
* using merge_selfsigs. The caller must release the content of PK by * using merge_selfsigs. The caller must release the content of PK by
@ -1726,13 +1727,17 @@ get_best_pubkey_byname (ctrl_t ctrl, enum get_pubkey_modes mode,
* free_public_key). * free_public_key).
*/ */
gpg_error_t gpg_error_t
get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname) get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname,
kbnode_t *r_keyblock)
{ {
gpg_error_t err; gpg_error_t err;
kbnode_t keyblock; kbnode_t keyblock;
kbnode_t found_key; kbnode_t found_key;
unsigned int infoflags; unsigned int infoflags;
if (r_keyblock)
*r_keyblock = NULL;
err = read_key_from_file_or_buffer (ctrl, fname, NULL, 0, &keyblock); err = read_key_from_file_or_buffer (ctrl, fname, NULL, 0, &keyblock);
if (!err) if (!err)
{ {
@ -1747,7 +1752,10 @@ get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname)
err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
} }
release_kbnode (keyblock); if (!err && r_keyblock)
*r_keyblock = keyblock;
else
release_kbnode (keyblock);
return err; return err;
} }

View File

@ -391,7 +391,8 @@ gpg_error_t get_best_pubkey_byname (ctrl_t ctrl, enum get_pubkey_modes mode,
/* Get a public key directly from file FNAME. */ /* Get a public key directly from file FNAME. */
gpg_error_t get_pubkey_fromfile (ctrl_t ctrl, gpg_error_t get_pubkey_fromfile (ctrl_t ctrl,
PKT_public_key *pk, const char *fname); PKT_public_key *pk, const char *fname,
kbnode_t *r_keyblock);
/* Get a public key from a buffer. */ /* Get a public key from a buffer. */
gpg_error_t get_pubkey_from_buffer (ctrl_t ctrl, PKT_public_key *pkbuf, gpg_error_t get_pubkey_from_buffer (ctrl_t ctrl, PKT_public_key *pkbuf,

View File

@ -845,7 +845,8 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
{ {
int rc; int rc;
PKT_public_key *pk; PKT_public_key *pk;
KBNODE keyblock = NULL; kbnode_t keyblock = NULL;
kbnode_t node;
if (!name || !*name) if (!name || !*name)
return gpg_error (GPG_ERR_INV_USER_ID); return gpg_error (GPG_ERR_INV_USER_ID);
@ -856,7 +857,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
pk->req_usage = use; pk->req_usage = use;
if (from_file) if (from_file)
rc = get_pubkey_fromfile (ctrl, pk, name); rc = get_pubkey_fromfile (ctrl, pk, name, &keyblock);
else else
rc = get_best_pubkey_byname (ctrl, GET_PUBKEY_NORMAL, rc = get_best_pubkey_byname (ctrl, GET_PUBKEY_NORMAL,
NULL, pk, name, &keyblock, 0); NULL, pk, name, &keyblock, 0);
@ -895,10 +896,10 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
int trustlevel; int trustlevel;
trustlevel = get_validity (ctrl, keyblock, pk, pk->user_id, NULL, 1); trustlevel = get_validity (ctrl, keyblock, pk, pk->user_id, NULL, 1);
release_kbnode (keyblock);
if ( (trustlevel & TRUST_FLAG_DISABLED) ) if ( (trustlevel & TRUST_FLAG_DISABLED) )
{ {
/* Key has been disabled. */ /* Key has been disabled. */
release_kbnode (keyblock);
send_status_inv_recp (13, name); send_status_inv_recp (13, name);
log_info (_("%s: skipped: public key is disabled\n"), name); log_info (_("%s: skipped: public key is disabled\n"), name);
free_public_key (pk); free_public_key (pk);
@ -908,6 +909,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
if ( !do_we_trust_pre (ctrl, pk, trustlevel) ) if ( !do_we_trust_pre (ctrl, pk, trustlevel) )
{ {
/* We don't trust this key. */ /* We don't trust this key. */
release_kbnode (keyblock);
send_status_inv_recp (10, name); send_status_inv_recp (10, name);
free_public_key (pk); free_public_key (pk);
return GPG_ERR_UNUSABLE_PUBKEY; return GPG_ERR_UNUSABLE_PUBKEY;
@ -926,19 +928,33 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
{ {
pk_list_t r; pk_list_t r;
r = xtrymalloc (sizeof *r); r = xmalloc (sizeof *r);
if (!r)
{
rc = gpg_error_from_syserror ();
free_public_key (pk);
return rc;
}
r->pk = pk; r->pk = pk;
r->next = *pk_list_addr; r->next = *pk_list_addr;
r->flags = mark_hidden? 1:0; r->flags = mark_hidden? 1:0;
*pk_list_addr = r; *pk_list_addr = r;
} }
for (node = keyblock; node; node = node->next)
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& ((pk=node->pkt->pkt.public_key)->pubkey_usage & PUBKEY_USAGE_RENC)
&& pk->flags.valid
&& !pk->flags.revoked
&& !pk->flags.disabled
&& !pk->has_expired
&& key_present_in_pk_list (*pk_list_addr, pk))
{
pk_list_t r;
r = xmalloc (sizeof *r);
r->pk = copy_public_key (NULL, pk);
r->next = *pk_list_addr;
r->flags = mark_hidden? 1:0; /* FIXME: Use PK_LIST_HIDDEN ? */
*pk_list_addr = r;
}
release_kbnode (keyblock);
return 0; return 0;
} }