You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by "Cullum, Steve" <st...@eds.com> on 2005/10/13 14:38:57 UTC

RE: why would this code fragment cause XSec1.2.0 to leak memory?

I think this may be the problem..inside the destructor
~WinCAPICryptoKeyRSA::CryptDestroyKey() never gets called. 
 
I this is already fixed in the CVS release...sorry!!! to waste your time
 
WinCAPICryptoKeyRSA::~WinCAPICryptoKeyRSA() 
{
    // If we have a RSA, delete it
    if (m_key == 0)
        CryptDestroyKey(m_key);
/**
 ** Shouldnt this be
 
    if (m_key != 0)
        CryptDestroyKey(m_key);
 **
 **/
 
    if (mp_exponent)
      delete[] mp_exponent;
 
    if (mp_modulus)
      delete[] mp_modulus;
};
 
 
 
________________________________

From: Cullum, Steve [mailto:steven.cullum@eds.com] 
Sent: 13 October 2005 13:01
To: security-dev@xml.apache.org
Subject: RE: why would this code fragment cause XSec1.2.0 to leak
memory?



	Okay.. my memory leak seems to occur as soon as i call
X509->clonePublicKey().
	 
	Calling prov->releaseSignature(sig) does not seem to release
memory for the key.
	 
	The entire test driver that recreates the memory leak is shown..
I am basically doing what the documentations except i call the signature
validation in a loop.
	 
	While(1)
	{
	    XercesDOMParser parser;
	    parser.setDoNamespaces(true);
	    parser.setCreateEntityReferenceNodes(true);
	    parser.setDoSchema(true);
	 
	    MemBufInputSource *memIS = new MemBufInputSource((const
XMLByte *)buffer, bufferLen,    "XSECMem", false);
	      
	    parser.parse(*memIS);
	    delete memIS;                               // destroy as
soon as possible
	    
	    // Now create a signature object to validate the document
	    XSECProvider prov;
	    DSIGSignature *sig =
prov.newSignatureFromDOM(parser.getDocument()); 
	 
	    sig->registerIdAttributeName(config.idAttributeName);
	    sig->registerIdAttributeNameNS(config.idAttributeNS,
config.idAttributeName);
	    sig->load();  
	    sig->setSigningKey(X509->clonePublicKey());        // memory
just goes up.. and up.. when i clone a key 
	    sig->verify();
	
	    prov->releaseSignature(sig);
	}
	 
	 



________________________________

		From: Cullum, Steve [mailto:steven.cullum@eds.com] 
		Sent: 12 October 2005 17:08
		To: security-dev@xml.apache.org
		Subject: RE: why would this code fragment cause
XSec1.2.0 to leak memory?
		
		
		Thanks Jesse, i have run this under a release and debug
build and nothing is indicated.  I know its in this code fragmant, as my
application can run for hours on end with no memory issues.  
		 
		Turning on ValidateSig() causes a slow but sure memory
increase.  AFAIK i have deleted/free'd all objects that xml-sec is using
and still my memory usage increases.
		 
		Is there anything obviously amiss with this code
fragment?  Am i calling fn()'s in the incorrect order, doing anything
that could result in undefined behaviour etc.
		 
		 
		    XercesDOMParser parser;
		    parser.setDoNamespaces(true);
		    parser.setCreateEntityReferenceNodes(true);
		    parser.setDoSchema(true);
		 
		    MemBufInputSource *memIS = new
MemBufInputSource((const XMLByte *)buffer, bufferLen,    "XSECMem",
false);
		      
		    parser.parse(*memIS);
		    delete memIS;                               //
destroy as soon as possible
		    
		    // Now create a signature object to validate the
document
		    XSECProvider prov;
		    DSIGSignature *sig =
prov.newSignatureFromDOM(parser.getDocument()); 
		 
	
sig->registerIdAttributeName(config.idAttributeName);
		    sig->registerIdAttributeNameNS(config.idAttributeNS,
config.idAttributeName);
		    sig->load();  
		    sig->setSigningKey(X509->clonePublicKey());
		    sig->verify();
		
		    prov->releaseSignature(sig);
		
		 
		 


________________________________

			From: Jesse Pelton [mailto:jsp@PKC.com] 
			Sent: 12 October 2005 16:44
			To: security-dev@xml.apache.org
			Subject: RE: why would this code fragment cause
XSec1.2.0 to leak memory?
			
			
			Have you tried running a debug build of your
code under the debugger? After the program terminates, you may find
memory leaks listed in the output window. Sometimes there's enough
information to make it obvious where the leak is, sometimes not. (It's a
good idea to do this in the course of development; it's much easier to
locate the problem if you know it's in code you're working on.)


________________________________

				From: Cullum, Steve
[mailto:steven.cullum@eds.com] 
				Sent: Wednesday, October 12, 2005 11:07
AM
				To: security-dev@xml.apache.org
				Subject: why would this code fragment
cause XSec1.2.0 to leak memory?
				
				
				Can someone please help me or point me
in the right direction. When running my application memory usage
increases slowly by about 6mb / hour.  Commenting out the function
digital signature validation routing ValidateSig() stops the memory
increase. 
				 
				a) I am getting no errors, so the leak
can is not inside my "catch" constructs.   
				b) I am using the MS Crypto api .. (is
that relevant??)
				c) I am linking to xerces-c_2_6.dll
[release] and xsec_1_2_0.dll [release] with no XALAN support on Windows
2003 compiled with VS2003.net
				 
				I have looked up & down this source and
