Fuite de mémoire dans la fonction OpenSSL EVP_PKEY_keygen

Je viens d’essayer de générer une clé RSA en utilisant:

#include  #include  int main(void) { OpenSSL_add_all_algorithms(); EVP_PKEY_CTX *ctx; EVP_PKEY *pkey = NULL; ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); if (!ctx) { // error } if (EVP_PKEY_keygen_init(ctx) <= 0) { // error } if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) { // error } if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { // this call seems to leak // error } EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); EVP_cleanup(); return 0; } 

Jusqu’ici, je ne pense pas que je fasse quelque chose de mal. Valgrind se plaint “en cours d’utilisation à la sortie: 416 octets sur 6 blocs”. J’ai d’abord pensé que j’avais oublié quelque chose à libérer, ensuite j’ai essayé

valgrind openssl genrsa 1024

Et je me suis aussi “utilisé à la sortie: 416 octets sur 6 blocs”. Fredonner?! Même les fuites binarys officielles d’OpenSSL?

La FAQ d’O Openssl raconte:

“Brutal” (thread-unsafe) Fonctions de nettoyage globales de l’application:

ERR_free_ssortingngs (), EVP_cleanup () et CRYPTO_cleanup_all_ex_data ().

Si j’exécute * CRYPTO_cleanup_all_ex_data () *, il ne fuit pas. Mais selon la documentation OpenSSL, il s’agit d’une méthode “brutale”, quelle que soit sa signification. Il n’y a pas de documentation supplémentaire sur cette fonction.

Y at-il un moyen de le nettoyer correctement?

J’utilise OpenSSL 1.0.1f le 6 janvier 2014

La FAQ de OpenSSL répond à la question (Merci à @opalenzuela):

Dans la plupart des cas, une fuite de mémoire apparente est due à une table interne OpenSSL allouée au démarrage d’une application. Étant donné que ces tables ne grossissent pas avec le temps, elles sont inoffensives.

Un examen plus approfondi des sources de OpenSSL montre:

 /* Release all "ex_data" state to prevent memory leaks. This can't be made * thread-safe without overhauling a lot of stuff, and shouldn't really be * called under potential race-conditions anyway (it's for program shutdown * after all). */ void CRYPTO_cleanup_all_ex_data(void) { IMPL_CHECK EX_IMPL(cleanup)(); }