Ejemplo n.º 1
0
NSS_IMPLEMENT NSSCryptoContext *
nssCryptoContext_Create (
  NSSTrustDomain *td,
  NSSCallback *uhhOpt
)
{
    NSSArena *arena;
    NSSCryptoContext *rvCC;
    arena = NSSArena_Create();
    if (!arena) {
	return NULL;
    }
    rvCC = nss_ZNEW(arena, NSSCryptoContext);
    if (!rvCC) {
	return NULL;
    }
    rvCC->td = td;
    rvCC->arena = arena;
    rvCC->certStore = nssCertificateStore_Create(rvCC->arena);
    if (!rvCC->certStore) {
	nssArena_Destroy(arena);
	return NULL;
    }

    return rvCC;
}
Ejemplo n.º 2
0
NSS_IMPLEMENT NSSTrustDomain *
NSSTrustDomain_Create (
  NSSUTF8 *moduleOpt,
  NSSUTF8 *uriOpt,
  NSSUTF8 *opaqueOpt,
  void *reserved
)
{
    NSSArena *arena;
    NSSTrustDomain *rvTD;
    arena = NSSArena_Create();
    if(!arena) {
	return (NSSTrustDomain *)NULL;
    }
    rvTD = nss_ZNEW(arena, NSSTrustDomain);
    if (!rvTD) {
	goto loser;
    }
    /* protect the token list and the token iterator */
    rvTD->tokensLock = NSSRWLock_New(100, "tokens");
    if (!rvTD->tokensLock) {
	goto loser;
    }
    nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
    rvTD->arena = arena;
    rvTD->refCount = 1;
    rvTD->statusConfig = NULL;
    return rvTD;
loser:
    if (rvTD && rvTD->tokensLock) {
	NSSRWLock_Destroy(rvTD->tokensLock);
    }
    nssArena_Destroy(arena);
    return (NSSTrustDomain *)NULL;
}
Ejemplo n.º 3
0
/* CERT_TraversePermCertsForNickname */
NSS_IMPLEMENT PRStatus
nssTrustDomain_TraverseCertificatesByNickname (
  NSSTrustDomain *td,
  NSSUTF8 *nickname,
  PRStatus (*callback)(NSSCertificate *c, void *arg),
  void *arg
)
{
    PRStatus nssrv = PR_SUCCESS;
    NSSArena *tmpArena;
    NSSCertificate **nickCerts;
    NSSCertificate *c;
    PRIntn i;
    tmpArena = NSSArena_Create();
    if (!tmpArena) {
        return PR_FAILURE;
    }
    nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL,
                                                          0, tmpArena);
    if (nickCerts) {
	for (i=0, c = nickCerts[i]; c; i++) {
	    nssrv = callback(c, arg);
	    if (nssrv != PR_SUCCESS) break;
	}
    }
    nssArena_Destroy(tmpArena);
    return nssrv;
}
Ejemplo n.º 4
0
int main()
{
    NSSArena *arena = NSSArena_Create();
    __VERIFIER_plot("NSSArena_Create", &arena);

    return 0;
}
Ejemplo n.º 5
0
NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *cc)
{
    NSSCertificate *c;
    nssCryptokiInstance *instance;
    nssPKIObject *pkiob;
    NSSArena *arena;
    c = cc->nssCertificate;
    if (c) {
    	return c;
    }
    /* i don't think this should happen.  but if it can, need to create
     * NSSCertificate from CERTCertificate values here.  */
    /* Yup, it can happen. */
    arena = NSSArena_Create();
    if (!arena) {
	return NULL;
    }
    c = nss_ZNEW(arena, NSSCertificate);
    if (!c) {
	nssArena_Destroy(arena);
	return NULL;
    }
    NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
    c->type = NSSCertificateType_PKIX;
    pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor);
    if (!pkiob) {
	nssArena_Destroy(arena);
	return NULL;
    }
    c->object = *pkiob;
    nssItem_Create(arena,
                   &c->issuer, cc->derIssuer.len, cc->derIssuer.data);
    nssItem_Create(arena,
                   &c->subject, cc->derSubject.len, cc->derSubject.data);
    if (PR_TRUE) {
	/* CERTCertificate stores serial numbers decoded.  I need the DER
	* here.  sigh.
	*/
	SECItem derSerial;
	SECStatus secrv;
	secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
	if (secrv == SECFailure) {
	    nssArena_Destroy(arena);
	    return NULL;
	}
	nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
	PORT_Free(derSerial.data);
    }
    if (cc->emailAddr && cc->emailAddr[0]) {
        c->email = nssUTF8_Create(arena,
                                  nssStringType_PrintableString,
                                  (NSSUTF8 *)cc->emailAddr,
                                  PORT_Strlen(cc->emailAddr));
    }
    if (cc->slot) {
	instance = nss_ZNEW(arena, nssCryptokiInstance);
	if (!instance) {
	    nssArena_Destroy(arena);
	    return NULL;
	}
	instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
	instance->handle = cc->pkcs11ID;
	instance->isTokenObject = PR_TRUE;
	if (cc->nickname) {
	    instance->label = nssUTF8_Create(arena,
	                                     nssStringType_UTF8String,
	                                     (NSSUTF8 *)cc->nickname,
	                                     PORT_Strlen(cc->nickname));
	}
	nssPKIObject_AddInstance(&c->object, instance);
    }
    c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc);
    cc->nssCertificate = c;
    return c;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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);
  }
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/*
 * nssCKFWInstance_Create
 *
 */
