mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
gpg: Fix a memory leak in batch key generation
* g10/keygen.c (append_to_parameter): New. (proc_parameter_file): Use new func to extend the parameter list. * g10/passphrase.c (passphrase_to_dek_ext): Print a diagnostic of gcry_kdf_derive failed. * g10/keygen.c (proc_parameter_file): Print a diagnostic if passphrase_to_dek failed. -- Due to an improper way of using the linked list head, all memory for items allocated in proc_parameter_file was never released. If batched key generation with a passphrase and more than ~200 keys was used this exhausted the secure memory.
This commit is contained in:
parent
baee681d24
commit
161674118d
48
g10/keygen.c
48
g10/keygen.c
@ -2591,6 +2591,17 @@ generate_user_id (KBNODE keyblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Append R to the linked list PARA. */
|
||||||
|
static void
|
||||||
|
append_to_parameter (struct para_data_s *para, struct para_data_s *r)
|
||||||
|
{
|
||||||
|
assert (para);
|
||||||
|
while (para->next)
|
||||||
|
para = para->next;
|
||||||
|
para->next = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the parameter list R. */
|
||||||
static void
|
static void
|
||||||
release_parameter_list (struct para_data_s *r)
|
release_parameter_list (struct para_data_s *r)
|
||||||
{
|
{
|
||||||
@ -2817,8 +2828,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
r->u.usage = (is_default
|
r->u.usage = (is_default
|
||||||
? (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG)
|
? (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG)
|
||||||
: openpgp_pk_algo_usage(algo));
|
: openpgp_pk_algo_usage(algo));
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
}
|
}
|
||||||
else if (err == -1)
|
else if (err == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -2854,8 +2864,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
r->u.usage = (is_default
|
r->u.usage = (is_default
|
||||||
? PUBKEY_USAGE_ENC
|
? PUBKEY_USAGE_ENC
|
||||||
: openpgp_pk_algo_usage (algo));
|
: openpgp_pk_algo_usage (algo));
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
}
|
}
|
||||||
else if (err == -1)
|
else if (err == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -2892,8 +2901,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")");
|
p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")");
|
||||||
if( s3 )
|
if( s3 )
|
||||||
p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">");
|
p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">");
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
have_user_id=1;
|
have_user_id=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2946,13 +2954,11 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
r = xmalloc_clear( sizeof *r );
|
r = xmalloc_clear( sizeof *r );
|
||||||
r->key = pPASSPHRASE_DEK;
|
r->key = pPASSPHRASE_DEK;
|
||||||
r->u.dek = dek;
|
r->u.dek = dek;
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
r = xmalloc_clear( sizeof *r );
|
r = xmalloc_clear( sizeof *r );
|
||||||
r->key = pPASSPHRASE_S2K;
|
r->key = pPASSPHRASE_S2K;
|
||||||
r->u.s2k = s2k;
|
r->u.s2k = s2k;
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canceled)
|
if (canceled)
|
||||||
@ -2971,27 +2977,32 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
* but because we do this always, why not here. */
|
* but because we do this always, why not here. */
|
||||||
STRING2KEY *s2k;
|
STRING2KEY *s2k;
|
||||||
DEK *dek;
|
DEK *dek;
|
||||||
|
static int count;
|
||||||
|
|
||||||
s2k = xmalloc_secure ( sizeof *s2k );
|
s2k = xmalloc ( sizeof *s2k );
|
||||||
s2k->mode = opt.s2k_mode;
|
s2k->mode = opt.s2k_mode;
|
||||||
s2k->hash_algo = S2K_DIGEST_ALGO;
|
s2k->hash_algo = S2K_DIGEST_ALGO;
|
||||||
set_next_passphrase ( r->u.value );
|
set_next_passphrase ( r->u.value );
|
||||||
dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
|
dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
set_next_passphrase (NULL );
|
if (!dek)
|
||||||
assert (dek);
|
{
|
||||||
|
log_error ("%s:%d: error post processing the passphrase\n",
|
||||||
|
fname, r->lnr );
|
||||||
|
xfree (s2k);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
set_next_passphrase (NULL);
|
||||||
memset (r->u.value, 0, strlen(r->u.value));
|
memset (r->u.value, 0, strlen(r->u.value));
|
||||||
|
|
||||||
r = xmalloc_clear (sizeof *r);
|
r = xmalloc_clear (sizeof *r);
|
||||||
r->key = pPASSPHRASE_S2K;
|
r->key = pPASSPHRASE_S2K;
|
||||||
r->u.s2k = s2k;
|
r->u.s2k = s2k;
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
r = xmalloc_clear (sizeof *r);
|
r = xmalloc_clear (sizeof *r);
|
||||||
r->key = pPASSPHRASE_DEK;
|
r->key = pPASSPHRASE_DEK;
|
||||||
r->u.dek = dek;
|
r->u.dek = dek;
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3029,8 +3040,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
r = xmalloc_clear( sizeof *r + 20 );
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
r->key = pSUBKEYEXPIRE;
|
r->key = pSUBKEYEXPIRE;
|
||||||
r->u.expire = seconds;
|
r->u.expire = seconds;
|
||||||
r->next = para;
|
append_to_parameter (para, r);
|
||||||
para = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do_generate_keypair( para, outctrl, card );
|
do_generate_keypair( para, outctrl, card );
|
||||||
|
@ -569,17 +569,21 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
dek->keylen = 0;
|
dek->keylen = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
|
dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
|
||||||
if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
|
if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
|
||||||
BUG ();
|
BUG ();
|
||||||
if (gcry_kdf_derive (pw, strlen (pw),
|
err = gcry_kdf_derive (pw, strlen (pw),
|
||||||
s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
|
s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
|
||||||
s2k->mode == 1? GCRY_KDF_SALTED_S2K :
|
s2k->mode == 1? GCRY_KDF_SALTED_S2K :
|
||||||
/* */ GCRY_KDF_SIMPLE_S2K,
|
/* */ GCRY_KDF_SIMPLE_S2K,
|
||||||
s2k->hash_algo, s2k->salt, 8,
|
s2k->hash_algo, s2k->salt, 8,
|
||||||
S2K_DECODE_COUNT(s2k->count),
|
S2K_DECODE_COUNT(s2k->count),
|
||||||
dek->keylen, dek->key))
|
dek->keylen, dek->key);
|
||||||
|
if (err)
|
||||||
{
|
{
|
||||||
|
log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err));
|
||||||
xfree (pw);
|
xfree (pw);
|
||||||
xfree (dek);
|
xfree (dek);
|
||||||
write_status( STATUS_MISSING_PASSPHRASE );
|
write_status( STATUS_MISSING_PASSPHRASE );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user