NSS_IMPLEMENT PRStatus nssUTF8_CopyIntoFixedBuffer(NSSUTF8 *string, char *buffer, PRUint32 bufferSize, char pad) { PRUint32 stringSize = 0; #ifdef NSSDEBUG if ((char *)NULL == buffer) { nss_SetError(NSS_ERROR_INVALID_POINTER); return PR_FALSE; } if (0 == bufferSize) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FALSE; } if ((pad & 0x80) != 0x00) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FALSE; } #endif /* NSSDEBUG */ if ((NSSUTF8 *)NULL == string) { string = (NSSUTF8 *)""; } stringSize = nssUTF8_Size(string, (PRStatus *)NULL); stringSize--; /* don't count the trailing null */ if (stringSize > bufferSize) { PRUint32 bs = bufferSize; (void)nsslibc_memcpy(buffer, string, bufferSize); if ((((buffer[bs - 1] & 0x80) == 0x00)) || ((bs > 1) && ((buffer[bs - 2] & 0xE0) == 0xC0)) || ((bs > 2) && ((buffer[bs - 3] & 0xF0) == 0xE0)) || ((bs > 3) && ((buffer[bs - 4] & 0xF8) == 0xF0)) || ((bs > 4) && ((buffer[bs - 5] & 0xFC) == 0xF8)) || ((bs > 5) && ((buffer[bs - 6] & 0xFE) == 0xFC))) { /* It fit exactly */ return PR_SUCCESS; } /* Too long. We have to trim the last character */ for (/*bs*/; bs != 0; bs--) { if ((buffer[bs - 1] & 0xC0) != 0x80) { buffer[bs - 1] = pad; break; } else { buffer[bs - 1] = pad; } } } else { (void)nsslibc_memset(buffer, pad, bufferSize); (void)nsslibc_memcpy(buffer, string, stringSize); } return PR_SUCCESS; }
NSS_IMPLEMENT NSSItem * nssItem_Create ( NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length, const void *data ) { NSSItem *rv = (NSSItem *)NULL; #ifdef DEBUG if( (NSSArena *)NULL != arenaOpt ) { if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { return (NSSItem *)NULL; } } if( (const void *)NULL == data ) { if( length > 0 ) { nss_SetError(NSS_ERROR_INVALID_POINTER); return (NSSItem *)NULL; } } #endif /* DEBUG */ if( (NSSItem *)NULL == rvOpt ) { rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem); if( (NSSItem *)NULL == rv ) { goto loser; } } else { rv = rvOpt; } rv->size = length; rv->data = nss_ZAlloc(arenaOpt, length); if( (void *)NULL == rv->data ) { goto loser; } if( length > 0 ) { (void)nsslibc_memcpy(rv->data, data, length); } return rv; loser: if( rv != rvOpt ) { nss_ZFreeIf(rv); } return (NSSItem *)NULL; }
NSS_IMPLEMENT NSSCKMDObject * nss_builtins_CreateMDObject ( NSSArena *arena, builtinsInternalObject *io, CK_RV *pError ) { if ( (void*)NULL == io->mdObject.etc) { (void) nsslibc_memcpy(&io->mdObject,&builtins_prototype_mdObject, sizeof(builtins_prototype_mdObject)); io->mdObject.etc = (void *)io; } return &io->mdObject; }
static error_stack * error_get_my_stack ( void) { PRStatus st; error_stack *rv; PRUintn new_size; PRUint32 new_bytes; error_stack *new_stack; if( INVALID_TPD_INDEX == error_stack_index ) { st = PR_CallOnce(&error_call_once, error_once_function); if( PR_SUCCESS != st ) { return (error_stack *)NULL; } } rv = (error_stack *)PR_GetThreadPrivate(error_stack_index); if( (error_stack *)NULL == rv ) { /* Doesn't exist; create one */ new_size = 16; } else if( rv->header.count == rv->header.space && rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) { /* Too small, expand it */ new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT); } else { /* Okay, return it */ return rv; } new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack); /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */ new_stack = PR_Calloc(1, new_bytes); if( (error_stack *)NULL != new_stack ) { if( (error_stack *)NULL != rv ) { (void)nsslibc_memcpy(new_stack,rv,rv->header.space); } new_stack->header.space = new_size; } /* Set the value, whether or not the allocation worked */ PR_SetThreadPrivate(error_stack_index, new_stack); return new_stack; }
NSS_IMPLEMENT NSSUTF8 * nssUTF8_Duplicate ( const NSSUTF8 *s, NSSArena *arenaOpt ) { NSSUTF8 *rv; PRUint32 len; #ifdef NSSDEBUG if( (const NSSUTF8 *)NULL == s ) { nss_SetError(NSS_ERROR_INVALID_POINTER); return (NSSUTF8 *)NULL; } if( (NSSArena *)NULL != arenaOpt ) { if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { return (NSSUTF8 *)NULL; } } #endif /* NSSDEBUG */ len = PL_strlen((const char *)s); #ifdef PEDANTIC if( '\0' != ((const char *)s)[ len ] ) { /* must have wrapped, e.g., too big for PRUint32 */ nss_SetError(NSS_ERROR_NO_MEMORY); return (NSSUTF8 *)NULL; } #endif /* PEDANTIC */ len++; /* zero termination */ rv = nss_ZAlloc(arenaOpt, len); if( (void *)NULL == rv ) { return (NSSUTF8 *)NULL; } (void)nsslibc_memcpy(rv, s, len); return rv; }
/* * nss_ckmdSessionObject_GetAttributeTypes * */ static CK_RV nss_ckmdSessionObject_GetAttributeTypes ( NSSCKMDObject *mdObject, NSSCKFWObject *fwObject, NSSCKMDSession *mdSession, NSSCKFWSession *fwSession, NSSCKMDToken *mdToken, NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance, CK_ATTRIBUTE_TYPE_PTR typeArray, CK_ULONG ulCount ) { #ifdef NSSDEBUG CK_RV error = CKR_OK; #endif /* NSSDEBUG */ nssCKMDSessionObject *obj; #ifdef NSSDEBUG error = nss_ckmdSessionObject_verifyPointer(mdObject); if( CKR_OK != error ) { return error; } /* We could even check all the other arguments, for sanity. */ #endif /* NSSDEBUG */ obj = (nssCKMDSessionObject *)mdObject->etc; if( ulCount < obj->n ) { return CKR_BUFFER_TOO_SMALL; } (void)nsslibc_memcpy(typeArray, obj->types, sizeof(CK_ATTRIBUTE_TYPE) * obj->n); return CKR_OK; }
NSS_IMPLEMENT NSSCKMDFindObjects * nss_ckmk_FindObjectsInit ( NSSCKFWSession *fwSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_RV *pError ) { /* This could be made more efficient. I'm rather rushed. */ NSSArena *arena; NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; struct ckmkFOStr *fo = (struct ckmkFOStr *)NULL; ckmkInternalObject **temp = (ckmkInternalObject **)NULL; arena = NSSArena_Create(); if( (NSSArena *)NULL == arena ) { goto loser; } rv = nss_ZNEW(arena, NSSCKMDFindObjects); if( (NSSCKMDFindObjects *)NULL == rv ) { *pError = CKR_HOST_MEMORY; goto loser; } fo = nss_ZNEW(arena, struct ckmkFOStr); if( (struct ckmkFOStr *)NULL == fo ) { *pError = CKR_HOST_MEMORY; goto loser; } fo->arena = arena; /* fo->n and fo->i are already zero */ rv->etc = (void *)fo; rv->Final = ckmk_mdFindObjects_Final; rv->Next = ckmk_mdFindObjects_Next; rv->null = (void *)NULL; fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError); if (*pError != CKR_OK) { goto loser; } fo->objs = nss_ZNEWARRAY(arena, ckmkInternalObject *, fo->n); if( (ckmkInternalObject **)NULL == fo->objs ) { *pError = CKR_HOST_MEMORY; goto loser; } (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckmkInternalObject *) * fo->n); nss_ZFreeIf(temp); temp = (ckmkInternalObject **)NULL; return rv; loser: nss_ZFreeIf(temp); nss_ZFreeIf(fo); nss_ZFreeIf(rv); if ((NSSArena *)NULL != arena) { NSSArena_Destroy(arena); } return (NSSCKMDFindObjects *)NULL; }
NSS_IMPLEMENT NSSUTF8 * nssUTF8_Create(NSSArena *arenaOpt, nssStringType type, const void *inputString, PRUint32 size /* in bytes, not characters */ ) { NSSUTF8 *rv = NULL; #ifdef NSSDEBUG if ((NSSArena *)NULL != arenaOpt) { if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) { return (NSSUTF8 *)NULL; } } if ((const void *)NULL == inputString) { nss_SetError(NSS_ERROR_INVALID_POINTER); return (NSSUTF8 *)NULL; } #endif /* NSSDEBUG */ switch (type) { case nssStringType_DirectoryString: /* This is a composite type requiring BER */ nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE); break; case nssStringType_TeletexString: /* * draft-ietf-pkix-ipki-part1-11 says in part: * * In addition, many legacy implementations support names encoded * in the ISO 8859-1 character set (Latin1String) but tag them as * TeletexString. The Latin1String includes characters used in * Western European countries which are not part of the * TeletexString charcter set. Implementations that process * TeletexString SHOULD be prepared to handle the entire ISO * 8859-1 character set.[ISO 8859-1]. */ nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_PrintableString: /* * PrintableString consists of A-Za-z0-9 ,()+,-./:=? * This is a subset of ASCII, which is a subset of UTF8. * So we can just duplicate the string over. */ if (0 == size) { rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt); } else { rv = nss_ZAlloc(arenaOpt, size + 1); if ((NSSUTF8 *)NULL == rv) { return (NSSUTF8 *)NULL; } (void)nsslibc_memcpy(rv, inputString, size); } break; case nssStringType_UniversalString: /* 4-byte unicode */ nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_BMPString: /* Base Multilingual Plane of Unicode */ nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_UTF8String: if (0 == size) { rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt); } else { rv = nss_ZAlloc(arenaOpt, size + 1); if ((NSSUTF8 *)NULL == rv) { return (NSSUTF8 *)NULL; } (void)nsslibc_memcpy(rv, inputString, size); } break; case nssStringType_PHGString: /* * PHGString is an IA5String (with case-insensitive comparisons). * IA5 is ~almost~ ascii; ascii has dollar-sign where IA5 has * currency symbol. */ nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_GeneralString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; default: nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE); break; } return rv; }
/* * nssCKFWObject_GetAttribute * * Usual NSS allocation rules: * If itemOpt is not NULL, it will be returned; otherwise an NSSItem * will be allocated. If itemOpt is not NULL but itemOpt->data is, * the buffer will be allocated; otherwise, the buffer will be used. * Any allocations will come from the optional arena, if one is * specified. */ NSS_IMPLEMENT NSSItem * nssCKFWObject_GetAttribute ( NSSCKFWObject *fwObject, CK_ATTRIBUTE_TYPE attribute, NSSItem *itemOpt, NSSArena *arenaOpt, CK_RV *pError ) { NSSItem *rv = (NSSItem *)NULL; NSSCKFWItem mdItem; #ifdef NSSDEBUG if( (CK_RV *)NULL == pError ) { return (NSSItem *)NULL; } *pError = nssCKFWObject_verifyPointer(fwObject); if( CKR_OK != *pError ) { return (NSSItem *)NULL; } #endif /* NSSDEBUG */ if( (void *)NULL == (void *)fwObject->mdObject->GetAttribute ) { *pError = CKR_GENERAL_ERROR; return (NSSItem *)NULL; } *pError = nssCKFWMutex_Lock(fwObject->mutex); if( CKR_OK != *pError ) { return (NSSItem *)NULL; } mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject, fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, attribute, pError); if( (NSSItem *)NULL == mdItem.item ) { if( CKR_OK == *pError ) { *pError = CKR_GENERAL_ERROR; } goto done; } if( (NSSItem *)NULL == itemOpt ) { rv = nss_ZNEW(arenaOpt, NSSItem); if( (NSSItem *)NULL == rv ) { *pError = CKR_HOST_MEMORY; goto done; } } else { rv = itemOpt; } if( (void *)NULL == rv->data ) { rv->size = mdItem.item->size; rv->data = nss_ZAlloc(arenaOpt, rv->size); if( (void *)NULL == rv->data ) { *pError = CKR_HOST_MEMORY; if( (NSSItem *)NULL == itemOpt ) { nss_ZFreeIf(rv); } rv = (NSSItem *)NULL; goto done; } } else { if( rv->size >= mdItem.item->size ) { rv->size = mdItem.item->size; } else { *pError = CKR_BUFFER_TOO_SMALL; /* Should we set rv->size to mdItem->size? */ /* rv can't have been allocated */ rv = (NSSItem *)NULL; goto done; } } (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size); if (PR_TRUE == mdItem.needsFreeing) { PR_ASSERT(fwObject->mdObject->FreeAttribute); if (fwObject->mdObject->FreeAttribute) { *pError = fwObject->mdObject->FreeAttribute(&mdItem); } } done: (void)nssCKFWMutex_Unlock(fwObject->mutex); return rv; }
/* # 1022 "arena.c" */ extern void * nss_ZRealloc ( void *pointer, PRUint32 newSize ) { NSSArena *arena; struct pointer_header *h, *new_h; PRUint32 my_newSize = newSize + sizeof(struct pointer_header); void *rv; if( my_newSize < sizeof(struct pointer_header) ) { nss_SetError(NSS_ERROR_NO_MEMORY); return (void *)((void *)0); } if( (void *)((void *)0) == pointer ) { nss_SetError(NSS_ERROR_INVALID_POINTER); return (void *)((void *)0); } h = (struct pointer_header *)((char *)pointer - sizeof(struct pointer_header)); if( newSize == h->size ) { return pointer; } arena = h->arena; if (!arena) { new_h = (struct pointer_header *)PR_Calloc(1, my_newSize); if( (struct pointer_header *)((void *)0) == new_h ) { nss_SetError(NSS_ERROR_NO_MEMORY); return (void *)((void *)0); } new_h->arena = (NSSArena *)((void *)0); new_h->size = newSize; rv = (void *)((char *)new_h + sizeof(struct pointer_header)); if( newSize > h->size ) { (void)nsslibc_memcpy(rv, pointer, h->size); (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size)); } else { (void)nsslibc_memcpy(rv, pointer, newSize); } (void)nsslibc_memset(pointer, 0, h->size); h->size = 0; PR_Free(h); return rv; } else { void *p; if (!arena->lock) { nss_SetError(NSS_ERROR_INVALID_POINTER); return (void *)((void *)0); } PR_Lock(arena->lock); /* # 1107 "arena.c" */ if( newSize < h->size ) { /* # 1120 "arena.c" */ char *extra = &((char *)pointer)[ newSize ]; (void)nsslibc_memset(extra, 0, (h->size - newSize)); PR_Unlock(arena->lock); return pointer; } do { PLArena *_a = (&arena->pool)->current; PRUint32 _nb = (((PRUword)(my_newSize) + (&arena->pool)->mask) & ~(&arena->pool)->mask); PRUword _p = _a->avail; PRUword _q = _p + _nb; if (_q > _a->limit) _p = (PRUword)PL_ArenaAllocate(&arena->pool, _nb); else _a->avail = _q; p = (void *)_p; ; } while (0); if( (void *)((void *)0) == p ) { PR_Unlock(arena->lock); nss_SetError(NSS_ERROR_NO_MEMORY); return (void *)((void *)0); } new_h = (struct pointer_header *)p; new_h->arena = arena; new_h->size = newSize; rv = (void *)((char *)new_h + sizeof(struct pointer_header)); if (rv != pointer) { (void)nsslibc_memcpy(rv, pointer, h->size); (void)nsslibc_memset(pointer, 0, h->size); } (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size)); h->arena = (NSSArena *)((void *)0); h->size = 0; PR_Unlock(arena->lock); return rv; } }
NSS_IMPLEMENT NSSCKMDFindObjects * nss_builtins_FindObjectsInit ( NSSCKFWSession *fwSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_RV *pError ) { /* This could be made more efficient. I'm rather rushed. */ NSSArena *arena; NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; builtinsInternalObject **temp = (builtinsInternalObject **)NULL; PRUint32 i; arena = NSSArena_Create(); if( (NSSArena *)NULL == arena ) { goto loser; } rv = nss_ZNEW(arena, NSSCKMDFindObjects); if( (NSSCKMDFindObjects *)NULL == rv ) { *pError = CKR_HOST_MEMORY; goto loser; } fo = nss_ZNEW(arena, struct builtinsFOStr); if( (struct builtinsFOStr *)NULL == fo ) { *pError = CKR_HOST_MEMORY; goto loser; } fo->arena = arena; /* fo->n and fo->i are already zero */ rv->etc = (void *)fo; rv->Final = builtins_mdFindObjects_Final; rv->Next = builtins_mdFindObjects_Next; rv->null = (void *)NULL; temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, nss_builtins_nObjects); if( (builtinsInternalObject **)NULL == temp ) { *pError = CKR_HOST_MEMORY; goto loser; } for( i = 0; i < nss_builtins_nObjects; i++ ) { builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i]; if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) { temp[ fo->n ] = o; fo->n++; } } fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n); if( (builtinsInternalObject **)NULL == fo->objs ) { *pError = CKR_HOST_MEMORY; goto loser; } (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n); nss_ZFreeIf(temp); temp = (builtinsInternalObject **)NULL; return rv; loser: nss_ZFreeIf(temp); nss_ZFreeIf(fo); nss_ZFreeIf(rv); if ((NSSArena *)NULL != arena) { NSSArena_Destroy(arena); } return (NSSCKMDFindObjects *)NULL; }
/* * Okay, so this implementation sucks. It doesn't support removing * an attribute (if value == NULL), and could be more graceful about * memory. It should allow "blank" slots in the arrays, with some * invalid attribute type, and then it could support removal much * more easily. Do this later. */ static CK_RV nss_ckmdSessionObject_SetAttribute ( NSSCKMDObject *mdObject, NSSCKFWObject *fwObject, NSSCKMDSession *mdSession, NSSCKFWSession *fwSession, NSSCKMDToken *mdToken, NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance, CK_ATTRIBUTE_TYPE attribute, NSSItem *value ) { nssCKMDSessionObject *obj; CK_ULONG i; NSSItem n; NSSItem *ra; CK_ATTRIBUTE_TYPE_PTR rt; #ifdef NSSDEBUG CK_RV error; #endif /* NSSDEBUG */ #ifdef NSSDEBUG error = nss_ckmdSessionObject_verifyPointer(mdObject); if( CKR_OK != error ) { return 0; } /* We could even check all the other arguments, for sanity. */ #endif /* NSSDEBUG */ obj = (nssCKMDSessionObject *)mdObject->etc; n.size = value->size; n.data = nss_ZAlloc(obj->arena, n.size); if (!n.data) { return CKR_HOST_MEMORY; } (void)nsslibc_memcpy(n.data, value->data, n.size); for( i = 0; i < obj->n; i++ ) { if( attribute == obj->types[i] ) { nss_ZFreeIf(obj->attributes[i].data); obj->attributes[i] = n; return CKR_OK; } } /* * It's new. */ ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1)); if (!ra) { nss_ZFreeIf(n.data); return CKR_HOST_MEMORY; } obj->attributes = ra; rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1)); if (!rt) { nss_ZFreeIf(n.data); return CKR_HOST_MEMORY; } obj->types = rt; obj->attributes[obj->n] = n; obj->types[obj->n] = attribute; obj->n++; return CKR_OK; }
/* * nssCKMDSessionObject_Create * */ NSS_IMPLEMENT NSSCKMDObject * nssCKMDSessionObject_Create ( NSSCKFWToken *fwToken, NSSArena *arena, CK_ATTRIBUTE_PTR attributes, CK_ULONG ulCount, CK_RV *pError ) { NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL; nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL; CK_ULONG i; nssCKFWHash *hash; *pError = CKR_OK; mdso = nss_ZNEW(arena, nssCKMDSessionObject); if (!mdso) { goto loser; } mdso->arena = arena; mdso->n = ulCount; mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount); if (!mdso->attributes) { goto loser; } mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount); if (!mdso->types) { goto loser; } for( i = 0; i < ulCount; i++ ) { mdso->types[i] = attributes[i].type; mdso->attributes[i].size = attributes[i].ulValueLen; mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen); if (!mdso->attributes[i].data) { goto loser; } (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue, attributes[i].ulValueLen); } mdObject = nss_ZNEW(arena, NSSCKMDObject); if (!mdObject) { goto loser; } mdObject->etc = (void *)mdso; mdObject->Finalize = nss_ckmdSessionObject_Finalize; mdObject->Destroy = nss_ckmdSessionObject_Destroy; mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject; mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount; mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes; mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize; mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute; mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute; mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize; hash = nssCKFWToken_GetSessionObjectHash(fwToken); if (!hash) { *pError = CKR_GENERAL_ERROR; goto loser; } mdso->hash = hash; *pError = nssCKFWHash_Add(hash, mdObject, mdObject); if( CKR_OK != *pError ) { goto loser; } #ifdef DEBUG if(( *pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK ) { goto loser; } #endif /* DEBUG */ return mdObject; loser: if (mdso) { if (mdso->attributes) { for( i = 0; i < ulCount; i++ ) { nss_ZFreeIf(mdso->attributes[i].data); } nss_ZFreeIf(mdso->attributes); } nss_ZFreeIf(mdso->types); nss_ZFreeIf(mdso); } nss_ZFreeIf(mdObject); if (*pError == CKR_OK) { *pError = CKR_HOST_MEMORY; } return (NSSCKMDObject *)NULL; }