Hi,
Maybe i'm not doing this right, but according to Valgrind
calling XSECCryptoHash is leaking mem,
here's how i'm calling it.


// start of code 
int GetSHA1Hash(unsigned char *pData, unsigned int pLen, char *pASCIIHash)
{
    unsigned char hash[SHA_DIGEST_LENGTH];
    XSECCryptoHash * sha1 = NULL;

    try {
        sha1 = XSECPlatformUtils::g_cryptoProvider->hashSHA1();
    }
    catch (XSECException &e)
    {
        cout << "Error xsec " << XMLString::transcode(e.getMsg()) << endl;
    }

    if (!sha1)
    {
     
        printf("GetSHA1Hash: Error ::CryptoProviderError\n");
        return -1;
    }
    //Janitor<XSECCryptoHash> j_sha1(sha1);
    
    sha1->reset();
    sha1->hash(pData, pLen);
    sha1->finish(hash, 160);

    char *ptr = pASCIIHash; 
    memset(ptr, 0, ((SHA_DIGEST_LENGTH *2) + 1));

    for (int i= 0; i < SHA_DIGEST_LENGTH; i++) {
        ptr += sprintf(ptr, "%02x", hash[i]);
    }
    sha1->reset();
    delete(sha1);
    return 0;
}


here's the valgrind output 

==15465== 11,200 bytes in 112 blocks are definitely lost in loss record 15 of 18
==15465==    at 0x4021620: malloc (vg_replace_malloc.c:149)
==15465==    by 0x407174D: (within /usr/lib/i686/cmov/libcrypto.so.0.9.8)
==15465==    by 0x4071DCE: CRYPTO_malloc (in 
/usr/lib/i686/cmov/libcrypto.so.0.9.8)
==15465==    by 0x40DFF30: EVP_DigestInit_ex (in 
/usr/lib/i686/cmov/libcrypto.so.0.9.8)
==15465==    by 0x40E00A8: EVP_DigestInit (in 
/usr/lib/i686/cmov/libcrypto.so.0.9.8)
==15465==    by 0x4201DFC: 
OpenSSLCryptoHash::OpenSSLCryptoHash(XSECCryptoHash::HashType) (in 
/usr/lib/libxml-security-c.so.12.0)
==15465==    by 0x4206407: OpenSSLCryptoProvider::hashSHA1() (in 
/usr/lib/libxml-security-c.so.12.0)
==15465==    by 0x805A9F4: GetSHA1Hash(unsigned char*, unsigned, char*) 
(GenXml.cpp:264)

not knowing what to do other than calling the destructor of XSECCryptoHash, I 
then replaced the XSECCryptoHash call with direct OPENSSL call
and the valgrind stopped complaining, here how it look with openSSL.

unsigned char *doSha1Hash(const void* const pSrcData, size_t pDataSize)
{
    unsigned char *hash = NULL;
    SHA_CTX shaCTX;

    // init the context.

    if (!SHA1_Init(&shaCTX)) {
        ERROR_LOG("error SHA1 init failed \r\n");
        return NULL;
    }

    //CRYPT_DEBUG_LOG("computing SHA1 hash for data of len %d\r\n", pDataSize);

    // compute the sha1 hash.
    SHA1_Update(&shaCTX, pSrcData, pDataSize);
    hash = (unsigned char *) malloc(SHA_DIGEST_LENGTH);

    if (!hash) {
        ERROR_LOG("error malloc in hash data\r\n");
        goto end;
    }

    if (!SHA1_Final(hash, &shaCTX))
    {
        free(hash);
        return NULL;
    }

    end:
    OPENSSL_cleanse(&shaCTX, sizeof(shaCTX));
    return hash;
}

int getSHA1Hash(unsigned char *pData, unsigned int pLen, char *pASCIIHash)
{
    unsigned char *hash = doSha1Hash(pData, pLen);
    char *ptr = pASCIIHash; 
    memset(ptr, 0, ((SHA_DIGEST_LENGTH *2) + 1));

    for (int i= 0; i < SHA_DIGEST_LENGTH; i++) {
        ptr += sprintf(ptr, "%02x", hash[i]);
    }
    free(hash);
    return 0;
}


What I don't understand is why XSECCryptoHash isn't cleaning up even after it's 
destructor is called, Or is there something i'm missing to do.

AFAIC remember i saw a similar usage in the sample code for xml-security-c, 
i followed the way it's called in everywhere else in xml-sec and used the 
Janitor<XSECCryptoHash> j_sha1(sha1); to do the clean up but that did make 
valgrind happy either, 
and the later resorted to a more explicit way to cleanup by calling delete (as 
you would see in the code above).

Let me know if you have any question. 


Any insights would really be appreciated.

thanks 
Bisla


_________________________________________________________________
Discover the new Windows Vista
http://search.msn.com/results.aspx?q=windows+vista&mkt=en-US&form=QBRE

Reply via email to