gpg: Return the last error for pubkey decryption.

* g10/mainproc.c (proc_encrypted): Check ->result against -1.
When c->dek == NULL, put GPG_ERR_NO_SECKEY only when not set.
* g10/pubkey-enc.c (get_session_key): Set k->result by the result of
get_it.
When no secret key is available for some reasons, return the last
specific error, if any.

GnuPG-bug-id: 4561
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2019-07-05 15:16:08 +09:00
parent 064aeb14c9
commit 6cc4119ec0
2 changed files with 25 additions and 18 deletions

View File

@ -583,7 +583,7 @@ proc_encrypted (CTX c, PACKET *pkt)
struct pubkey_enc_list *list;
for (list = c->pkenc_list; list; list = list->next)
if (list->result == GPG_ERR_NO_SECKEY)
if (list->result != -1)
{
char buf[20];
snprintf (buf, sizeof buf, "%08lX%08lX",
@ -668,7 +668,10 @@ proc_encrypted (CTX c, PACKET *pkt)
}
}
else if (!c->dek)
result = GPG_ERR_NO_SECKEY;
{
if (!result)
result = GPG_ERR_NO_SECKEY;
}
/* Compute compliance with CO_DE_VS. */
if (!result && is_status_enabled ()

View File

@ -75,25 +75,21 @@ gpg_error_t
get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
{
PKT_public_key *sk = NULL;
int rc;
gpg_error_t err;
void *enum_context = NULL;
u32 keyid[2];
int search_for_secret_keys = 1;
struct pubkey_enc_list *k;
if (DBG_CLOCK)
log_clock ("get_session_key enter");
while (search_for_secret_keys)
{
struct pubkey_enc_list *k;
sk = xmalloc_clear (sizeof *sk);
rc = enum_secret_keys (ctrl, &enum_context, sk);
if (rc)
{
rc = GPG_ERR_NO_SECKEY;
break;
}
err = enum_secret_keys (ctrl, &enum_context, sk);
if (err)
break;
if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
continue;
@ -132,8 +128,6 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
if (openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC))
continue;
k->result = GPG_ERR_NO_SECKEY;
if (sk->pubkey_algo != k->pubkey_algo)
continue;
@ -154,16 +148,16 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
else
continue;
rc = get_it (ctrl, k, dek, sk, keyid);
if (!rc)
err = get_it (ctrl, k, dek, sk, keyid);
k->result = err;
if (!err)
{
k->result = 0;
if (!opt.quiet && !k->keyid[0] && !k->keyid[1])
log_info (_("okay, we are the anonymous recipient.\n"));
search_for_secret_keys = 0;
break;
}
else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
else if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
{
search_for_secret_keys = 0;
break; /* Don't try any more secret keys. */
@ -172,9 +166,19 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
}
enum_secret_keys (ctrl, &enum_context, NULL); /* free context */
if (gpg_err_code (err) == GPG_ERR_EOF)
{
err = gpg_error (GPG_ERR_NO_SECKEY);
/* Return the last specific error, if any. */
for (k = list; k; k = k->next)
if (k->result != -1)
err = k->result;
}
if (DBG_CLOCK)
log_clock ("get_session_key leave");
return rc;
return err;
}