/* # 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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
/*
 * 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;
}
Exemple #13
0
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);
  }
Exemple #14
0
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;
}
Exemple #15
0
/*
 * 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;
}
Exemple #16
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;
}