summaryrefslogtreecommitdiffstats
path: root/pinst.c
diff options
context:
space:
mode:
authorKamil Dudka <kdudka@redhat.com>2009-08-20 11:04:14 +0200
committerRob Crittenden <rcritten@redhat.com>2009-08-20 10:58:37 -0400
commit99286597662891ac69146fce6590a435331938cd (patch)
treeea9a52d2c65ba57967357cb7b23cdb3967c343dd /pinst.c
parent6f7f653c5dc2deca95d3453d706ddc4c2eb46e70 (diff)
downloadpemnss-99286597662891ac69146fce6590a435331938cd.tar.gz
pemnss-99286597662891ac69146fce6590a435331938cd.tar.xz
pemnss-99286597662891ac69146fce6590a435331938cd.zip
implement memory management for internal objects
* ckpem.h: Define list objects, add reference counter to internal objects. * pfind.c: Increase object's reference while exporting. Skip already freed objects. * pinst.c (AddObjectIfNeeded): New function providing sharing of internal objects. * pobject.c: Add support for list objects. Implement pem_mdObject_Finalize(). * psession.c (pem_mdSession_CopyObject): Increase reference count only. Signed-off-by: Kamil Dudka <kdudka@redhat.com>
Diffstat (limited to 'pinst.c')
-rw-r--r--pinst.c112
1 files changed, 70 insertions, 42 deletions
diff --git a/pinst.c b/pinst.c
index c995b14..d92cd19 100644
--- a/pinst.c
+++ b/pinst.c
@@ -56,24 +56,6 @@ PRInt32 count = 0;
#define PEM_ITEM_CHUNK 512
-#define PUT_Object(obj,err) \
- { \
- if (count >= size) { \
- gobj = gobj ? \
- nss_ZREALLOCARRAY(gobj, pemInternalObject *, \
- (size+PEM_ITEM_CHUNK) ) : \
- nss_ZNEWARRAY(NULL, pemInternalObject *, \
- (size+PEM_ITEM_CHUNK) ) ; \
- if ((pemInternalObject **)NULL == gobj) { \
- err = CKR_HOST_MEMORY; \
- goto loser; \
- } \
- size += PEM_ITEM_CHUNK; \
- } \
- (gobj)[ count ] = (obj); \
- count++; \
- }
-
/*
* simple cert decoder to avoid the cost of asn1 engine
*/
@@ -195,7 +177,7 @@ GetCertFields(unsigned char *cert, int cert_length,
return SECSuccess;
}
-pemInternalObject *
+static pemInternalObject *
CreateObject(CK_OBJECT_CLASS objClass,
pemObjectType type, SECItem * certDER,
SECItem * keyDER, char *filename,
@@ -286,6 +268,67 @@ CreateObject(CK_OBJECT_CLASS objClass,
return o;
}
+pemInternalObject *
+AddObjectIfNeeded(CK_OBJECT_CLASS objClass,
+ pemObjectType type, SECItem * certDER,
+ SECItem * keyDER, char *filename,
+ int objid, CK_SLOT_ID slotID)
+{
+ int i;
+
+ /* FIXME: copy-pasted from CreateObject */
+ const char *nickname = strrchr(filename, '/');
+ if (nickname)
+ nickname++;
+ else
+ nickname = filename;
+
+ /* first look for the object in gobj, it might be already there */
+ for (i = 0; i < pem_nobjs; i++) {
+ if (NULL == gobj[i])
+ continue;
+
+ if ((gobj[i]->objClass == objClass)
+ && (gobj[i]->type == type)
+ && (gobj[i]->slotID == slotID)
+#if 0
+ /* FIXME: is it safe to return object with different objid? */
+ && (atoi(gobj[i]->id.data) == objid)
+#endif
+ && (0 == strcmp(gobj[i]->nickname, nickname))) {
+
+ plog("AddObjectIfNeeded: re-using internal object #%i\n", i);
+ gobj[i]->refCount ++;
+ return gobj[i];
+ }
+ }
+
+ /* object not found, we need to create it */
+ pemInternalObject *io = CreateObject(objClass, type, certDER, keyDER,
+ filename, objid, slotID);
+
+ io->gobjIndex = count;
+
+ /* add object to global array */
+ if (count >= size) {
+ gobj = gobj ?
+ nss_ZREALLOCARRAY(gobj, pemInternalObject *,
+ (size+PEM_ITEM_CHUNK) ) :
+ nss_ZNEWARRAY(NULL, pemInternalObject *,
+ (size+PEM_ITEM_CHUNK) ) ;
+
+ if ((pemInternalObject **)NULL == gobj)
+ return NULL;
+ size += PEM_ITEM_CHUNK;
+ }
+ gobj[count] = io;
+ count++;
+ pem_nobjs++;
+
+ io->refCount ++;
+ return io;
+}
+
CK_RV
AddCertificate(char *certfile, char *keyfile, PRBool cacert,
CK_SLOT_ID slotID)
@@ -314,44 +357,37 @@ AddCertificate(char *certfile, char *keyfile, PRBool cacert,
snprintf(nickname, 1024, "%s - %d", certfile, i);
- o = CreateObject(CKO_CERTIFICATE, pemCert, objs[i], NULL,
- nickname, 0, slotID);
+ o = AddObjectIfNeeded(CKO_CERTIFICATE, pemCert, objs[i], NULL,
+ nickname, 0, slotID);
if (o == NULL) {
error = CKR_GENERAL_ERROR;
goto loser;
}
- PUT_Object(o, error);
if (error != CKR_OK)
goto loser;
o = NULL;
- pem_nobjs++;
/* Add the CA trust object */
- o = CreateObject(CKO_NETSCAPE_TRUST, pemTrust, objs[i], NULL,
- nickname, 0, slotID);
+ o = AddObjectIfNeeded(CKO_NETSCAPE_TRUST, pemTrust, objs[i], NULL,
+ nickname, 0, slotID);
if (o == NULL) {
error = CKR_GENERAL_ERROR;
goto loser;
}
- PUT_Object(o, error);
- pem_nobjs++;
} /* for */
} else {
objid = pem_nobjs + 1;
- o = CreateObject(CKO_CERTIFICATE, pemCert, objs[0], NULL, certfile,
- objid, slotID);
+ o = AddObjectIfNeeded(CKO_CERTIFICATE, pemCert, objs[0], NULL, certfile,
+ objid, slotID);
if (o == NULL) {
error = CKR_GENERAL_ERROR;
goto loser;
}
- PUT_Object(o, error);
-
if (error != CKR_OK)
goto loser;
o = NULL;
- pem_nobjs++;
if (keyfile) { /* add the private key */
SECItem **keyobjs = NULL;
@@ -363,15 +399,12 @@ AddCertificate(char *certfile, char *keyfile, PRBool cacert,
error = CKR_GENERAL_ERROR;
goto loser;
}
- o = CreateObject(CKO_PRIVATE_KEY, pemBareKey, objs[0],
- keyobjs[0], certfile, objid, slotID);
+ o = AddObjectIfNeeded(CKO_PRIVATE_KEY, pemBareKey, objs[0],
+ keyobjs[0], certfile, objid, slotID);
if (o == NULL) {
error = CKR_GENERAL_ERROR;
goto loser;
}
-
- PUT_Object(o, error);
- pem_nobjs++;
}
}
@@ -487,15 +520,10 @@ pem_Finalize
NSSCKFWInstance * fwInstance
)
{
- int i;
-
plog("pem_Finalize\n");
if (!pemInitialized)
return;
- for (i = 0; i < pem_nobjs; ++i)
- pem_DestroyInternalObject(gobj[i]);
-
nss_ZFreeIf(gobj);
gobj = NULL;