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:[EMAIL PROTECTED]
Sent: Wednesday, October 12, 2005 11:07 AM
To: [email protected]
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;
}
 
 

Reply via email to