NSS_IMPLEMENT NSSCKFWInstance *
nssCKFWInstance_Create(
    CK_C_INITIALIZE_ARGS_PTR pInitArgs,
    CryptokiLockingState LockingState,
    NSSCKMDInstance *mdInstance,
    CK_RV *pError)
{
    NSSCKFWInstance *fwInstance;
    NSSArena *arena = (NSSArena *)NULL;
    CK_ULONG i;
    CK_BBOOL called_Initialize = CK_FALSE;

#ifdef NSSDEBUG
    if ((CK_RV)NULL == pError) {
        return (NSSCKFWInstance *)NULL;
    }

    if (!mdInstance) {
        *pError = CKR_ARGUMENTS_BAD;
        return (NSSCKFWInstance *)NULL;
    }
#endif /* NSSDEBUG */

    arena = NSSArena_Create();
    if (!arena) {
        *pError = CKR_HOST_MEMORY;
        return (NSSCKFWInstance *)NULL;
    }

    fwInstance = nss_ZNEW(arena, NSSCKFWInstance);
    if (!fwInstance) {
        goto nomem;
    }

    fwInstance->arena = arena;
    fwInstance->mdInstance = mdInstance;

    fwInstance->LockingState = LockingState;
    if ((CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs) {
        fwInstance->initArgs = *pInitArgs;
        fwInstance->pInitArgs = &fwInstance->initArgs;
        if (pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
            fwInstance->mayCreatePthreads = CK_FALSE;
        } else {
            fwInstance->mayCreatePthreads = CK_TRUE;
        }
        fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved);
    } else {
        fwInstance->mayCreatePthreads = CK_TRUE;
    }

    fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, LockingState, arena,
                                            pError);
    if (!fwInstance->mutex) {
        if (CKR_OK == *pError) {
            *pError = CKR_GENERAL_ERROR;
        }
        goto loser;
    }

    if (mdInstance->Initialize) {
        *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData);
        if (CKR_OK != *pError) {
            goto loser;
        }

        called_Initialize = CK_TRUE;
    }

    if (mdInstance->ModuleHandlesSessionObjects) {
        fwInstance->moduleHandlesSessionObjects =
            mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);
    } else {
        fwInstance->moduleHandlesSessionObjects = CK_FALSE;
    }

    if (!mdInstance->GetNSlots) {
        /* That routine is required */
        *pError = CKR_GENERAL_ERROR;
        goto loser;
    }

    fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError);
    if ((CK_ULONG)0 == fwInstance->nSlots) {
        if (CKR_OK == *pError) {
            /* Zero is not a legitimate answer */
            *pError = CKR_GENERAL_ERROR;
        }
        goto loser;
    }

    fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots);
    if ((NSSCKFWSlot **)NULL == fwInstance->fwSlotList) {
        goto nomem;
    }

    fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots);
    if ((NSSCKMDSlot **)NULL == fwInstance->mdSlotList) {
        goto nomem;
    }

    fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance,
                                                       fwInstance->arena, pError);
    if (!fwInstance->sessionHandleHash) {
        goto loser;
    }

    fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance,
                                                      fwInstance->arena, pError);
    if (!fwInstance->objectHandleHash) {
        goto loser;
    }

    if (!mdInstance->GetSlots) {
        /* That routine is required */
        *pError = CKR_GENERAL_ERROR;
        goto loser;
    }

    *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList);
    if (CKR_OK != *pError) {
        goto loser;
    }

    for (i = 0; i < fwInstance->nSlots; i++) {
        NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i];

        if (!mdSlot) {
            *pError = CKR_GENERAL_ERROR;
            goto loser;
        }

        fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError);
        if (CKR_OK != *pError) {
            CK_ULONG j;

            for (j = 0; j < i; j++) {
                (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]);
            }

            for (j = i; j < fwInstance->nSlots; j++) {
                NSSCKMDSlot *mds = fwInstance->mdSlotList[j];
                if (mds->Destroy) {
                    mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance);
                }
            }

            goto loser;
        }
    }

