Thanks for the explanation and pinter for the relevant ASN1 function.
Erwin
--------------------------------------------------
From: "Jakob Bohm" <jb-open...@wisemo.com>
Sent: Friday, September 09, 2011 4:22 AM
To: <openssl-users@openssl.org>
Subject: Re: How to Check Whether the resources of X509 has been freed when
it is freed by X509_free()
On 9/9/2011 5:21 AM, Erwin Himawan wrote:
Hi All,
I have several questions associated with freeing resources of X509
struct.
snippet of my code:
X509 *x509Cert = X509_new();
if (x509Cert == NULL) printf("Error instantiating X509 object\n");
/* do some processing with my x509Cert object */
/* Cleaning up resources of x509Cert */
if(x509Cert != NULL) X509_free(x509Cert);
My questions are:
1. How to check that x509Cert resources have been freed? I notice that
X509_free(x509Cert) does not set the x509Cert to NULL, therefore I can
not
rely on if(x509Cert != NULL) to verify that x509Cert resources has been
freed. this a bug or there are other method for verifying whether
x509Cert
resources have been freed.
As OpenSSL is a C (not C++ or Pascal) API, unless a function takes an
explicit pointer to your x509Cert variable it is not supposed to have the
ability to change it. This is one of the nice semantic guarantees of the
C language.
As x509_free() returns void, you should simply assume that the call *will*
free what it is told to free, to the maximum extent reasonably possible,
which is actually the sanest and most programmer friendly way to specify a
cleanup function (for the same reason, C++ destructors have no return
value either and are barred from using exceptions during stack unwind). It
is good practice to wrap it in a block such as the following: { X509
*ptmp = x509Cert; x509Cert = NULL; // Do this first to reduce risk of
race conditions // in your own multithreading x509_free(tmp); } Or in
C++ you could declare a macro-assisted smart pointer type similar to the
following: (NOT TESTED!) (For C++ purists: the macros are used to do the
name pasting needed to refer to individual per-type global function names
and to generate obvious class names such as X509Ptr, all the real work is
done by the C++ template).
#define ASNPTR_TYP(typ) ASNPtr<type, typ##_new, typ##_free> #define
DECLARE_ASNPTR(typ) typedef ASNPTR_TYP(typ) typ##Ptr; class ASNPTRBase {
protected: void *p; public: typedef ASNPTRBase Self; typedef Self* PSelf;
typedef void *PTYP; protected: PTYP Take(void) { PTYP p1 = p; p = 0;
return p1; } ASNPtrBase(): p(0) {} ASNPtrBase(PTYP p1) p(p1) {}
ASNPTRBase(Self &p1) p(p1.Take()) {} ~ASNPTRBase() { } public: bool
operator bool() const { return !!p; } PTYP operator PTYP() const { return
p; } private: Self & operator = (PTYP p1) {}; // Not available, do not
generate default impl. Self & operator = (Self &p1) {}; // Not available,
do not generate default impl. }; template < class ASNT, ASNT*
(*ASNT_new)(void), void (*ASNT_free)(ASNT *p) > class ASNPtr: public
ASNPTRBase { public: typedef ASNPtr Self; typedef Self *PSelf; typedef
ASNT * PTYP; PTYP Take(void) { return (PTYP)ASNPTRBase::Take(); } void
Free(void) { // Must be in template because of type-specic specific call
PTYP p1 = Take(); if (p1) ASNT_free(p1); } ASNPtr &Alloc(void) { // Must
be in template to avoid adding a vptr to the size of ASNPtrBase objects
Free(); p = ASNT_new(); } ASNPtr &Set(PTYP p1) { // Must be in template to
avoid adding a vptr to the size of ASNPtrBase objects Free(); p = p1; }
ASNPtr &Set(ASNPtr &p1) { return Set(p1.Take()); } ASNPtr() {}
ASNPtr(PTYP p1) ASNPTRBase(p1) {} ASNPtr(ASNPtr&p1) ASNPtrBase(p1) {}
~ASNPtr() { Free(); } Self& operator = (PTYP p1) { return Set(p1); } Self&
operator = (Self &p1) { return Set(p1); } PTYP operator PTYP() const {
return p; } private: Self& operator = (const Self &p1) {} // Not
available, do not generate default impl. // do not generate call to
operator=(p1.operator PTYP()) // for const source objects as that would
ruin the // rule that only one ASNPTR can own the object at // any given
time. } DECLARE_ASNPTR(X509) DECLARE_ASNPTR(X509_NAME)
DECLARE_ASNPTR(X509_CRL) // etc.
2. Does X509_free() also free all the internal objects that are part of
the
X509 struct; e.g. X509_ALGOR, X509_NAME, ASN1_INTEGER, ASN1_TIME, etc
Thanks,
Erwin
Please look at the source code of the function ASN1_item_free, which does
the real work.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org