Hello,
Example for OpenSSL-1.0.0-beta3:
#include <openssl/evp.h>
#include <openssl/rsa.h>
int main() {
EVP_PKEY *pkey;
const unsigned char pubkey[] =
"\x30\x48\x02\x41\x00\x80\x63\xe9"
"\xed\x51\x86\xed\x3c\x17\xaf\x58"
"\x0f\xdf\xca\x74\x27\x89\x3a\xa4"
"\x00\xb3\x6e\x4a\x0d\xae\x29\xba"
"\x97\x12\xf0\x8e\xba\xbf\x43\xed"
"\x64\x3c\xd3\x0b\x6a\x64\xee\x64"
"\x2d\xe2\xa4\x3e\x15\x04\x4d\x15"
"\x31\x42\x70\x85\x2a\xab\xf3\x82"
"\x7c\x47\x97\xe4\x89\x02\x03\x01"
"\x00\x01";
long pubkey_len = sizeof(pubkey) - 1;
const unsigned char* p = pubkey;
pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &p, pubkey_len);
if (!pkey)
return -1;
EVP_PKEY_free(pkey);
return 0;
}
Result: 0, and memory leak:
==32529== searching for pointers to 11 not-freed blocks.
==32529== checked 72,752 bytes.
==32529==
==32529== 200 (88 direct, 112 indirect) bytes in 1 blocks are definitely
lost in loss record 1 of 3
==32529== at 0x401C5D5: malloc (vg_replace_malloc.c:149)
==32529== by 0x804F9A1: default_malloc_ex
==32529== by 0x804FE69: CRYPTO_malloc
==32529== by 0x805FCC0: RSA_new_method
==32529== by 0x805FEBD: RSA_new
==32529== by 0x805FED1: rsa_cb
==32529== by 0x804A1B6: asn1_item_ex_combine_new
==32529== by 0x804A3E4: ASN1_item_ex_new
==32529== by 0x804D139: ASN1_item_ex_d2i
==32529== by 0x804D571: ASN1_item_d2i
==32529== by 0x805FFAA: d2i_RSAPublicKey
==32529== by 0x8049C6F: d2i_PublicKey
==32529==
==32529== LEAK SUMMARY:
==32529== definitely lost: 88 bytes in 1 blocks.
Minimal patch for OpenSSL-1.0.0-beta3 attached.
Thanks
diff -u -r openssl-1.0.0-beta3/crypto/asn1/d2i_pu.c openssl-1.0.0-beta3_new/crypto/asn1/d2i_pu.c
--- openssl-1.0.0-beta3/crypto/asn1/d2i_pu.c 2008-11-12 06:57:49.000000000 +0300
+++ openssl-1.0.0-beta3_new/crypto/asn1/d2i_pu.c 2009-10-29 15:19:14.000000000 +0300
@@ -62,6 +62,9 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
@@ -85,11 +88,25 @@
return(NULL);
}
}
- else ret= *a;
+ else
+ {
+ ret= *a;
+#ifndef OPENSSL_NO_ENGINE
+ if (ret->engine)
+ {
+ ENGINE_finish(ret->engine);
+ ret->engine = NULL;
+ }
+#endif
+ }
+
+ if (!EVP_PKEY_set_type(ret, type))
+ {
+ ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+ goto err;
+ }
- ret->save_type=type;
- ret->type=EVP_PKEY_type(type);
- switch (ret->type)
+ switch (EVP_PKEY_id(ret))
{
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA: