/* * Get the session key from a pubkey enc packet and return it in DEK, * which should have been allocated in secure memory by the caller. */ gpg_error_t get_session_key (PKT_pubkey_enc * k, DEK * dek) { PKT_public_key *sk = NULL; int rc; 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) { sk = xmalloc_clear (sizeof *sk); sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */ if (!(rc = get_seckey (sk, k->keyid))) rc = get_it (k, dek, sk, k->keyid); } 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) free_public_key (sk); sk = xmalloc_clear (sizeof *sk); rc = enum_secret_keys (&enum_context, sk); if (rc) { rc = G10ERR_NO_SECKEY; break; } if (sk->pubkey_algo != k->pubkey_algo) continue; if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC)) continue; keyid_from_pk (sk, keyid); log_info (_("anonymous recipient; trying secret key %s ...\n"), keystr (keyid)); rc = get_it (k, dek, sk, keyid); if (!rc) { log_info (_("okay, we are the anonymous recipient.\n")); break; } else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) break; /* Don't try any more secret keys. */ } enum_secret_keys (&enum_context, NULL); /* free context */ } leave: if (sk) free_public_key (sk); return rc; }
/**************** * Get the session key from a pubkey enc paket and return * it in DEK, which should have been allocated in secure memory. */ int get_session_key( PKT_pubkey_enc *k, DEK *dek ) { PKT_secret_key *sk = NULL; int rc; rc = check_pubkey_algo( k->pubkey_algo ); if( rc ) goto leave; if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) { sk = m_alloc_clear( sizeof *sk ); sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ if( !(rc = get_seckey( sk, k->keyid )) ) rc = get_it( k, dek, sk, k->keyid ); } else { /* anonymous receiver: Try all available secret keys */ void *enum_context = NULL; u32 keyid[2]; for(;;) { if( sk ) free_secret_key( sk ); sk = m_alloc_clear( sizeof *sk ); rc=enum_secret_keys( &enum_context, sk, 1); if( rc ) { rc = G10ERR_NO_SECKEY; break; } if( sk->pubkey_algo != k->pubkey_algo ) continue; keyid_from_sk( sk, keyid ); log_info(_("anonymous receiver; trying secret key %08lX ...\n"), (ulong)keyid[1] ); rc = check_secret_key( sk, 1 ); /* ask only once */ if( !rc ) rc = get_it( k, dek, sk, keyid ); if( !rc ) { log_info(_("okay, we are the anonymous recipient.\n") ); break; } } enum_secret_keys( &enum_context, NULL, 0 ); /* free context */ } leave: if( sk ) free_secret_key( sk ); return rc; }
/**************** * Get the session key from a pubkey enc packet and return * it in DEK, which should have been allocated in secure memory. */ int get_session_key( PKT_pubkey_enc *k, DEK *dek ) { PKT_secret_key *sk = NULL; int rc; 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 ) { sk = xmalloc_clear( sizeof *sk ); sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ if( !(rc = get_seckey( sk, k->keyid )) ) rc = get_it( k, dek, sk, k->keyid ); } else { /* anonymous receiver: Try all available secret keys */ void *enum_context = NULL; u32 keyid[2]; char *p; for(;;) { if( sk ) free_secret_key( sk ); sk = xmalloc_clear( sizeof *sk ); rc=enum_secret_keys( &enum_context, sk, 1, 0); if( rc ) { rc = G10ERR_NO_SECKEY; break; } if( sk->pubkey_algo != k->pubkey_algo ) continue; keyid_from_sk( sk, keyid ); log_info(_("anonymous recipient; trying secret key %s ...\n"), keystr(keyid)); if(!opt.try_all_secrets && !is_status_enabled()) { p=get_last_passphrase(); set_next_passphrase(p); xfree(p); } rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask only once */ if( !rc ) { rc = get_it( k, dek, sk, keyid ); /* Successfully checked the secret key (either it was a card, had no passphrase, or had the right passphrase) but couldn't decrypt the session key, so thus that key is not the anonymous recipient. Move the next passphrase into last for the next round. We only do this if the secret key was successfully checked as in the normal case, check_secret_key handles this for us via passphrase_to_dek */ if(rc) next_to_last_passphrase(); } if( !rc ) { log_info(_("okay, we are the anonymous recipient.\n") ); break; } } enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */ } leave: if( sk ) free_secret_key( sk ); return rc; }
/* * Get the session key from a pubkey enc packet and return it in DEK, * 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) { PKT_public_key *sk = NULL; int rc; 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) { 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))) { /* 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); } } 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 (;;) { 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) continue; if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC)) 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)) { log_info (_("key %s is not suitable for decryption" " in %s mode\n"), keystr_from_pk (sk), gnupg_compliance_option_string (opt.compliance)); continue; } rc = get_it (ctrl, k, dek, sk, keyid); if (!rc) { if (!opt.quiet) log_info (_("okay, we are the anonymous recipient.\n")); break; } else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) break; /* Don't try any more secret keys. */ } enum_secret_keys (ctrl, &enum_context, NULL); /* free context */ } leave: free_public_key (sk); if (DBG_CLOCK) log_clock ("get_session_key leave"); return rc; }