2.5.7 gnutls_x509_privkey_generate() returns GNUTLS_E_INVALID_REQUEST
Sam Varshavchik
mrsam at courier-mta.com
Sun Sep 21 19:30:44 CEST 2008
Nikos Mavrogiannopoulos writes:
> Sam Varshavchik wrote:
>
>> Unfortunately, there appears to be more problems with private key
>> functions in 2.5.7. I'm now getting segfaults in
>> gnutls_x509_privkey_import(). My debugging results are as follows:
>>
> [...]
>> ==3339== 5,886 (168 direct, 5,718 indirect) bytes in 3 blocks are
>> definitely lost in loss record 8 of 9
>> ==3339== at 0x4A05174: calloc (vg_replace_malloc.c:397)
>> ==3339== by 0x3158C0A211: (within /usr/lib64/libtasn1.so.3.0.14)
>> ==3339== by 0x3158C0A3F2: (within /usr/lib64/libtasn1.so.3.0.14)
>> ==3339== by 0x3158C0A7BD: asn1_create_element (in
>> /usr/lib64/libtasn1.so.3.0.14)
>> ==3339== by 0x4C829B2: _gnutls_asn1_encode_rsa (privkey.c:1075)
>> ==3339== by 0x4C83E0B: gnutls_x509_privkey_export (privkey.c:739)
>
> Hello Sam,
> I've commited fixes for these issues, so that latest code in git should
> not have these issues. All except the last one (quoted). It would be
> very helpful to give me some pointers on how to reproduce it.
>
> As far as I understand it should happening when
> gnutls_rsa_params_export_raw() is called?
The following minimal program triggers the leak:
#include <gcrypt.h>
#include <gnutls/gnutls.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
GCRY_THREAD_OPTION_PTHREAD_IMPL;
int main()
{
int i;
gnutls_rsa_params_t rsa;
size_t buflen;
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM);
gnutls_global_init();
gnutls_rsa_params_init(&rsa);
printf("vers %s %s\n", LIBGNUTLS_VERSION, gnutls_check_version (NULL));
gnutls_rsa_params_generate2(rsa, 1024);
gnutls_rsa_params_export_pkcs1(rsa, GNUTLS_X509_FMT_DER, NULL, &buflen);
char b[buflen];
gnutls_rsa_params_export_pkcs1(rsa, GNUTLS_X509_FMT_DER, b, &buflen);
gnutls_rsa_params_deinit(rsa);
return(0);
}
The leak gets triggered only when gnutls_rsa_params_export_pkcs1() gets
invoked twice, once with a NULL buffer pointer, to compute the buffer size,
and a second time with the real buffer pointer. Invoking it just once is not
sufficient.
What looks like is happening is that in gnutls_x509_privkey_export():
case GNUTLS_PK_RSA:
ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
First time through, key->key is NULL, and _gnutls_asn1_encode_rsa()
allocates it using asn1_create_element(). On the second call, key->key holds
the previously allocated buffer, but _gnutls_asn1_encode_rsa() allocates a
new one, without freeing the first one, and leaks it.
I also see similar logic for the GNUTLS_PK_DSA case, and
_gnutls_asn1_encode_dsa(), so there may also be a similar leak there.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: </pipermail/attachments/20080921/95868500/attachment.pgp>
More information about the Gnutls-devel
mailing list