#ifdef DEBUG
    *pError = instance_add_pointer(fwInstance);
    if (CKR_OK != *pError) {
        for (i = 0; i < fwInstance->nSlots; i++) {
            (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
        }

        goto loser;
    }
#endif /* DEBUG */

    *pError = CKR_OK;
    return fwInstance;

nomem:
    *pError = CKR_HOST_MEMORY;
/*FALLTHROUGH*/
loser:

    if (CK_TRUE == called_Initialize) {
        if (mdInstance->Finalize) {
            mdInstance->Finalize(mdInstance, fwInstance);
        }
    }

    if (fwInstance && fwInstance->mutex) {
        nssCKFWMutex_Destroy(fwInstance->mutex);
    }

    if (arena) {
        (void)NSSArena_Destroy(arena);
    }
    return (NSSCKFWInstance *)NULL;
}
Ejemplo n.º 11
0
/*
 * nssCKMDFindSessionObjects_Create
 *
 */
NSS_IMPLEMENT NSSCKMDFindObjects *
nssCKMDFindSessionObjects_Create
(
  NSSCKFWToken *fwToken,
  CK_ATTRIBUTE_PTR pTemplate,
  CK_ULONG ulCount,
  CK_RV *pError
)
{
  NSSArena *arena;
  nssCKMDFindSessionObjects *mdfso;
  nssCKFWHash *hash;
  NSSCKMDFindObjects *rv;

#ifdef NSSDEBUG
  if (!pError) {
    return (NSSCKMDFindObjects *)NULL;
  }

  *pError = nssCKFWToken_verifyPointer(fwToken);
  if( CKR_OK != *pError ) {
    return (NSSCKMDFindObjects *)NULL;
  }

  if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
    *pError = CKR_ARGUMENTS_BAD;
    return (NSSCKMDFindObjects *)NULL;
  }
#endif /* NSSDEBUG */

  *pError = CKR_OK;

  hash = nssCKFWToken_GetSessionObjectHash(fwToken);
  if (!hash) {
    *pError= CKR_GENERAL_ERROR;
    return (NSSCKMDFindObjects *)NULL;
  }

  arena = NSSArena_Create();
  if (!arena) {
    *pError = CKR_HOST_MEMORY;
    return (NSSCKMDFindObjects *)NULL;
  }

  mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
  if (!mdfso) {
    goto loser;
  }

  rv = nss_ZNEW(arena, NSSCKMDFindObjects);
  if(rv == NULL) {
    goto loser;
  }

  mdfso->error = CKR_OK;
  mdfso->pTemplate = pTemplate;
  mdfso->ulCount = ulCount;
  mdfso->hash = hash;

  nssCKFWHash_Iterate(hash, findfcn, mdfso);

  if( CKR_OK != mdfso->error ) {
    goto loser;
  }

  rv->etc = (void *)mdfso;
  rv->Final = nss_ckmdFindSessionObjects_Final;
  rv->Next = nss_ckmdFindSessionObjects_Next;

#ifdef DEBUG
  if( (*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK ) {
    goto loser;
  }
#endif /* DEBUG */    
  mdfso->arena = arena;

  return rv;

loser:
  if (arena) {
    NSSArena_Destroy(arena);
  }
  if (*pError == CKR_OK) {
      *pError = CKR_HOST_MEMORY;
  }
  return NULL;
}