/* # 404 "arena.c" */ NSSArena * nssArena_Create ( void ) { NSSArena *rv = (NSSArena *)((void *)0); rv = ((NSSArena *)nss_ZAlloc(((NSSArena *)((void *)0)), sizeof(NSSArena))); if( (NSSArena *)((void *)0) == rv ) { nss_SetError(NSS_ERROR_NO_MEMORY); return (NSSArena *)((void *)0); } rv->lock = PR_NewLock(); if( (PRLock *)((void *)0) == rv->lock ) { (void)nss_ZFreeIf(rv); nss_SetError(NSS_ERROR_NO_MEMORY); return (NSSArena *)((void *)0); } /* # 442 "arena.c" */ PL_InitArenaPool(&rv->pool, "NSS", 2048, sizeof(double)); /* # 457 "arena.c" */ return rv; }
NSS_IMPLEMENT NSSItem * nssToken_FinishDigest ( NSSToken *tok, nssSession *sessionOpt, NSSItem *rvOpt, NSSArena *arenaOpt ) { CK_RV ckrv; CK_ULONG digestLen; CK_BYTE_PTR digest; NSSItem *rvItem = NULL; void *epv = nssToken_GetCryptokiEPV(tok); nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; /* Don't ask the module to use an invalid session handle. */ if (!session || session->handle == CK_INVALID_SESSION) { PORT_SetError(SEC_ERROR_NO_TOKEN); return NULL; } nssSession_EnterMonitor(session); ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); if (ckrv != CKR_OK || digestLen == 0) { nssSession_ExitMonitor(session); return NULL; } digest = NULL; if (rvOpt) { if (rvOpt->size > 0 && rvOpt->size < digestLen) { nssSession_ExitMonitor(session); /* the error should be bad args */ return NULL; } if (rvOpt->data) { digest = rvOpt->data; } digestLen = rvOpt->size; } if (!digest) { digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); if (!digest) { nssSession_ExitMonitor(session); return NULL; } } ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); nssSession_ExitMonitor(session); if (ckrv != CKR_OK) { nss_ZFreeIf(digest); return NULL; } if (!rvOpt) { rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); } return rvItem; }
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; }
static CK_RV nss_dbm_db_unwrap_object ( NSSArena *arena, DBT *object, CK_ATTRIBUTE_PTR *ppTemplate, CK_ULONG *pulAttributeCount ) { CK_ULONG *pulData; char *pcData; CK_ULONG n, i; CK_ATTRIBUTE_PTR pTemplate; pulData = (CK_ULONG *)object->data; pcData = (char *)object->data; n = ntohl(pulData[0]); *pulAttributeCount = n; pTemplate = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, n); if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { return CKR_HOST_MEMORY; } for( i = 0; i < n; i++ ) { CK_ULONG len; CK_ULONG offset; void *p; pTemplate[i].type = ntohl(pulData[1 + i*3]); len = ntohl(pulData[2 + i*3]); offset = ntohl(pulData[3 + i*3]); p = nss_ZAlloc(arena, len); if( (void *)NULL == p ) { return CKR_HOST_MEMORY; } nss_dbm_db_swap_copy(pTemplate[i].type, p, &pcData[offset], len); pTemplate[i].ulValueLen = len; pTemplate[i].pValue = p; } *ppTemplate = pTemplate; return CKR_OK; }
static void * PR_CALLBACK nss_arena_hash_alloc_table ( void *pool, PRSize size ) { NSSArena *arena = (NSSArena *)NULL; #ifdef NSSDEBUG if( (void *)NULL != arena ) { if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { return (void *)NULL; } } #endif /* NSSDEBUG */ return nss_ZAlloc(arena, size); }
static CK_RV nss_dbm_db_wrap_object ( NSSArena *arena, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, DBT *object ) { CK_ULONG object_size; CK_ULONG i; CK_ULONG *pulData; char *pcData; CK_ULONG offset; object_size = (1 + ulAttributeCount*3) * sizeof(CK_ULONG); offset = object_size; for( i = 0; i < ulAttributeCount; i++ ) { object_size += pTemplate[i].ulValueLen; } object->size = object_size; object->data = nss_ZAlloc(arena, object_size); if( (void *)NULL == object->data ) { return CKR_HOST_MEMORY; } pulData = (CK_ULONG *)object->data; pcData = (char *)object->data; pulData[0] = htonl(ulAttributeCount); for( i = 0; i < ulAttributeCount; i++ ) { CK_ULONG len = pTemplate[i].ulValueLen; pulData[1 + i*3] = htonl(pTemplate[i].type); pulData[2 + i*3] = htonl(len); pulData[3 + i*3] = htonl(offset); nss_dbm_db_swap_copy(pTemplate[i].type, &pcData[offset], pTemplate[i].pValue, len); offset += len; } return CKR_OK; }
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_IMPLEMENT NSSItem * nssToken_Digest ( NSSToken *tok, nssSession *sessionOpt, NSSAlgorithmAndParameters *ap, NSSItem *data, NSSItem *rvOpt, NSSArena *arenaOpt ) { CK_RV ckrv; CK_ULONG digestLen; CK_BYTE_PTR digest; NSSItem *rvItem = NULL; void *epv = nssToken_GetCryptokiEPV(tok); nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; /* Don't ask the module to use an invalid session handle. */ if (!session || session->handle == CK_INVALID_SESSION) { PORT_SetError(SEC_ERROR_NO_TOKEN); return rvItem; } nssSession_EnterMonitor(session); ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); return NULL; } #if 0 /* XXX the standard says this should work, but it doesn't */ ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); return NULL; } #endif digestLen = 0; /* XXX for now */ digest = NULL; if (rvOpt) { if (rvOpt->size > 0 && rvOpt->size < digestLen) { nssSession_ExitMonitor(session); /* the error should be bad args */ return NULL; } if (rvOpt->data) { digest = rvOpt->data; } digestLen = rvOpt->size; } if (!digest) { digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); if (!digest) { nssSession_ExitMonitor(session); return NULL; } } ckrv = CKAPI(epv)->C_Digest(session->handle, (CK_BYTE_PTR)data->data, (CK_ULONG)data->size, (CK_BYTE_PTR)digest, &digestLen); nssSession_ExitMonitor(session); if (ckrv != CKR_OK) { nss_ZFreeIf(digest); return NULL; } if (!rvOpt) { rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); } return rvItem; }
static NSSCKMDObject * nss_dbm_mdFindObjects_Next ( NSSCKMDFindObjects *mdFindObjects, NSSCKFWFindObjects *fwFindObjects, NSSCKMDSession *mdSession, NSSCKFWSession *fwSession, NSSCKMDToken *mdToken, NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance, NSSArena *arena, CK_RV *pError ) { nss_dbm_find_t *find = (nss_dbm_find_t *)mdFindObjects->etc; struct nss_dbm_dbt_node *node; nss_dbm_object_t *object; NSSCKMDObject *rv; while(1) { /* Lock */ { *pError = NSSCKFWMutex_Lock(find->list_lock); if( CKR_OK != *pError ) { return (NSSCKMDObject *)NULL; } node = find->found; if( (struct nss_dbm_dbt_node *)NULL != node ) { find->found = node->next; } *pError = NSSCKFWMutex_Unlock(find->list_lock); if( CKR_OK != *pError ) { /* screwed now */ return (NSSCKMDObject *)NULL; } } if( (struct nss_dbm_dbt_node *)NULL == node ) { break; } if( nss_dbm_db_object_still_exists(node->dbt) ) { break; } } if( (struct nss_dbm_dbt_node *)NULL == node ) { *pError = CKR_OK; return (NSSCKMDObject *)NULL; } object = nss_ZNEW(arena, nss_dbm_object_t); if( (nss_dbm_object_t *)NULL == object ) { *pError = CKR_HOST_MEMORY; return (NSSCKMDObject *)NULL; } object->arena = arena; object->handle = nss_ZNEW(arena, nss_dbm_dbt_t); if( (nss_dbm_dbt_t *)NULL == object->handle ) { *pError = CKR_HOST_MEMORY; return (NSSCKMDObject *)NULL; } object->handle->my_db = node->dbt->my_db; object->handle->dbt.size = node->dbt->dbt.size; object->handle->dbt.data = nss_ZAlloc(arena, node->dbt->dbt.size); if( (void *)NULL == object->handle->dbt.data ) { *pError = CKR_HOST_MEMORY; return (NSSCKMDObject *)NULL; } (void)memcpy(object->handle->dbt.data, node->dbt->dbt.data, node->dbt->dbt.size); rv = nss_dbm_mdObject_factory(object, pError); if( (NSSCKMDObject *)NULL == rv ) { return (NSSCKMDObject *)NULL; } return rv; }
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; }
NSS_IMPLEMENT PRStatus nssCKObject_GetAttributes( CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR obj_template, CK_ULONG count, NSSArena *arenaOpt, nssSession *session, NSSSlot *slot) { nssArenaMark *mark = NULL; CK_SESSION_HANDLE hSession; CK_ULONG i = 0; CK_RV ckrv; PRStatus nssrv; PRBool alloced = PR_FALSE; void *epv = nssSlot_GetCryptokiEPV(slot); hSession = session->handle; if (arenaOpt) { mark = nssArena_Mark(arenaOpt); if (!mark) { goto loser; } } nssSession_EnterMonitor(session); /* XXX kinda hacky, if the storage size is already in the first template * item, then skip the alloc portion */ if (obj_template[0].ulValueLen == 0) { /* Get the storage size needed for each attribute */ ckrv = CKAPI(epv)->C_GetAttributeValue(hSession, object, obj_template, count); if (ckrv != CKR_OK && ckrv != CKR_ATTRIBUTE_TYPE_INVALID && ckrv != CKR_ATTRIBUTE_SENSITIVE) { nssSession_ExitMonitor(session); nss_SetError(NSS_ERROR_DEVICE_ERROR); goto loser; } /* Allocate memory for each attribute. */ for (i = 0; i < count; i++) { CK_ULONG ulValueLen = obj_template[i].ulValueLen; if (ulValueLen == 0 || ulValueLen == (CK_ULONG)-1) { obj_template[i].pValue = NULL; obj_template[i].ulValueLen = 0; continue; } if (is_string_attribute(obj_template[i].type)) { ulValueLen++; } obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen); if (!obj_template[i].pValue) { nssSession_ExitMonitor(session); goto loser; } } alloced = PR_TRUE; } /* Obtain the actual attribute values. */ ckrv = CKAPI(epv)->C_GetAttributeValue(hSession, object, obj_template, count); nssSession_ExitMonitor(session); if (ckrv != CKR_OK && ckrv != CKR_ATTRIBUTE_TYPE_INVALID && ckrv != CKR_ATTRIBUTE_SENSITIVE) { nss_SetError(NSS_ERROR_DEVICE_ERROR); goto loser; } if (alloced && arenaOpt) { nssrv = nssArena_Unmark(arenaOpt, mark); if (nssrv != PR_SUCCESS) { goto loser; } } if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || (ckrv == CKR_ATTRIBUTE_SENSITIVE))) { /* old tokens would keep the length of '0' and not deal with any * of the attributes we passed. For those tokens read them one at * a time */ for (i = 0; i < count; i++) { if ((obj_template[i].ulValueLen == 0) || (obj_template[i].ulValueLen == -1)) { obj_template[i].ulValueLen = 0; (void)nssCKObject_GetAttributes(object, &obj_template[i], 1, arenaOpt, session, slot); } } } return PR_SUCCESS; loser: if (alloced) { if (arenaOpt) { /* release all arena memory allocated before the failure. */ (void)nssArena_Release(arenaOpt, mark); } else { CK_ULONG j; /* free each heap object that was allocated before the failure. */ for (j = 0; j < i; j++) { nss_ZFreeIf(obj_template[j].pValue); } } } return PR_FAILURE; }
/* * 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; }
NSS_IMPLEMENT CK_RV nss_dbm_db_find_objects ( nss_dbm_find_t *find, nss_dbm_db_t *db, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_ULONG *pdbrv ) { CK_RV rv = CKR_OK; if( (nss_dbm_db_t *)NULL != db ) { DBT k, v; rv = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != rv ) { return rv; } *pdbrv = db->db->seq(db->db, &k, &v, R_FIRST); while( 0 == *pdbrv ) { CK_ULONG i, j; NSSArena *tmparena = (NSSArena *)NULL; CK_ULONG ulac; CK_ATTRIBUTE_PTR pt; if( (k.size < 4) || (0 != memcmp(k.data, PREFIX_OBJECT, 4)) ) { goto nomatch; } tmparena = NSSArena_Create(); rv = nss_dbm_db_unwrap_object(tmparena, &v, &pt, &ulac); if( CKR_OK != rv ) { goto loser; } for( i = 0; i < ulAttributeCount; i++ ) { for( j = 0; j < ulac; j++ ) { if( pTemplate[i].type == pt[j].type ) { if( pTemplate[i].ulValueLen != pt[j].ulValueLen ) { goto nomatch; } if( 0 != memcmp(pTemplate[i].pValue, pt[j].pValue, pt[j].ulValueLen) ) { goto nomatch; } break; } } if( j == ulac ) { goto nomatch; } } /* entire template matches */ { struct nss_dbm_dbt_node *node; node = nss_ZNEW(find->arena, struct nss_dbm_dbt_node); if( (struct nss_dbm_dbt_node *)NULL == node ) { rv = CKR_HOST_MEMORY; goto loser; } node->dbt = nss_ZNEW(find->arena, nss_dbm_dbt_t); if( (nss_dbm_dbt_t *)NULL == node->dbt ) { rv = CKR_HOST_MEMORY; goto loser; } node->dbt->dbt.size = k.size; node->dbt->dbt.data = nss_ZAlloc(find->arena, k.size); if( (void *)NULL == node->dbt->dbt.data ) { rv = CKR_HOST_MEMORY; goto loser; } (void)memcpy(node->dbt->dbt.data, k.data, k.size); node->dbt->my_db = db; node->next = find->found; find->found = node; } nomatch: if( (NSSArena *)NULL != tmparena ) { (void)NSSArena_Destroy(tmparena); } *pdbrv = db->db->seq(db->db, &k, &v, R_NEXT); } if( *pdbrv < 0 ) { rv = CKR_DEVICE_ERROR; goto loser; } rv = CKR_OK; loser: (void)NSSCKFWMutex_Unlock(db->crustylock); }
NSS_IMPLEMENT nss_dbm_dbt_t * nss_dbm_db_create_object ( NSSArena *arena, nss_dbm_db_t *db, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_RV *pError, CK_ULONG *pdbrv ) { NSSArena *tmparena = (NSSArena *)NULL; nss_dbm_dbt_t *rv = (nss_dbm_dbt_t *)NULL; DBT object; rv = nss_ZNEW(arena, nss_dbm_dbt_t); if( (nss_dbm_dbt_t *)NULL == rv ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_dbt_t *)NULL; } rv->my_db = db; rv->dbt.size = sizeof(struct handle); rv->dbt.data = nss_ZAlloc(arena, rv->dbt.size); if( (void *)NULL == rv->dbt.data ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_dbt_t *)NULL; } *pdbrv = nss_dbm_db_new_handle(db, &rv->dbt, pError); if( 0 != *pdbrv ) { return (nss_dbm_dbt_t *)NULL; } tmparena = NSSArena_Create(); if( (NSSArena *)NULL == tmparena ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_dbt_t *)NULL; } *pError = nss_dbm_db_wrap_object(tmparena, pTemplate, ulAttributeCount, &object); if( CKR_OK != *pError ) { return (nss_dbm_dbt_t *)NULL; } /* Locked region */ { *pError = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != *pError ) { goto loser; } *pdbrv = db->db->put(db->db, &rv->dbt, &object, 0); if( 0 != *pdbrv ) { *pError = CKR_DEVICE_ERROR; } (void)db->db->sync(db->db, 0); (void)NSSCKFWMutex_Unlock(db->crustylock); } loser: if( (NSSArena *)NULL != tmparena ) { (void)NSSArena_Destroy(tmparena); } return rv; }
/* * 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; }