mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-26 22:29:58 +01:00
g10: factor out a function for secret key retrieval.
* g10/export.c (receive_seckey_from_agent): New. (do_export_stream): Use it. -- Also fixed a memory leak of WRAPPEDKEY on a successful path of build_packet. In the log message, key is now by a hexgrip instead of a format by keystr_with_sub.
This commit is contained in:
parent
fc010b6c7f
commit
e644aa7f59
153
g10/export.c
153
g10/export.c
@ -825,6 +825,78 @@ print_status_exported (PKT_public_key *pk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Receive a secret key from agent specified by HEXGRIP.
|
||||||
|
*
|
||||||
|
* Since the key data from agant is encrypted, decrypt it by CIPHERHD.
|
||||||
|
* Then, parse the decrypted key data in transfer format, and put
|
||||||
|
* secret papameters into PK.
|
||||||
|
*
|
||||||
|
* CACHE_NONCE_ADDR is used to share nonce for multple key retrievals.
|
||||||
|
*/
|
||||||
|
gpg_error_t
|
||||||
|
receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
|
||||||
|
char **cache_nonce_addr, const char *hexgrip,
|
||||||
|
PKT_public_key *pk)
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
unsigned char *wrappedkey = NULL;
|
||||||
|
size_t wrappedkeylen;
|
||||||
|
unsigned char *key = NULL;
|
||||||
|
size_t keylen, realkeylen;
|
||||||
|
gcry_sexp_t s_skey;
|
||||||
|
char *prompt;
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info ("key %s: asking agent for the secret parts\n", hexgrip);
|
||||||
|
|
||||||
|
prompt = gpg_format_keydesc (pk, FORMAT_KEYDESC_EXPORT,1);
|
||||||
|
err = agent_export_key (ctrl, hexgrip, prompt, cache_nonce_addr,
|
||||||
|
&wrappedkey, &wrappedkeylen);
|
||||||
|
xfree (prompt);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto unwraperror;
|
||||||
|
if (wrappedkeylen < 24)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_LENGTH);
|
||||||
|
goto unwraperror;
|
||||||
|
}
|
||||||
|
keylen = wrappedkeylen - 8;
|
||||||
|
key = xtrymalloc_secure (keylen);
|
||||||
|
if (!key)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto unwraperror;
|
||||||
|
}
|
||||||
|
err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
|
||||||
|
if (err)
|
||||||
|
goto unwraperror;
|
||||||
|
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
||||||
|
if (!realkeylen)
|
||||||
|
goto unwraperror; /* Invalid csexp. */
|
||||||
|
|
||||||
|
err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
err = transfer_format_to_openpgp (s_skey, pk);
|
||||||
|
gcry_sexp_release (s_skey);
|
||||||
|
}
|
||||||
|
|
||||||
|
unwraperror:
|
||||||
|
xfree (key);
|
||||||
|
xfree (wrappedkey);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("key %s: error receiving key from agent:"
|
||||||
|
" %s%s\n", hexgrip, gpg_strerror (err),
|
||||||
|
gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
|
||||||
|
"":_(" - skipped"));
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Export the keys identified by the list of strings in USERS to the
|
/* Export the keys identified by the list of strings in USERS to the
|
||||||
stream OUT. If Secret is false public keys will be exported. With
|
stream OUT. If Secret is false public keys will be exported. With
|
||||||
secret true secret keys will be exported; in this case 1 means the
|
secret true secret keys will be exported; in this case 1 means the
|
||||||
@ -1203,83 +1275,24 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
}
|
}
|
||||||
else if (!err)
|
else if (!err)
|
||||||
{
|
{
|
||||||
/* FIXME: Move this spaghetti code into a separate
|
err = receive_seckey_from_agent (ctrl, cipherhd, &cache_nonce,
|
||||||
function. */
|
hexgrip, pk);
|
||||||
unsigned char *wrappedkey = NULL;
|
|
||||||
size_t wrappedkeylen;
|
|
||||||
unsigned char *key = NULL;
|
|
||||||
size_t keylen, realkeylen;
|
|
||||||
gcry_sexp_t s_skey;
|
|
||||||
|
|
||||||
if (opt.verbose)
|
|
||||||
log_info ("key %s: asking agent for the secret parts\n",
|
|
||||||
keystr_with_sub (keyid, subkid));
|
|
||||||
|
|
||||||
{
|
|
||||||
char *prompt = gpg_format_keydesc (pk,
|
|
||||||
FORMAT_KEYDESC_EXPORT,1);
|
|
||||||
err = agent_export_key (ctrl, hexgrip, prompt, &cache_nonce,
|
|
||||||
&wrappedkey, &wrappedkeylen);
|
|
||||||
xfree (prompt);
|
|
||||||
}
|
|
||||||
if (err)
|
|
||||||
goto unwraperror;
|
|
||||||
if (wrappedkeylen < 24)
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_INV_LENGTH);
|
|
||||||
goto unwraperror;
|
|
||||||
}
|
|
||||||
keylen = wrappedkeylen - 8;
|
|
||||||
key = xtrymalloc_secure (keylen);
|
|
||||||
if (!key)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_syserror ();
|
|
||||||
goto unwraperror;
|
|
||||||
}
|
|
||||||
err = gcry_cipher_decrypt (cipherhd, key, keylen,
|
|
||||||
wrappedkey, wrappedkeylen);
|
|
||||||
if (err)
|
|
||||||
goto unwraperror;
|
|
||||||
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
|
||||||
if (!realkeylen)
|
|
||||||
goto unwraperror; /* Invalid csexp. */
|
|
||||||
|
|
||||||
err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
|
|
||||||
xfree (key);
|
|
||||||
key = NULL;
|
|
||||||
if (err)
|
|
||||||
goto unwraperror;
|
|
||||||
err = transfer_format_to_openpgp (s_skey, pk);
|
|
||||||
gcry_sexp_release (s_skey);
|
|
||||||
if (err)
|
|
||||||
goto unwraperror;
|
|
||||||
|
|
||||||
err = build_packet (out, node->pkt);
|
|
||||||
if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
|
|
||||||
{
|
|
||||||
stats->exported++;
|
|
||||||
print_status_exported (node->pkt->pkt.public_key);
|
|
||||||
}
|
|
||||||
goto unwraperror_leave;
|
|
||||||
|
|
||||||
unwraperror:
|
|
||||||
xfree (wrappedkey);
|
|
||||||
xfree (key);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("key %s: error receiving key from agent:"
|
|
||||||
" %s%s\n",
|
|
||||||
keystr_with_sub (keyid, subkid),
|
|
||||||
gpg_strerror (err),
|
|
||||||
gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
|
|
||||||
"":_(" - skipped"));
|
|
||||||
if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
|
if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
|
||||||
goto leave;
|
goto leave;
|
||||||
skip_until_subkey = 1;
|
skip_until_subkey = 1;
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
unwraperror_leave:
|
else
|
||||||
;
|
{
|
||||||
|
err = build_packet (out, node->pkt);
|
||||||
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||||
|
{
|
||||||
|
stats->exported++;
|
||||||
|
print_status_exported (node->pkt->pkt.public_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user