aboutsummaryrefslogtreecommitdiffstats
path: root/g10/pubkey-enc.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2018-08-27 04:12:31 +0000
committerNIIBE Yutaka <[email protected]>2018-08-27 04:12:31 +0000
commitce2f71760155b71a71418fe145a557c99bd52290 (patch)
tree9c5f3eca5989d3ce2302d4f56930b3271615f075 /g10/pubkey-enc.c
parentg10: Fix undefined behavior when EOF in parsing packet for S2K. (diff)
downloadgnupg-ce2f71760155b71a71418fe145a557c99bd52290.tar.gz
gnupg-ce2f71760155b71a71418fe145a557c99bd52290.zip
g10: Change decryption key selection for public key encryption.
* g10/mainproc.c (struct mainproc_context): It's now pubkey_enc_list. (do_proc_packets): Remove the first arg CTRL. Fix call of proc_pubkey_enc. (release_list): Handle pubkey_enc_list. (proc_pubkey_enc): Remove the first arg CTRL. Simply put the packet to pubkey_enc_list. (print_pkenc_list): Remove the last arg FAILED. (proc_encrypted): Only call print_pkenc_list once. Handle DEK here. (proc_packets, proc_signature_packets, proc_signature_packets_by_fd) (proc_encryption_packets): Fix call of do_proc_packets. * g10/packet.h (struct pubkey_enc_list): Define. * g10/pubkey-enc.c (get_it): Change the second argument K. (get_session_key): Select session key by LIST, using enum_secret_keys. * g10/gpgv.c (get_session_key): Change the second argument K. * g10/test-stubs.c (get_session_key): Likewise. -- Collect all PKT_PUBKEY_ENC packets, and then, process the PKT_ENCRYPTED* packet. Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to 'g10/pubkey-enc.c')
-rw-r--r--g10/pubkey-enc.c118
1 files changed, 59 insertions, 59 deletions
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 0185097a4..8540e03c9 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -38,7 +38,7 @@
#include "../common/compliance.h"
-static gpg_error_t get_it (ctrl_t ctrl, PKT_pubkey_enc *k,
+static gpg_error_t get_it (ctrl_t ctrl, struct pubkey_enc_list *k,
DEK *dek, PKT_public_key *sk, u32 *keyid);
@@ -72,92 +72,92 @@ is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
* which should have been allocated in secure memory by the caller.
*/
gpg_error_t
-get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
+get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
{
PKT_public_key *sk = NULL;
int rc;
+ void *enum_context = NULL;
+ u32 keyid[2];
+ int search_for_secret_keys = 1;
if (DBG_CLOCK)
log_clock ("get_session_key enter");
- rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
- if (rc)
- goto leave;
-
- if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets)
+ while (search_for_secret_keys)
{
+ struct pubkey_enc_list *k;
+
+ free_public_key (sk);
sk = xmalloc_clear (sizeof *sk);
- sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */
- if (!(rc = get_seckey (ctrl, sk, k->keyid)))
+ rc = enum_secret_keys (ctrl, &enum_context, sk);
+ if (rc)
{
- /* Check compliance. */
- if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
- sk->pubkey_algo,
- sk->pkey, nbits_from_pk (sk), NULL))
- {
- log_info (_("key %s is not suitable for decryption"
- " in %s mode\n"),
- keystr_from_pk (sk),
- gnupg_compliance_option_string (opt.compliance));
- rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
- }
- else
- rc = get_it (ctrl, k, dek, sk, k->keyid);
+ rc = GPG_ERR_NO_SECKEY;
+ break;
}
- }
- else if (opt.skip_hidden_recipients)
- rc = gpg_error (GPG_ERR_NO_SECKEY);
- else /* Anonymous receiver: Try all available secret keys. */
- {
- void *enum_context = NULL;
- u32 keyid[2];
- for (;;)
+ if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
+ continue;
+
+ /* Check compliance. */
+ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
+ sk->pubkey_algo,
+ sk->pkey, nbits_from_pk (sk), NULL))
{
- free_public_key (sk);
- sk = xmalloc_clear (sizeof *sk);
- rc = enum_secret_keys (ctrl, &enum_context, sk);
- if (rc)
- {
- rc = GPG_ERR_NO_SECKEY;
- break;
- }
- if (sk->pubkey_algo != k->pubkey_algo)
+ log_info (_("key %s is not suitable for decryption"
+ " in %s mode\n"),
+ keystr_from_pk (sk),
+ gnupg_compliance_option_string (opt.compliance));
+ continue;
+ }
+
+ for (k = list; k; k = k->next)
+ {
+ if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E
+ || k->pubkey_algo == PUBKEY_ALGO_ECDH
+ || k->pubkey_algo == PUBKEY_ALGO_RSA
+ || k->pubkey_algo == PUBKEY_ALGO_RSA_E
+ || k->pubkey_algo == PUBKEY_ALGO_ELGAMAL))
continue;
- if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
+
+ if (openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC))
+ continue;
+
+ if (sk->pubkey_algo != k->pubkey_algo)
continue;
+
keyid_from_pk (sk, keyid);
- if (!opt.quiet)
- log_info (_("anonymous recipient; trying secret key %s ...\n"),
- keystr (keyid));
-
- /* Check compliance. */
- if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
- sk->pubkey_algo,
- sk->pkey, nbits_from_pk (sk), NULL))
+
+ if (!k->keyid[0] && !k->keyid[1])
{
- log_info (_("key %s is not suitable for decryption"
- " in %s mode\n"),
- keystr_from_pk (sk),
- gnupg_compliance_option_string (opt.compliance));
- continue;
+ if (!opt.quiet)
+ log_info (_("anonymous recipient; trying secret key %s ...\n"),
+ keystr (keyid));
}
+ else if (opt.try_all_secrets
+ || (k->keyid[0] == keyid[0] && k->keyid[1] == keyid[1]))
+ ;
+ else
+ continue;
rc = get_it (ctrl, k, dek, sk, keyid);
if (!rc)
{
- if (!opt.quiet)
+ 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)
- break; /* Don't try any more secret keys. */
+ {
+ search_for_secret_keys = 0;
+ break; /* Don't try any more secret keys. */
+ }
}
- enum_secret_keys (ctrl, &enum_context, NULL); /* free context */
}
-
- leave:
+ enum_secret_keys (ctrl, &enum_context, NULL); /* free context */
free_public_key (sk);
+
if (DBG_CLOCK)
log_clock ("get_session_key leave");
return rc;
@@ -166,7 +166,7 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
static gpg_error_t
get_it (ctrl_t ctrl,
- PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
+ struct pubkey_enc_list *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
{
gpg_error_t err;
byte *frame = NULL;