Example #1
0
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;
}
Example #2
0
/* Sigh.  The methods to find objects declared above cause problems with
 * the low-level object cache in the softoken -- the objects are found in 
 * toto, then one wave of GetAttributes is done, then another.  Having a 
 * large number of objects causes the cache to be thrashed, as the objects 
 * are gone before there's any chance to ask for their attributes.
 * So, for now, bringing back traversal methods for certs.  This way all of 
 * the cert's attributes can be grabbed immediately after finding it,
 * increasing the likelihood that the cache takes care of it.
 */
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificates (
  NSSToken *token,
  nssSession *sessionOpt,
  nssTokenSearchType searchType,
  PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
  void *arg
)
{
    CK_RV ckrv;
    CK_ULONG count;
    CK_OBJECT_HANDLE *objectHandles;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE cert_template[2];
    CK_ULONG ctsize;
    NSSArena *arena;
    PRStatus status;
    PRUint32 arraySize, numHandles;
    nssCryptokiObject **objects;
    void *epv = nssToken_GetCryptokiEPV(token);
    nssSession *session = (sessionOpt) ? sessionOpt : token->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 PR_FAILURE;
    }

    /* template for all certs */
    NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
    if (searchType == nssTokenSearchType_SessionOnly) {
	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly ||
               searchType == nssTokenSearchType_TokenForced) {
	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);

    /* the arena is only for the array of object handles */
    arena = nssArena_Create();
    if (!arena) {
	return PR_FAILURE;
    }
    arraySize = OBJECT_STACK_SIZE;
    numHandles = 0;
    objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize);
    if (!objectHandles) {
	goto loser;
    }
    nssSession_EnterMonitor(session); /* ==== session lock === */
    /* Initialize the find with the template */
    ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, 
                                         cert_template, ctsize);
    if (ckrv != CKR_OK) {
	nssSession_ExitMonitor(session);
	goto loser;
    }
    while (PR_TRUE) {
	/* Issue the find for up to arraySize - numHandles objects */
	ckrv = CKAPI(epv)->C_FindObjects(session->handle, 
	                                 objectHandles + numHandles, 
	                                 arraySize - numHandles, 
	                                 &count);
	if (ckrv != CKR_OK) {
	    nssSession_ExitMonitor(session);
	    goto loser;
	}
	/* bump the number of found objects */
	numHandles += count;
	if (numHandles < arraySize) {
	    break;
	}
	/* the array is filled, double it and continue */
	arraySize *= 2;
	objectHandles = nss_ZREALLOCARRAY(objectHandles, 
	                                  CK_OBJECT_HANDLE, 
	                                  arraySize);
	if (!objectHandles) {
	    nssSession_ExitMonitor(session);
	    goto loser;
	}
    }
    ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
    nssSession_ExitMonitor(session); /* ==== end session lock === */
    if (ckrv != CKR_OK) {
	goto loser;
    }
    if (numHandles > 0) {
	objects = create_objects_from_handles(token, session,
	                                      objectHandles, numHandles);
	if (objects) {
	    nssCryptokiObject **op;
	    for (op = objects; *op; op++) {
		status = (*callback)(*op, arg);
	    }
	    nss_ZFreeIf(objects);
	}
    }
    nssArena_Destroy(arena);
    return PR_SUCCESS;
loser:
    nssArena_Destroy(arena);
    return PR_FAILURE;
}
Example #3
0
/*
 * 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;
}