apr_crypto_nss: Ensure the SECItem returned by PK11_ParamFromIV
is properly freed.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1751898 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES b/CHANGES
index 5d65a65..90348e7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes for APR 2.0.0
+ *) apr_crypto_nss: Ensure the SECItem returned by PK11_ParamFromIV
+ is properly freed. [Graham Leggett]
+
*) apr_crypto: Don't cache the driver if initialisation fails. This
stops the second and subsequent attempt to use the API from failing
claiming the library is not initialised. [Graham Leggett]
diff --git a/crypto/apr_crypto_nss.c b/crypto/apr_crypto_nss.c
index 1a92c85..8949b6b 100644
--- a/crypto/apr_crypto_nss.c
+++ b/crypto/apr_crypto_nss.c
@@ -77,6 +77,7 @@
const apr_crypto_t *f;
PK11Context *ctx;
apr_crypto_key_t *key;
+ SECItem *secParam;
int blockSize;
};
@@ -108,6 +109,8 @@
if (NSS_IsInitialized()) {
SECStatus s = NSS_Shutdown();
if (s != SECSuccess) {
+ fprintf(stderr, "NSS failed to shutdown, possible leak: %d: %s",
+ PR_GetError(), PR_ErrorToName(s));
return APR_EINIT;
}
}
@@ -216,6 +219,11 @@
err->reason = apr_pstrdup(pool, "Error during 'nss' initialisation");
*result = err;
}
+ s = NSS_Shutdown();
+ if (s != SECSuccess) {
+ return APR_ECRYPT;
+ }
+
return APR_ECRYPT;
}
@@ -235,6 +243,11 @@
static apr_status_t crypto_block_cleanup(apr_crypto_block_t *block)
{
+ if (block->secParam) {
+ SECITEM_FreeItem(block->secParam, PR_TRUE);
+ block->secParam = NULL;
+ }
+
if (block->ctx) {
PK11_DestroyContext(block->ctx, PR_TRUE);
block->ctx = NULL;
@@ -536,7 +549,6 @@
apr_size_t *blockSize, apr_pool_t *p)
{
PRErrorCode perr;
- SECItem * secParam;
SECItem ivItem;
unsigned char * usedIv;
apr_crypto_block_t *block = *ctx;
@@ -575,14 +587,14 @@
}
ivItem.data = usedIv;
ivItem.len = key->ivSize;
- secParam = PK11_ParamFromIV(key->cipherMech, &ivItem);
+ block->secParam = PK11_ParamFromIV(key->cipherMech, &ivItem);
}
else {
- secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
+ block->secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
}
- block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
+ block->blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam);
block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_ENCRYPT,
- key->symKey, secParam);
+ key->symKey, block->secParam);
/* did an error occur? */
perr = PORT_GetError();
@@ -593,7 +605,7 @@
}
if (blockSize) {
- *blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
+ *blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam);
}
return APR_SUCCESS;
@@ -717,7 +729,6 @@
const apr_crypto_key_t *key, apr_pool_t *p)
{
PRErrorCode perr;
- SECItem * secParam;
apr_crypto_block_t *block = *ctx;
if (!block) {
*ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
@@ -739,14 +750,14 @@
}
ivItem.data = (unsigned char*) iv;
ivItem.len = key->ivSize;
- secParam = PK11_ParamFromIV(key->cipherMech, &ivItem);
+ block->secParam = PK11_ParamFromIV(key->cipherMech, &ivItem);
}
else {
- secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
+ block->secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
}
- block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
+ block->blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam);
block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_DECRYPT,
- key->symKey, secParam);
+ key->symKey, block->secParam);
/* did an error occur? */
perr = PORT_GetError();
@@ -757,7 +768,7 @@
}
if (blockSize) {
- *blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
+ *blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam);
}
return APR_SUCCESS;