can see no obvious mistakes!  
				 
				Can anyone help me please?
				 
				 
				 
				 
				 
				BOOL ValidateSig()
				{
				  //
				  // parse the XML document, load in the
signature field and attempt to validate it using a copy of the
				  // X509 public key we create earlier
from the certificate store.
				  //
				  BOOL valid = FALSE;
				  try
				  {
				    XercesDOMParser parser;
				    parser.setDoNamespaces(true);
	
parser.setCreateEntityReferenceNodes(true);
				    parser.setDoSchema(true);
				 
				    MemBufInputSource *memIS = new
MemBufInputSource((const XMLByte *)buffer, bufferLen, "XSECMem", false);
				      
				    parser.parse(*memIS);
				    delete memIS;
// destroy as soon as possible
				    if(parser.getErrorCount() > 0) 
				    {
				      Display( "Error parsing input
document", "error in XML parse", buffer, bufferLen) );
				      return FALSE;
				    } 
				 
				    // Now create a signature object to
validate the document
				    XSECProvider prov;
				    DSIGSignature *sig =
prov.newSignatureFromDOM(parser.getDocument());
				 
	
sig->registerIdAttributeName(config.idAttributeName);
	
sig->registerIdAttributeNameNS(config.idAttributeNS,
config.idAttributeName);
				    sig->load();  
	
sig->setSigningKey(X509->clonePublicKey());
				    if(sig->verify()) 
				    {
				      Display(_T("Signature
Valid...OK"));
				      valid = TRUE;  // the only way to
set this is if this fn() is successfull
				    }
				    else 
				    {
				      char *err =
XMLString::transcode(sig->getErrMsgs());
				      Display("Error parsing [or]
validating document", err, buffer, bufferLen);
				      XSEC_RELEASE_XMLCH(err);
				      Display("Error parsing [or]
validating document\n%s", sig->getErrMsgs());
				    }
				 
				    prov->releaseSignature(sig);
				  }
				  catch(XSECException &e) // signature
related errors
				  {
				    char *err =
XMLString::transcode(e.getMsg());
				    Display( "An error occured during
signature load", err, buffer, bufferLen); 
				    XSEC_RELEASE_XMLCH(err);
				    Display(_T("An error occured during
signature load\n%s", e.getMsg());  // e.getMsg() is WIDE 
				  }
				  catch(const XMLException &e) // xml
related parsing errors
				  {
				    char *err =
XMLString::transcode(e.getMessage());
				    Display("An error occured during
xerces parsing and loading of xml", err, buffer, bufferLen); 
				    XSEC_RELEASE_XMLCH(err);
				    Display( _T("An error occured during
xerces parsing and loading of xml\n%s"), e.getMessage()); //
e.getMessage() is WIDE
				  }
				 
				  return valid;
				}
				
				 
				 
				// XSec startup code && x509
constuction.. dont think its relevant here.
				 
				
				SomeConstructor()
				{
				  // startup xerces & xsec for signature
validation
				  // because parts of the Apache
signature library are not thread safe - all initialisation
				  // now takes place inside the
constructor - rather than the preferred Init() method.
				  // i NEVER destroy the cryptoProv
object... it is owned by XSEC and is killed vie
XSECPlatformUtils::Terminate()
				  // 
				  try 
				  {
				    // initialize xerces xml parser and
the Apache XML-Security library
				    XMLPlatformUtils::Initialize();
				    XSECPlatformUtils::Initialise();  
				 
				    cryptoProv = new
WinCAPICryptoProvider(NULL, NULL, 0);
	
XSECPlatformUtils::SetCryptoProvider(cryptoProv);       // this is set
"globally" 
				  }
				  catch(const XMLException &e)
				  {
				    throw; // rethrow..to waiting
handler
				  }
				}
				 
				BOOL CreateX509()
				{
				  //
				  // load the public key from the
certificate store.  
				  // install the key as a service
certificate using mmc->certificates->services certificate, 
				  // browse for the "microsoft firewall"
and install the cert in the Trusted Root Authority.
				  // For example the "microsoft
firewall" uses the storeName L"fwsrv\Root" 
				  //
				  HCERTSTORE     certStore = NULL;
				  PCCERT_CONTEXT certContext = NULL; 
				  DWORD          certOpenFlags =
CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_SERVICES |
CERT_STORE_READONLY_FLAG;
				 
				  // open the store .. fail if the store
does not exist, look in the services store, open for readonly
				  certStore =
CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, certOpenFlags,
config.storeName);
				  if(certStore == NULL)
				  {
				    _com_error e(GetLastError());
				    return FALSE;
				  }
				 
				  // find signer's certificate
				  certContext =
CertFindCertificateInStore(certStore, (PKCS_7_ASN_ENCODING |
X509_ASN_ENCODING), 0, CERT_FIND_SUBJECT_STR, config.signerName , NULL);
				  CertCloseStore(certStore, 0); // close
the store regardless
				  if(certContext == NULL)
				  {  
				    _com_error e(GetLastError());
				    return FALSE;
				  }
				 
				  try
				  {
				    if(X509 != NULL)  // if we have
already been created .. then destroy and re-create
				      delete X509;    // X509 destructor
takes care of CertFreeCertificateContext()
				    X509 = new
WinCAPICryptoX509(certContext, cryptoProv->getProviderRSA(),
cryptoProv->getProviderDSS()); 
				  }
				  catch(XSECCryptoException &e) 
				  {
				    delete X509;
				    return FALSE;
				  }
				 
				  return TRUE;
				}