1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-10 23:49:50 +02:00

gpg: Fix memory leak in ECC encryption.

* g10/pkglue.c (pk_encrypt): Fix memory leak and streamline error
handling.
This commit is contained in:
Werner Koch 2014-09-08 18:25:06 +02:00
parent a94674c54e
commit 98f65291d7

View File

@ -190,7 +190,9 @@ int
pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
PKT_public_key *pk, gcry_mpi_t *pkey) PKT_public_key *pk, gcry_mpi_t *pkey)
{ {
gcry_sexp_t s_ciph, s_data, s_pkey; gcry_sexp_t s_ciph = NULL;
gcry_sexp_t s_data = NULL;
gcry_sexp_t s_pkey = NULL;
int rc; int rc;
/* Make a sexp from pkey. */ /* Make a sexp from pkey. */
@ -200,9 +202,8 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
"(public-key(elg(p%m)(g%m)(y%m)))", "(public-key(elg(p%m)(g%m)(y%m)))",
pkey[0], pkey[1], pkey[2]); pkey[0], pkey[1], pkey[2]);
/* Put DATA into a simplified S-expression. */ /* Put DATA into a simplified S-expression. */
if (rc || gcry_sexp_build (&s_data, NULL, "%m", data)) if (!rc)
BUG (); rc = gcry_sexp_build (&s_data, NULL, "%m", data);
} }
else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E) else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E)
{ {
@ -210,40 +211,42 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
"(public-key(rsa(n%m)(e%m)))", "(public-key(rsa(n%m)(e%m)))",
pkey[0], pkey[1]); pkey[0], pkey[1]);
/* Put DATA into a simplified S-expression. */ /* Put DATA into a simplified S-expression. */
if (rc || gcry_sexp_build (&s_data, NULL, "%m", data)) if (!rc)
BUG (); rc = gcry_sexp_build (&s_data, NULL, "%m", data);
} }
else if (algo == PUBKEY_ALGO_ECDH) else if (algo == PUBKEY_ALGO_ECDH)
{ {
gcry_mpi_t k; gcry_mpi_t k;
char *curve;
rc = pk_ecdh_generate_ephemeral_key (pkey, &k); rc = pk_ecdh_generate_ephemeral_key (pkey, &k);
if (rc) if (!rc)
return rc;
curve = openpgp_oid_to_str (pkey[0]);
if (!curve)
rc = gpg_error_from_syserror ();
else
{ {
/* Now use the ephemeral secret to compute the shared point. */ char *curve;
rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(ecdh(curve%s)(q%m)))", curve = openpgp_oid_to_str (pkey[0]);
curve, pkey[1]); if (!curve)
xfree (curve); rc = gpg_error_from_syserror ();
/* FIXME: Take care of RC. */ else
/* Put K into a simplified S-expression. */ {
if (rc || gcry_sexp_build (&s_data, NULL, "%m", k)) /* Now use the ephemeral secret to compute the shared point. */
BUG (); rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(ecdh(curve%s)(q%m)))",
curve, pkey[1]);
xfree (curve);
/* Put K into a simplified S-expression. */
if (!rc)
rc = gcry_sexp_build (&s_data, NULL, "%m", k);
}
gcry_mpi_release (k);
} }
} }
else else
return gpg_error (GPG_ERR_PUBKEY_ALGO); rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
/* Pass it to libgcrypt. */ /* Pass it to libgcrypt. */
rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); if (!rc)
rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
gcry_sexp_release (s_data); gcry_sexp_release (s_data);
gcry_sexp_release (s_pkey); gcry_sexp_release (s_pkey);