123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /*
- * slot.c
- *
- * This file implements the NSSCKFWSlot type and methods.
- */
- #ifndef CK_T
- #include "ck.h"
- #endif /* CK_T */
- /*
- * NSSCKFWSlot
- *
- * -- create/destroy --
- * nssCKFWSlot_Create
- * nssCKFWSlot_Destroy
- *
- * -- public accessors --
- * NSSCKFWSlot_GetMDSlot
- * NSSCKFWSlot_GetFWInstance
- * NSSCKFWSlot_GetMDInstance
- * NSSCKFWSlot_GetSlotID
- *
- * -- implement public accessors --
- * nssCKFWSlot_GetMDSlot
- * nssCKFWSlot_GetFWInstance
- * nssCKFWSlot_GetMDInstance
- * nssCKFWSlot_GetSlotID
- *
- * -- private accessors --
- * nssCKFWSlot_ClearToken
- *
- * -- module fronts --
- * nssCKFWSlot_GetSlotDescription
- * nssCKFWSlot_GetManufacturerID
- * nssCKFWSlot_GetTokenPresent
- * nssCKFWSlot_GetRemovableDevice
- * nssCKFWSlot_GetHardwareSlot
- * nssCKFWSlot_GetHardwareVersion
- * nssCKFWSlot_GetFirmwareVersion
- * nssCKFWSlot_InitToken
- * nssCKFWSlot_GetToken
- */
- struct NSSCKFWSlotStr {
- NSSCKFWMutex *mutex;
- NSSCKMDSlot *mdSlot;
- NSSCKFWInstance *fwInstance;
- NSSCKMDInstance *mdInstance;
- CK_SLOT_ID slotID;
- /*
- * Everything above is set at creation time, and then not modified.
- * The invariants the mutex protects are:
- *
- * 1) Each of the cached descriptions (versions, etc.) are in an
- * internally consistant state.
- *
- * 2) The fwToken points to the token currently in the slot, and
- * it is in a consistant state.
- *
- * Note that the calls accessing the cached descriptions will
- * call the NSSCKMDSlot methods with the mutex locked. Those
- * methods may then call the public NSSCKFWSlot routines. Those
- * public routines only access the constant data above, so there's
- * no problem. But be careful if you add to this object; mutexes
- * are in general not reentrant, so don't create deadlock situations.
- */
- NSSUTF8 *slotDescription;
- NSSUTF8 *manufacturerID;
- CK_VERSION hardwareVersion;
- CK_VERSION firmwareVersion;
- NSSCKFWToken *fwToken;
- };
- #ifdef DEBUG
- /*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
- static CK_RV
- slot_add_pointer(
- const NSSCKFWSlot *fwSlot)
- {
- return CKR_OK;
- }
- static CK_RV
- slot_remove_pointer(
- const NSSCKFWSlot *fwSlot)
- {
- return CKR_OK;
- }
- NSS_IMPLEMENT CK_RV
- nssCKFWSlot_verifyPointer(
- const NSSCKFWSlot *fwSlot)
- {
- return CKR_OK;
- }
- #endif /* DEBUG */
- /*
- * nssCKFWSlot_Create
- *
- */
- NSS_IMPLEMENT NSSCKFWSlot *
- nssCKFWSlot_Create(
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *mdSlot,
- CK_SLOT_ID slotID,
- CK_RV *pError)
- {
- NSSCKFWSlot *fwSlot;
- NSSCKMDInstance *mdInstance;
- NSSArena *arena;
- #ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSlot *)NULL;
- }
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if (CKR_OK != *pError) {
- return (NSSCKFWSlot *)NULL;
- }
- #endif /* NSSDEBUG */
- mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
- if (!mdInstance) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWSlot *)NULL;
- }
- arena = nssCKFWInstance_GetArena(fwInstance, pError);
- if (!arena) {
- if (CKR_OK == *pError) {
- *pError = CKR_GENERAL_ERROR;
- }
- }
- fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
- if (!fwSlot) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWSlot *)NULL;
- }
- fwSlot->mdSlot = mdSlot;
- fwSlot->fwInstance = fwInstance;
- fwSlot->mdInstance = mdInstance;
- fwSlot->slotID = slotID;
- fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if (!fwSlot->mutex) {
- if (CKR_OK == *pError) {
- *pError = CKR_GENERAL_ERROR;
- }
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
- if (mdSlot->Initialize) {
- *pError = CKR_OK;
- *pError = mdSlot->Initialize(mdSlot, fwSlot, mdInstance, fwInstance);
- if (CKR_OK != *pError) {
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
- }
- #ifdef DEBUG
- *pError = slot_add_pointer(fwSlot);
- if (CKR_OK != *pError) {
- if (mdSlot->Destroy) {
- mdSlot->Destroy(mdSlot, fwSlot, mdInstance, fwInstance);
- }
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
- #endif /* DEBUG */
- return fwSlot;
- }
- /*
- * nssCKFWSlot_Destroy
- *
- */
- NSS_IMPLEMENT CK_RV
- nssCKFWSlot_Destroy(
- NSSCKFWSlot *fwSlot)
- {
- CK_RV error = CKR_OK;
- #ifdef NSSDEBUG
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if (CKR_OK != error) {
- return error;
- }
- #endif /* NSSDEBUG */
- if (fwSlot->fwToken) {
- nssCKFWToken_Destroy(fwSlot->fwToken);
- }
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- if (fwSlot->mdSlot->Destroy) {
- fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
- }
- #ifdef DEBUG
- error = slot_remove_pointer(fwSlot);
- #endif /* DEBUG */
- (void)nss_ZFreeIf(fwSlot);
- return error;
- }
- /*
- * nssCKFWSlot_GetMDSlot
- *
- */
- NSS_IMPLEMENT NSSCKMDSlot *
- nssCKFWSlot_GetMDSlot(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (NSSCKMDSlot *)NULL;
- }
- #endif /* NSSDEBUG */
- return fwSlot->mdSlot;
- }
- /*
- * nssCKFWSlot_GetFWInstance
- *
- */
- NSS_IMPLEMENT NSSCKFWInstance *
- nssCKFWSlot_GetFWInstance(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (NSSCKFWInstance *)NULL;
- }
- #endif /* NSSDEBUG */
- return fwSlot->fwInstance;
- }
- /*
- * nssCKFWSlot_GetMDInstance
- *
- */
- NSS_IMPLEMENT NSSCKMDInstance *
- nssCKFWSlot_GetMDInstance(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (NSSCKMDInstance *)NULL;
- }
- #endif /* NSSDEBUG */
- return fwSlot->mdInstance;
- }
- /*
- * nssCKFWSlot_GetSlotID
- *
- */
- NSS_IMPLEMENT CK_SLOT_ID
- nssCKFWSlot_GetSlotID(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (CK_SLOT_ID)0;
- }
- #endif /* NSSDEBUG */
- return fwSlot->slotID;
- }
- /*
- * nssCKFWSlot_GetSlotDescription
- *
- */
- NSS_IMPLEMENT CK_RV
- nssCKFWSlot_GetSlotDescription(
- NSSCKFWSlot *fwSlot,
- CK_CHAR slotDescription[64])
- {
- CK_RV error = CKR_OK;
- #ifdef NSSDEBUG
- if ((CK_CHAR_PTR)NULL == slotDescription) {
- return CKR_ARGUMENTS_BAD;
- }
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if (CKR_OK != error) {
- return error;
- }
- #endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwSlot->mutex);
- if (CKR_OK != error) {
- return error;
- }
- if (!fwSlot->slotDescription) {
- if (fwSlot->mdSlot->GetSlotDescription) {
- fwSlot->slotDescription = fwSlot->mdSlot->GetSlotDescription(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
- fwSlot->fwInstance, &error);
- if ((!fwSlot->slotDescription) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwSlot->slotDescription = (NSSUTF8 *)"";
- }
- }
- (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, (char *)slotDescription, 64, ' ');
- error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return error;
- }
- /*
- * nssCKFWSlot_GetManufacturerID
- *
- */
- NSS_IMPLEMENT CK_RV
- nssCKFWSlot_GetManufacturerID(
- NSSCKFWSlot *fwSlot,
- CK_CHAR manufacturerID[32])
- {
- CK_RV error = CKR_OK;
- #ifdef NSSDEBUG
- if ((CK_CHAR_PTR)NULL == manufacturerID) {
- return CKR_ARGUMENTS_BAD;
- }
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if (CKR_OK != error) {
- return error;
- }
- #endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwSlot->mutex);
- if (CKR_OK != error) {
- return error;
- }
- if (!fwSlot->manufacturerID) {
- if (fwSlot->mdSlot->GetManufacturerID) {
- fwSlot->manufacturerID = fwSlot->mdSlot->GetManufacturerID(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
- fwSlot->fwInstance, &error);
- if ((!fwSlot->manufacturerID) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwSlot->manufacturerID = (NSSUTF8 *)"";
- }
- }
- (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, (char *)manufacturerID, 32, ' ');
- error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return error;
- }
- /*
- * nssCKFWSlot_GetTokenPresent
- *
- */
- NSS_IMPLEMENT CK_BBOOL
- nssCKFWSlot_GetTokenPresent(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return CK_FALSE;
- }
- #endif /* NSSDEBUG */
- if (!fwSlot->mdSlot->GetTokenPresent) {
- return CK_TRUE;
- }
- return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
- }
- /*
- * nssCKFWSlot_GetRemovableDevice
- *
- */
- NSS_IMPLEMENT CK_BBOOL
- nssCKFWSlot_GetRemovableDevice(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return CK_FALSE;
- }
- #endif /* NSSDEBUG */
- if (!fwSlot->mdSlot->GetRemovableDevice) {
- return CK_FALSE;
- }
- return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
- }
- /*
- * nssCKFWSlot_GetHardwareSlot
- *
- */
- NSS_IMPLEMENT CK_BBOOL
- nssCKFWSlot_GetHardwareSlot(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return CK_FALSE;
- }
- #endif /* NSSDEBUG */
- if (!fwSlot->mdSlot->GetHardwareSlot) {
- return CK_FALSE;
- }
- return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
- }
- /*
- * nssCKFWSlot_GetHardwareVersion
- *
- */
- NSS_IMPLEMENT CK_VERSION
- nssCKFWSlot_GetHardwareVersion(
- NSSCKFWSlot *fwSlot)
- {
- CK_VERSION rv;
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- rv.major = rv.minor = 0;
- return rv;
- }
- #endif /* NSSDEBUG */
- if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) {
- rv.major = rv.minor = 0;
- return rv;
- }
- if ((0 != fwSlot->hardwareVersion.major) ||
- (0 != fwSlot->hardwareVersion.minor)) {
- rv = fwSlot->hardwareVersion;
- goto done;
- }
- if (fwSlot->mdSlot->GetHardwareVersion) {
- fwSlot->hardwareVersion = fwSlot->mdSlot->GetHardwareVersion(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
- } else {
- fwSlot->hardwareVersion.major = 0;
- fwSlot->hardwareVersion.minor = 1;
- }
- rv = fwSlot->hardwareVersion;
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return rv;
- }
- /*
- * nssCKFWSlot_GetFirmwareVersion
- *
- */
- NSS_IMPLEMENT CK_VERSION
- nssCKFWSlot_GetFirmwareVersion(
- NSSCKFWSlot *fwSlot)
- {
- CK_VERSION rv;
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- rv.major = rv.minor = 0;
- return rv;
- }
- #endif /* NSSDEBUG */
- if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) {
- rv.major = rv.minor = 0;
- return rv;
- }
- if ((0 != fwSlot->firmwareVersion.major) ||
- (0 != fwSlot->firmwareVersion.minor)) {
- rv = fwSlot->firmwareVersion;
- goto done;
- }
- if (fwSlot->mdSlot->GetFirmwareVersion) {
- fwSlot->firmwareVersion = fwSlot->mdSlot->GetFirmwareVersion(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
- } else {
- fwSlot->firmwareVersion.major = 0;
- fwSlot->firmwareVersion.minor = 1;
- }
- rv = fwSlot->firmwareVersion;
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return rv;
- }
- /*
- * nssCKFWSlot_GetToken
- *
- */
- NSS_IMPLEMENT NSSCKFWToken *
- nssCKFWSlot_GetToken(
- NSSCKFWSlot *fwSlot,
- CK_RV *pError)
- {
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
- #ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWToken *)NULL;
- }
- *pError = nssCKFWSlot_verifyPointer(fwSlot);
- if (CKR_OK != *pError) {
- return (NSSCKFWToken *)NULL;
- }
- #endif /* NSSDEBUG */
- *pError = nssCKFWMutex_Lock(fwSlot->mutex);
- if (CKR_OK != *pError) {
- return (NSSCKFWToken *)NULL;
- }
- if (!fwSlot->fwToken) {
- if (!fwSlot->mdSlot->GetToken) {
- *pError = CKR_GENERAL_ERROR;
- fwToken = (NSSCKFWToken *)NULL;
- goto done;
- }
- mdToken = fwSlot->mdSlot->GetToken(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance, pError);
- if (!mdToken) {
- if (CKR_OK == *pError) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWToken *)NULL;
- }
- fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError);
- fwSlot->fwToken = fwToken;
- } else {
- fwToken = fwSlot->fwToken;
- }
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return fwToken;
- }
- /*
- * nssCKFWSlot_ClearToken
- *
- */
- NSS_IMPLEMENT void
- nssCKFWSlot_ClearToken(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef NSSDEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return;
- }
- #endif /* NSSDEBUG */
- if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) {
- /* Now what? */
- return;
- }
- fwSlot->fwToken = (NSSCKFWToken *)NULL;
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return;
- }
- /*
- * NSSCKFWSlot_GetMDSlot
- *
- */
- NSS_IMPLEMENT NSSCKMDSlot *
- NSSCKFWSlot_GetMDSlot(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef DEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (NSSCKMDSlot *)NULL;
- }
- #endif /* DEBUG */
- return nssCKFWSlot_GetMDSlot(fwSlot);
- }
- /*
- * NSSCKFWSlot_GetFWInstance
- *
- */
- NSS_IMPLEMENT NSSCKFWInstance *
- NSSCKFWSlot_GetFWInstance(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef DEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (NSSCKFWInstance *)NULL;
- }
- #endif /* DEBUG */
- return nssCKFWSlot_GetFWInstance(fwSlot);
- }
- /*
- * NSSCKFWSlot_GetMDInstance
- *
- */
- NSS_IMPLEMENT NSSCKMDInstance *
- NSSCKFWSlot_GetMDInstance(
- NSSCKFWSlot *fwSlot)
- {
- #ifdef DEBUG
- if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
- return (NSSCKMDInstance *)NULL;
- }
- #endif /* DEBUG */
- return nssCKFWSlot_GetMDInstance(fwSlot);
- }
- /*
- * NSSCKFWSlot_GetSlotID
- *
- */
- NSS_IMPLEMENT CK_SLOT_ID
- NSSCKFWSlot_GetSlotID(
- NSSCKFWSlot *fwSlot)
- {
- return nssCKFWSlot_GetSlotID(fwSlot);
- }
|