Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
pk11util.c File Reference
#include "seccomon.h"
#include "secmod.h"
#include "nssilock.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pk11func.h"
#include "pki3hack.h"
#include "secerr.h"
#include "dev.h"
#include "pkcs11ni.h"

Go to the source code of this file.

Functions

void SECMOD_Init ()
SECStatus SECMOD_Shutdown ()
SECMODModule * SECMOD_GetInternalModule (void)
SECStatus secmod_AddModuleToList (SECMODModuleList **moduleList, SECMODModule *newModule)
SECStatus SECMOD_AddModuleToList (SECMODModule *newModule)
SECStatus SECMOD_AddModuleToDBOnlyList (SECMODModule *newModule)
SECStatus SECMOD_AddModuleToUnloadList (SECMODModule *newModule)
SECMODModuleList * SECMOD_GetDefaultModuleList ()
SECMODModuleList * SECMOD_GetDeadModuleList ()
SECMODModuleList * SECMOD_GetDBModuleList ()
SECMODListLockSECMOD_GetDefaultModuleListLock ()
SECMODModule * SECMOD_FindModule (const char *name)
SECMODModule * SECMOD_FindModuleByID (SECMODModuleID id)
PK11SlotInfo * SECMOD_FindSlotByID (SECMODModule *module, CK_SLOT_ID slotID)
PK11SlotInfo * SECMOD_LookupSlot (SECMODModuleID moduleID, CK_SLOT_ID slotID)
SECStatus SECMOD_DeleteModuleEx (const char *name, SECMODModule *mod, int *type, PRBool permdb)
SECStatus SECMOD_DeleteModule (const char *name, int *type)
SECStatus SECMOD_DeleteInternalModule (const char *name)
SECStatus SECMOD_AddModule (SECMODModule *newModule)
PK11SlotInfo * SECMOD_FindSlot (SECMODModule *module, const char *name)
SECStatus PK11_GetModInfo (SECMODModule *mod, CK_INFO *info)
PRBool PK11_IsFIPS (void)
SECStatus SECMOD_AddNewModuleEx (const char *moduleName, const char *dllPath, unsigned long defaultMechanismFlags, unsigned long cipherEnableFlags, char *modparms, char *nssparms)
SECStatus SECMOD_AddNewModule (const char *moduleName, const char *dllPath, unsigned long defaultMechanismFlags, unsigned long cipherEnableFlags)
SECStatus SECMOD_UpdateModule (SECMODModule *module)
unsigned long SECMOD_PubMechFlagstoInternal (unsigned long publicFlags)
unsigned long SECMOD_InternaltoPubMechFlags (unsigned long internalFlags)
unsigned long SECMOD_PubCipherFlagstoInternal (unsigned long publicFlags)
unsigned long SECMOD_InternaltoPubCipherFlags (unsigned long internalFlags)
PRBool SECMOD_IsModulePresent (unsigned long int pubCipherEnableFlags)
SECMODModuleList * SECMOD_NewModuleListElement (void)
SECMODModule * SECMOD_ReferenceModule (SECMODModule *module)
void SECMOD_DestroyModule (SECMODModule *module)
void SECMOD_SlotDestroyModule (SECMODModule *module, PRBool fromSlot)
SECMODModuleList * SECMOD_DestroyModuleListElement (SECMODModuleList *element)
void SECMOD_DestroyModuleList (SECMODModuleList *list)
PRBool SECMOD_CanDeleteInternalModule (void)
SECStatus SECMOD_UpdateSlotList (SECMODModule *mod)
PK11SlotInfo * secmod_HandleWaitForSlotEvent (SECMODModule *mod, unsigned long flags, PRIntervalTime latency)
PK11SlotInfo * SECMOD_WaitForAnyTokenEvent (SECMODModule *mod, unsigned long flags, PRIntervalTime latency)
SECStatus SECMOD_CancelWait (SECMODModule *mod)
PRBool SECMOD_HasRemovableSlots (SECMODModule *mod)
static SECStatus secmod_UserDBOp (CK_OBJECT_CLASS objClass, const char *sendSpec)
static char * nss_addEscape (const char *string, char quote)
static char * nss_doubleEscape (const char *string)
PK11SlotInfo * SECMOD_OpenUserDB (const char *moduleSpec)
SECStatus SECMOD_CloseUserDB (PK11SlotInfo *slot)

Variables

static SECMODModuleList * modules = NULL
static SECMODModuleList * modulesDB = NULL
static SECMODModuleList * modulesUnload = NULL
static SECMODModule * internalModule = NULL
static SECMODModule * defaultDBModule = NULL
static SECMODModule * pendingModule = NULL
static SECMODListLockmoduleLock = NULL
int secmod_PrivateModuleCount = 0
PK11DefaultArrayEntry PK11_DefaultArray []
int num_pk11_default_mechanisms

Function Documentation

static char* nss_addEscape ( const char *  string,
char  quote 
) [static]

Definition at line 1240 of file pk11util.c.

{
    char *newString = 0;
    int escapes = 0, size = 0;
    const char *src;
    char *dest;

    for (src=string; *src ; src++) {
        if ((*src == quote) || (*src == '\\')) escapes++;
        size++;
    }

    newString = PORT_ZAlloc(escapes+size+1);
    if (newString == NULL) {
        return NULL;
    }

    for (src=string, dest=newString; *src; src++,dest++) {
        if ((*src == '\\') || (*src == quote)) {
            *dest++ = '\\';
        }
        *dest = *src;
    }

    return newString;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* nss_doubleEscape ( const char *  string) [static]

Definition at line 1268 of file pk11util.c.

{
    char *round1 = NULL;
    char *retValue = NULL;
    if (string == NULL) {
        goto done;
    }
    round1 = nss_addEscape(string,'>');
    if (round1) {
        retValue = nss_addEscape(round1,']');
        PORT_Free(round1);
    }

done:
    if (retValue == NULL) {
        retValue = PORT_Strdup("");
    }
    return retValue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus PK11_GetModInfo ( SECMODModule *  mod,
CK_INFO info 
)

Definition at line 534 of file pk11util.c.

{
    CK_RV crv;

    if (mod->functionList == NULL) return SECFailure;
    crv = PK11_GETTAB(mod)->C_GetInfo(info);
    if (crv != CKR_OK) {
       PORT_SetError(PK11_MapError(crv));
    }  
    return (crv == CKR_OK) ? SECSuccess : SECFailure;
}

Definition at line 551 of file pk11util.c.

{
    SECMODModule *mod = SECMOD_GetInternalModule();

    if (mod && mod->internal) {
       return mod->isFIPS;
    }

    return PR_FALSE;
}
SECStatus SECMOD_AddModule ( SECMODModule *  newModule)

Definition at line 471 of file pk11util.c.

{
    SECStatus rv;
    SECMODModule *oldModule;

    /* Test if a module w/ the same name already exists */
    /* and return SECWouldBlock if so. */
    /* We should probably add a new return value such as */
    /* SECDublicateModule, but to minimize ripples, I'll */
    /* give SECWouldBlock a new meaning */
    if ((oldModule = SECMOD_FindModule(newModule->commonName)) != NULL) {
       SECMOD_DestroyModule(oldModule);
        return SECWouldBlock;
        /* module already exists. */
    }

    rv = SECMOD_LoadPKCS11Module(newModule);
    if (rv != SECSuccess) {
       return rv;
    }

    if (newModule->parent == NULL) {
       newModule->parent = SECMOD_ReferenceModule(defaultDBModule);
    }

    SECMOD_AddPermDB(newModule);
    SECMOD_AddModuleToList(newModule);

    rv = STAN_AddModuleToDefaultTrustDomain(newModule);

    return rv;
}

Here is the caller graph for this function:

SECStatus SECMOD_AddModuleToDBOnlyList ( SECMODModule *  newModule)

Definition at line 180 of file pk11util.c.

Here is the caller graph for this function:

SECStatus secmod_AddModuleToList ( SECMODModuleList **  moduleList,
SECMODModule *  newModule 
)

Definition at line 142 of file pk11util.c.

{
    SECMODModuleList *mlp, *newListElement, *last = NULL;

    newListElement = SECMOD_NewModuleListElement();
    if (newListElement == NULL) {
       return SECFailure;
    }

    newListElement->module = SECMOD_ReferenceModule(newModule);

    SECMOD_GetWriteLock(moduleLock);
    /* Added it to the end (This is very inefficient, but Adding a module
     * on the fly should happen maybe 2-3 times through the life this program
     * on a given computer, and this list should be *SHORT*. */
    for(mlp = *moduleList; mlp != NULL; mlp = mlp->next) {
       last = mlp;
    }

    if (last == NULL) {
       *moduleList = newListElement;
    } else {
       SECMOD_AddList(last,newListElement,NULL);
    }
    SECMOD_ReleaseWriteLock(moduleLock);
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus SECMOD_AddModuleToList ( SECMODModule *  newModule)

Definition at line 171 of file pk11util.c.

{
    if (newModule->internal && !internalModule) {
       internalModule = SECMOD_ReferenceModule(newModule);
    }
    return secmod_AddModuleToList(&modules,newModule);
}

Here is the caller graph for this function:

SECStatus SECMOD_AddModuleToUnloadList ( SECMODModule *  newModule)

Definition at line 189 of file pk11util.c.

{
    return secmod_AddModuleToList(&modulesUnload,newModule);
}

Here is the caller graph for this function:

SECStatus SECMOD_AddNewModule ( const char *  moduleName,
const char *  dllPath,
unsigned long  defaultMechanismFlags,
unsigned long  cipherEnableFlags 
)

Definition at line 622 of file pk11util.c.

{
    return SECMOD_AddNewModuleEx(moduleName, dllPath, defaultMechanismFlags,
                  cipherEnableFlags, 
                  NULL, NULL); /* don't pass module or nss params */
}

Here is the caller graph for this function:

SECStatus SECMOD_AddNewModuleEx ( const char *  moduleName,
const char *  dllPath,
unsigned long  defaultMechanismFlags,
unsigned long  cipherEnableFlags,
char *  modparms,
char *  nssparms 
)

Definition at line 566 of file pk11util.c.

{
    SECMODModule *module;
    SECStatus result = SECFailure;
    int s,i;
    PK11SlotInfo* slot;

    PR_SetErrorText(0, NULL);

    module = SECMOD_CreateModule(dllPath, moduleName, modparms, nssparms);

    if (module == NULL) {
       return result;
    }

    if (module->dllName != NULL) {
        if (module->dllName[0] != 0) {
            result = SECMOD_AddModule(module);
            if (result == SECSuccess) {
                /* turn on SSL cipher enable flags */
                module->ssl[0] = cipherEnableFlags;

              SECMOD_GetReadLock(moduleLock);
                /* check each slot to turn on appropriate mechanisms */
                for (s = 0; s < module->slotCount; s++) {
                    slot = (module->slots)[s];
                    /* for each possible mechanism */
                    for (i=0; i < num_pk11_default_mechanisms; i++) {
                        /* we are told to turn it on by default ? */
                     PRBool add = 
                      (PK11_DefaultArray[i].flag & defaultMechanismFlags) ?
                                          PR_TRUE: PR_FALSE;
                        result = PK11_UpdateSlotAttribute(slot, 
                                   &(PK11_DefaultArray[i]),  add);
                    } /* for each mechanism */
                    /* disable each slot if the defaultFlags say so */
                    if (defaultMechanismFlags & PK11_DISABLE_FLAG) {
                        PK11_UserDisableSlot(slot);
                    }
                } /* for each slot of this module */
              SECMOD_ReleaseReadLock(moduleLock);

                /* delete and re-add module in order to save changes 
               * to the module */
              result = SECMOD_UpdateModule(module);
            }
        }
    }
    SECMOD_DestroyModule(module);
    return result;
}

Here is the caller graph for this function:

SECStatus SECMOD_CancelWait ( SECMODModule *  mod)

Definition at line 1133 of file pk11util.c.

{
    unsigned long controlMask = mod->evControlMask;
    SECStatus rv = SECSuccess;
    CK_RV crv;

    PZ_Lock(mod->refLock);
    mod->evControlMask |= SECMOD_END_WAIT;
    controlMask = mod->evControlMask;
    if (controlMask & SECMOD_WAIT_PKCS11_EVENT) {
        if (!pk11_getFinalizeModulesOption()) {
            /* can't get here unless pk11_getFinalizeModulesOption is set */
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            rv = SECFailure;
            goto loser;
        }
       /* NOTE: this call will drop all transient keys, in progress
        * operations, and any authentication. This is the only documented
        * way to get WaitForSlotEvent to return. Also note: for non-thread
        * safe tokens, we need to hold the module lock, this is not yet at
        * system shutdown/startup time, so we need to protect these calls */
       crv = PK11_GETTAB(mod)->C_Finalize(NULL);
       /* ok, we slammed the module down, now we need to reinit it in case
        * we intend to use it again */
       if (CKR_OK == crv) {
            PRBool alreadyLoaded;
           secmod_ModuleInit(mod, &alreadyLoaded);
       } else {
           /* Finalized failed for some reason,  notify the application
            * so maybe it has a prayer of recovering... */
           PORT_SetError(PK11_MapError(crv));
           rv = SECFailure;
       }
    } else if (controlMask & SECMOD_WAIT_SIMULATED_EVENT) {
       mod->evControlMask &= ~SECMOD_WAIT_SIMULATED_EVENT; 
                            /* Simulated events will eventually timeout
                             * and wake up in the loop */
    }
loser:
    PZ_Unlock(mod->refLock);
    return rv;
}

Here is the caller graph for this function:

Definition at line 845 of file pk11util.c.

{
    return (PRBool) (pendingModule == NULL);
}
SECStatus SECMOD_CloseUserDB ( PK11SlotInfo *  slot)

Definition at line 1421 of file pk11util.c.

{
    SECStatus rv;
    char *sendSpec;

    if (!slot->isInternal) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    
    sendSpec = PR_smprintf("tokens=[0x%x=<>]", slot->slotID);
    if (sendSpec == NULL) {
       /* PR_smprintf does not set no memory error */
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }
    rv = secmod_UserDBOp(CKO_NETSCAPE_DELSLOT, sendSpec);
    PR_smprintf_free(sendSpec);
    return rv;
}

Definition at line 398 of file pk11util.c.

{
    SECMODModuleList *mlp;
    SECMODModuleList **mlpp;
    SECStatus rv = SECFailure;

    if (pendingModule) {
       PORT_SetError(SEC_ERROR_MODULE_STUCK);
       return rv;
    }

    SECMOD_GetWriteLock(moduleLock);
    for(mlpp = &modules,mlp = modules; 
                            mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
       if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
           /* don't delete the internal module */
           if (mlp->module->internal) {
              SECMOD_RemoveList(mlpp,mlp);
              rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module);
           } 
           break;
       }
    }
    SECMOD_ReleaseWriteLock(moduleLock);

    if (rv == SECSuccess) {
       SECMODModule *newModule,*oldModule;

       if (mlp->module->isFIPS) {
           newModule = SECMOD_CreateModule(NULL, SECMOD_INT_NAME,
                            NULL, SECMOD_INT_FLAGS);
       } else {
           newModule = SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME,
                            NULL, SECMOD_FIPS_FLAGS);
       }
       if (newModule) {
           newModule->libraryParams = 
            PORT_ArenaStrdup(newModule->arena,mlp->module->libraryParams);
           rv = SECMOD_AddModule(newModule);
           if (rv != SECSuccess) {
              SECMOD_DestroyModule(newModule);
              newModule = NULL;
           }
       }
       if (newModule == NULL) {
           SECMODModuleList *last = NULL,*mlp2;
          /* we're in pretty deep trouble if this happens...Security
           * not going to work well... try to put the old module back on
           * the list */
          SECMOD_GetWriteLock(moduleLock);
          for(mlp2 = modules; mlp2 != NULL; mlp2 = mlp->next) {
              last = mlp2;
          }

          if (last == NULL) {
              modules = mlp;
          } else {
              SECMOD_AddList(last,mlp,NULL);
          }
          SECMOD_ReleaseWriteLock(moduleLock);
          return SECFailure; 
       }
       pendingModule = oldModule = internalModule;
       internalModule = NULL;
       SECMOD_DestroyModule(oldModule);
       SECMOD_DeletePermDB(mlp->module);
       SECMOD_DestroyModuleListElement(mlp);
       internalModule = newModule; /* adopt the module */
    }
    return rv;
}

Here is the caller graph for this function:

SECStatus SECMOD_DeleteModule ( const char *  name,
int type 
)

Definition at line 389 of file pk11util.c.

Here is the caller graph for this function:

SECStatus SECMOD_DeleteModuleEx ( const char *  name,
SECMODModule *  mod,
int type,
PRBool  permdb 
)

Definition at line 325 of file pk11util.c.

{
    SECMODModuleList *mlp;
    SECMODModuleList **mlpp;
    SECStatus rv = SECFailure;

    *type = SECMOD_EXTERNAL;

    SECMOD_GetWriteLock(moduleLock);
    for (mlpp = &modules,mlp = modules; 
                            mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
       if ((name && (PORT_Strcmp(name,mlp->module->commonName) == 0)) ||
                                                 mod == mlp->module) {
           /* don't delete the internal module */
           if (!mlp->module->internal) {
              SECMOD_RemoveList(mlpp,mlp);
              /* delete it after we release the lock */
              rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module);
           } else if (mlp->module->isFIPS) {
              *type = SECMOD_FIPS;
           } else {
              *type = SECMOD_INTERNAL;
           }
           break;
       }
    }
    if (mlp) {
       goto found;
    }
    /* not on the internal list, check the unload list */
    for (mlpp = &modulesUnload,mlp = modulesUnload; 
                            mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
       if ((name && (PORT_Strcmp(name,mlp->module->commonName) == 0)) ||
                                                 mod == mlp->module) {
           /* don't delete the internal module */
           if (!mlp->module->internal) {
              SECMOD_RemoveList(mlpp,mlp);
              rv = SECSuccess;
           } else if (mlp->module->isFIPS) {
              *type = SECMOD_FIPS;
           } else {
              *type = SECMOD_INTERNAL;
           }
           break;
       }
    }
found:
    SECMOD_ReleaseWriteLock(moduleLock);


    if (rv == SECSuccess) {
       if (permdb) {
           SECMOD_DeletePermDB(mlp->module);
       }
       SECMOD_DestroyModuleListElement(mlp);
    }
    return rv;
}

Here is the caller graph for this function:

void SECMOD_DestroyModule ( SECMODModule *  module)

Definition at line 741 of file pk11util.c.

{
    PRBool willfree = PR_FALSE;
    int slotCount;
    int i;

    PZ_Lock(module->refLock);
    if (module->refCount-- == 1) {
       willfree = PR_TRUE;
    }
    PORT_Assert(willfree || (module->refCount > 0));
    PZ_Unlock(module->refLock);

    if (!willfree) {
       return;
    }
   
    if (module->parent != NULL) {
       SECMODModule *parent = module->parent;
       /* paranoia, don't loop forever if the modules are looped */
       module->parent = NULL;
       SECMOD_DestroyModule(parent);
    }

    /* slots can't really disappear until our module starts freeing them,
     * so this check is safe */
    slotCount = module->slotCount;
    if (slotCount == 0) {
       SECMOD_SlotDestroyModule(module,PR_FALSE);
       return;
    }

    /* now free all out slots, when they are done, they will cause the
     * module to disappear altogether */
    for (i=0 ; i < slotCount; i++) {
       if (!module->slots[i]->disabled) {
              PK11_ClearSlotList(module->slots[i]);
       }
       PK11_FreeSlot(module->slots[i]);
    }
    /* WARNING: once the last slot has been freed is it possible (even likely)
     * that module is no more... touching it now is a good way to go south */
}

Here is the caller graph for this function:

void SECMOD_DestroyModuleList ( SECMODModuleList *  list)

Definition at line 837 of file pk11util.c.

{
    SECMODModuleList *lp;

    for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ;
}

Here is the caller graph for this function:

SECMODModuleList* SECMOD_DestroyModuleListElement ( SECMODModuleList *  element)

Definition at line 820 of file pk11util.c.

{
    SECMODModuleList *next = element->next;

    if (element->module) {
       SECMOD_DestroyModule(element->module);
       element->module = NULL;
    }
    PORT_Free(element);
    return next;
}

Here is the caller graph for this function:

SECMODModule* SECMOD_FindModule ( const char *  name)

Definition at line 221 of file pk11util.c.

{
    SECMODModuleList *mlp;
    SECMODModule *module = NULL;

    SECMOD_GetReadLock(moduleLock);
    for(mlp = modules; mlp != NULL; mlp = mlp->next) {
       if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
           module = mlp->module;
           SECMOD_ReferenceModule(module);
           break;
       }
    }
    if (module) {
       goto found;
    }
    for(mlp = modulesUnload; mlp != NULL; mlp = mlp->next) {
       if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
           module = mlp->module;
           SECMOD_ReferenceModule(module);
           break;
       }
    }

found:
    SECMOD_ReleaseReadLock(moduleLock);

    return module;
}

Here is the caller graph for this function:

SECMODModule* SECMOD_FindModuleByID ( SECMODModuleID  id)

Definition at line 256 of file pk11util.c.

{
    SECMODModuleList *mlp;
    SECMODModule *module = NULL;

    SECMOD_GetReadLock(moduleLock);
    for(mlp = modules; mlp != NULL; mlp = mlp->next) {
       if (id == mlp->module->moduleID) {
           module = mlp->module;
           SECMOD_ReferenceModule(module);
           break;
       }
    }
    SECMOD_ReleaseReadLock(moduleLock);
    if (module == NULL) {
       PORT_SetError(SEC_ERROR_NO_MODULE);
    }
    return module;
}

Here is the caller graph for this function:

PK11SlotInfo* SECMOD_FindSlot ( SECMODModule *  module,
const char *  name 
)

Definition at line 505 of file pk11util.c.

{
    int i;
    char *string;
    PK11SlotInfo *retSlot = NULL;

    SECMOD_GetReadLock(moduleLock);
    for (i=0; i < module->slotCount; i++) {
       PK11SlotInfo *slot = module->slots[i];

       if (PK11_IsPresent(slot)) {
           string = PK11_GetTokenName(slot);
       } else {
           string = PK11_GetSlotName(slot);
       }
       if (PORT_Strcmp(name,string) == 0) {
           retSlot = PK11_ReferenceSlot(slot);
           break;
       }
    }
    SECMOD_ReleaseReadLock(moduleLock);

    if (retSlot == NULL) {
       PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
    }
    return retSlot;
}
PK11SlotInfo* SECMOD_FindSlotByID ( SECMODModule *  module,
CK_SLOT_ID  slotID 
)

Definition at line 280 of file pk11util.c.

{
    int i;
    PK11SlotInfo *slot = NULL;

    SECMOD_GetReadLock(moduleLock);
    for (i=0; i < module->slotCount; i++) {
       PK11SlotInfo *cSlot = module->slots[i];

       if (cSlot->slotID == slotID) {
           slot = PK11_ReferenceSlot(cSlot);
           break;
       }
    }
    SECMOD_ReleaseReadLock(moduleLock);

    if (slot == NULL) {
       PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
    }
    return slot;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECMODModuleList* SECMOD_GetDBModuleList ( void  )

Definition at line 199 of file pk11util.c.

{ return modulesDB; }
SECMODModuleList* SECMOD_GetDeadModuleList ( void  )

Definition at line 198 of file pk11util.c.

{ return modulesUnload; }

Here is the caller graph for this function:

SECMODModuleList* SECMOD_GetDefaultModuleList ( void  )

Definition at line 197 of file pk11util.c.

{ return modules; }

Here is the caller graph for this function:

Definition at line 212 of file pk11util.c.

{ return moduleLock; }

Here is the caller graph for this function:

SECMODModule* SECMOD_GetInternalModule ( void  )

Definition at line 135 of file pk11util.c.

{
   return internalModule;
}

Here is the caller graph for this function:

PK11SlotInfo* secmod_HandleWaitForSlotEvent ( SECMODModule *  mod,
unsigned long  flags,
PRIntervalTime  latency 
)

Definition at line 984 of file pk11util.c.

{
    PRBool removableSlotsFound = PR_FALSE;
    int i;
    int error = SEC_ERROR_NO_EVENT;

    PZ_Lock(mod->refLock);
    if (mod->evControlMask & SECMOD_END_WAIT) {
       mod->evControlMask &= ~SECMOD_END_WAIT;
       PZ_Unlock(mod->refLock);
       PORT_SetError(SEC_ERROR_NO_EVENT);
       return NULL;
    }
    mod->evControlMask |= SECMOD_WAIT_SIMULATED_EVENT;
    while (mod->evControlMask & SECMOD_WAIT_SIMULATED_EVENT) {
       PZ_Unlock(mod->refLock);
       /* now is a good time to see if new slots have been added */
       SECMOD_UpdateSlotList(mod);

       /* loop through all the slots on a module */
       SECMOD_GetReadLock(moduleLock);
       for (i=0; i < mod->slotCount; i++) {
           PK11SlotInfo *slot = mod->slots[i];
           uint16 series;
           PRBool present;

           /* perm modules do not change */
           if (slot->isPerm) {
              continue;
           }
           removableSlotsFound = PR_TRUE;
           /* simulate the PKCS #11 module flags. are the flags different
            * from the last time we called? */
           series = slot->series;
           present = PK11_IsPresent(slot);
           if ((slot->flagSeries != series) || (slot->flagState != present)) {
              slot->flagState = present;
              slot->flagSeries = series;
              SECMOD_ReleaseReadLock(moduleLock);
              PZ_Lock(mod->refLock);
              mod->evControlMask &= ~SECMOD_END_WAIT;
              PZ_Unlock(mod->refLock);
              return PK11_ReferenceSlot(slot);
           }
       }
       SECMOD_ReleaseReadLock(moduleLock);
       /* if everything was perm modules, don't lock up forever */
       if (!removableSlotsFound) {
           error =SEC_ERROR_NO_SLOT_SELECTED;
           PZ_Lock(mod->refLock);
           break;
       }
       if (flags & CKF_DONT_BLOCK) {
           PZ_Lock(mod->refLock);
           break;
       }
       PR_Sleep(latency);
       PZ_Lock(mod->refLock);
    }
    mod->evControlMask &= ~SECMOD_END_WAIT;
    PZ_Unlock(mod->refLock);
    PORT_SetError(error);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool SECMOD_HasRemovableSlots ( SECMODModule *  mod)

Definition at line 1182 of file pk11util.c.

{
    int i;
    PRBool ret = PR_FALSE;

    SECMOD_GetReadLock(moduleLock);
    for (i=0; i < mod->slotCount; i++) {
       PK11SlotInfo *slot = mod->slots[i];
       /* perm modules are not inserted or removed */
       if (slot->isPerm) {
           continue;
       }
       ret = PR_TRUE;
       break;
    }
    SECMOD_ReleaseReadLock(moduleLock);
    return ret;
}

Here is the caller graph for this function:

Definition at line 67 of file pk11util.c.

{
    /* don't initialize twice */
    if (moduleLock) return;

    moduleLock = SECMOD_NewListLock();
    PK11_InitSlotLists();
}

Here is the caller graph for this function:

unsigned long SECMOD_InternaltoPubCipherFlags ( unsigned long  internalFlags)

Definition at line 686 of file pk11util.c.

{
    return internalFlags;
}
unsigned long SECMOD_InternaltoPubMechFlags ( unsigned long  internalFlags)

Definition at line 664 of file pk11util.c.

{
    unsigned long publicFlags = internalFlags;

    if (internalFlags & SECMOD_RANDOM_FLAG) {
        publicFlags &= ~SECMOD_RANDOM_FLAG;
        publicFlags |= PUBLIC_MECH_RANDOM_FLAG;
    }
    return publicFlags;
}
PRBool SECMOD_IsModulePresent ( unsigned long int  pubCipherEnableFlags)

Definition at line 693 of file pk11util.c.

{
    PRBool result = PR_FALSE;
    SECMODModuleList *mods = SECMOD_GetDefaultModuleList();
    SECMOD_GetReadLock(moduleLock);


    for ( ; mods != NULL; mods = mods->next) {
        if (mods->module->ssl[0] & 
              SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
            result = PR_TRUE;
        }
    }

    SECMOD_ReleaseReadLock(moduleLock);
    return result;
}
PK11SlotInfo* SECMOD_LookupSlot ( SECMODModuleID  moduleID,
CK_SLOT_ID  slotID 
)

Definition at line 306 of file pk11util.c.

{
    SECMODModule *module;
    PK11SlotInfo *slot;

    module = SECMOD_FindModuleByID(moduleID);
    if (module == NULL) return NULL;

    slot = SECMOD_FindSlotByID(module, slotID);
    SECMOD_DestroyModule(module);
    return slot;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECMODModuleList* SECMOD_NewModuleListElement ( void  )

Definition at line 712 of file pk11util.c.

{
    SECMODModuleList *newModList;

    newModList= (SECMODModuleList *) PORT_Alloc(sizeof(SECMODModuleList));
    if (newModList) {
       newModList->next = NULL;
       newModList->module = NULL;
    }
    return newModList;
}

Here is the caller graph for this function:

PK11SlotInfo* SECMOD_OpenUserDB ( const char *  moduleSpec)

Definition at line 1338 of file pk11util.c.

{
    CK_SLOT_ID slotID = 0;
    char *escSpec;
    char *sendSpec;
    SECStatus rv;
    SECMODModule *mod;
    CK_SLOT_ID i, minSlotID, maxSlotID;
    PRBool found = PR_FALSE;

    if (moduleSpec == NULL) {
       return NULL;
    }

    /* NOTE: unlike most PK11 function, this does not return a reference
     * to the module */
    mod = SECMOD_GetInternalModule();
    if (!mod) {
       /* shouldn't happen */
       PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
       return NULL;
    }

    /* look for a free slot id on the internal module */
    if (mod->isFIPS) {
       minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
       maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
    } else {
       minSlotID = SFTK_MIN_USER_SLOT_ID;
       maxSlotID = SFTK_MAX_USER_SLOT_ID;
    }
    for (i=minSlotID; i < maxSlotID; i++) {
       PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, i);
       if (slot) {
           PRBool present = PK11_IsPresent(slot);
           PK11_FreeSlot(slot);
           if (present) {
              continue;
           }
           /* not present means it's available */
       }
       /* it doesn't exist or isn't present, it's available */
       slotID = i;
       found = PR_TRUE;
       break;
    }

    if (!found) {
       /* this could happen if we try to open too many slots */
       PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
       return NULL;
    }

    /* we've found the slot, now build the moduleSpec */

    escSpec = nss_doubleEscape(moduleSpec);
    if (escSpec == NULL) {
       return NULL;
    }
    sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
    PORT_Free(escSpec);

    if (sendSpec == NULL) {
       /* PR_smprintf does not set no memory error */
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }
    rv = secmod_UserDBOp(CKO_NETSCAPE_NEWSLOT, sendSpec);
    PR_smprintf_free(sendSpec);
    if (rv != SECSuccess) {
       return NULL;
    }

    return SECMOD_FindSlotByID(mod, slotID);
}
unsigned long SECMOD_PubCipherFlagstoInternal ( unsigned long  publicFlags)

Definition at line 680 of file pk11util.c.

{
    return publicFlags;
}

Here is the caller graph for this function:

unsigned long SECMOD_PubMechFlagstoInternal ( unsigned long  publicFlags)

Definition at line 652 of file pk11util.c.

{
    unsigned long internalFlags = publicFlags;

    if (publicFlags & PUBLIC_MECH_RANDOM_FLAG) {
        internalFlags &= ~PUBLIC_MECH_RANDOM_FLAG;
        internalFlags |= SECMOD_RANDOM_FLAG;
    }
    return internalFlags;
}

Here is the caller graph for this function:

SECMODModule* SECMOD_ReferenceModule ( SECMODModule *  module)

Definition at line 728 of file pk11util.c.

{
    PZ_Lock(module->refLock);
    PORT_Assert(module->refCount > 0);

    module->refCount++;
    PZ_Unlock(module->refLock);
    return module;
}

Here is the caller graph for this function:

Definition at line 78 of file pk11util.c.

{
    /* destroy the lock */
    if (moduleLock) {
       SECMOD_DestroyListLock(moduleLock);
       moduleLock = NULL;
    }
    /* free the internal module */
    if (internalModule) {
       SECMOD_DestroyModule(internalModule);
       internalModule = NULL;
    }

    /* free the default database module */
    if (defaultDBModule) {
       SECMOD_DestroyModule(defaultDBModule);
       defaultDBModule = NULL;
    }
       
    /* destroy the list */
    if (modules) {
       SECMOD_DestroyModuleList(modules);
       modules = NULL;
    }
   
    if (modulesDB) {
       SECMOD_DestroyModuleList(modulesDB);
       modulesDB = NULL;
    }

    if (modulesUnload) {
       SECMOD_DestroyModuleList(modulesUnload);
       modulesUnload = NULL;
    }

    /* make all the slots and the lists go away */
    PK11_DestroySlotLists();

    nss_DumpModuleLog();

#ifdef DEBUG
    if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
       PORT_Assert(secmod_PrivateModuleCount == 0);
    }
#endif
    if (secmod_PrivateModuleCount) {
       PORT_SetError(SEC_ERROR_BUSY);
       return SECFailure;
    }
    return SECSuccess;
}

Here is the caller graph for this function:

void SECMOD_SlotDestroyModule ( SECMODModule *  module,
PRBool  fromSlot 
)

Definition at line 789 of file pk11util.c.

{
    PRBool willfree = PR_FALSE;
    if (fromSlot) {
        PORT_Assert(module->refCount == 0);
       PZ_Lock(module->refLock);
       if (module->slotCount-- == 1) {
           willfree = PR_TRUE;
       }
       PORT_Assert(willfree || (module->slotCount > 0));
       PZ_Unlock(module->refLock);
        if (!willfree) return;
    }

    if (module == pendingModule) {
       pendingModule = NULL;
    }

    if (module->loaded) {
       SECMOD_UnloadModule(module);
    }
    PZ_DestroyLock(module->refLock);
    PORT_FreeArena(module->arena,PR_FALSE);
    secmod_PrivateModuleCount--;
}

Here is the caller graph for this function:

SECStatus SECMOD_UpdateModule ( SECMODModule *  module)

Definition at line 632 of file pk11util.c.

{
    SECStatus result;

    result = SECMOD_DeletePermDB(module);
                
    if (result == SECSuccess) {          
       result = SECMOD_AddPermDB(module);
    }
    return result;
}

Here is the caller graph for this function:

SECStatus SECMOD_UpdateSlotList ( SECMODModule *  mod)

Definition at line 859 of file pk11util.c.

{
    CK_RV crv;
    CK_ULONG count;
    CK_ULONG i, oldCount;
    PRBool freeRef = PR_FALSE;
    void *mark = NULL;
    CK_ULONG *slotIDs = NULL;
    PK11SlotInfo **newSlots = NULL;
    PK11SlotInfo **oldSlots = NULL;

    /* C_GetSlotList is not a session function, make sure 
     * calls are serialized */
    PZ_Lock(mod->refLock);
    freeRef = PR_TRUE;
    /* see if the number of slots have changed */
    crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, NULL, &count);
    if (crv != CKR_OK) {
       PORT_SetError(PK11_MapError(crv));
       goto loser;
    }
    /* nothing new, blow out early, we want this function to be quick
     * and cheap in the normal case  */
    if (count == mod->slotCount) {
       PZ_Unlock(mod->refLock);
       return SECSuccess;
    }
    if (count < (CK_ULONG)mod->slotCount) {
       /* shouldn't happen with a properly functioning PKCS #11 module */
       PORT_SetError( SEC_ERROR_INCOMPATIBLE_PKCS11 );
       goto loser;
    }

    /* get the new slot list */
    slotIDs = PORT_NewArray(CK_SLOT_ID, count);
    if (slotIDs == NULL) {
       goto loser;
    }

    crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, slotIDs, &count);
    if (crv != CKR_OK) {
       PORT_SetError(PK11_MapError(crv));
       goto loser;
    }
    freeRef = PR_FALSE;
    PZ_Unlock(mod->refLock);
    mark = PORT_ArenaMark(mod->arena);
    if (mark == NULL) {
       goto loser;
    }
    newSlots = PORT_ArenaZNewArray(mod->arena,PK11SlotInfo *,count);

    /* walk down the new slot ID list returned from the module. We keep
     * the old slots which match a returned ID, and we initialize the new 
     * slots. */
    for (i=0; i < count; i++) {
       PK11SlotInfo *slot = SECMOD_FindSlotByID(mod,slotIDs[i]);

       if (!slot) {
           /* we have a new slot create a new slot data structure */
           slot = PK11_NewSlotInfo(mod);
           if (!slot) {
              goto loser;
           }
           PK11_InitSlot(mod, slotIDs[i], slot);
           STAN_InitTokenForSlotInfo(NULL, slot);
       }
       newSlots[i] = slot;
    }
    STAN_ResetTokenInterator(NULL);
    PORT_Free(slotIDs);
    slotIDs = NULL;
    PORT_ArenaUnmark(mod->arena, mark);

    /* until this point we're still using the old slot list. Now we update
     * module slot list. We update the slots (array) first then the count, 
     * since we've already guarrenteed that count has increased (just in case 
     * someone is looking at the slots field of  module without holding the 
     * moduleLock */
    SECMOD_GetWriteLock(moduleLock);
    oldCount =mod->slotCount;
    oldSlots = mod->slots;
    mod->slots = newSlots; /* typical arena 'leak'... old mod->slots is
                         * allocated out of the module arena and won't
                         * be freed until the module is freed */
    mod->slotCount = count;
    SECMOD_ReleaseWriteLock(moduleLock);
    /* free our old references before forgetting about oldSlot*/
    for (i=0; i < oldCount; i++) {
       PK11_FreeSlot(oldSlots[i]);
    }
    return SECSuccess;

loser:
    if (freeRef) {
       PZ_Unlock(mod->refLock);
    }
    if (slotIDs) {
       PORT_Free(slotIDs);
    }
    /* free all the slots we allocated. newSlots are part of the
     * mod arena. NOTE: the newSlots array contain both new and old
     * slots, but we kept a reference to the old slots when we built the new
     * array, so we need to free all the slots in newSlots array. */
    if (newSlots) {
       for (i=0; i < count; i++) {
           if (newSlots[i] == NULL) {
              break; /* hit the last one */
           }
           PK11_FreeSlot(newSlots[i]);
       }
    }
    /* must come after freeing newSlots */
    if (mark) {
       PORT_ArenaRelease(mod->arena, mark);
    }
    return SECFailure;
}

Here is the caller graph for this function:

static SECStatus secmod_UserDBOp ( CK_OBJECT_CLASS  objClass,
const char *  sendSpec 
) [static]

Definition at line 1205 of file pk11util.c.

{
    PK11SlotInfo *slot = PK11_GetInternalSlot();
    CK_OBJECT_HANDLE dummy;
    CK_ATTRIBUTE template[2] ;
    CK_ATTRIBUTE *attrs = template;
    SECStatus rv;
    CK_RV crv;

    PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
    PK11_SETATTRS(attrs, CKA_NETSCAPE_MODULE_SPEC , (unsigned char *)sendSpec,
                                    strlen(sendSpec)+1); attrs++;

    PORT_Assert(attrs-template <= 2);


    PK11_EnterSlotMonitor(slot);
    crv = PK11_CreateNewObject(slot, slot->session,
       template, attrs-template, PR_FALSE, &dummy);
    PK11_ExitSlotMonitor(slot);

    if (crv != CKR_OK) {
       PK11_FreeSlot(slot);
       PORT_SetError(PK11_MapError(crv));
       return SECFailure;
    }
    rv = SECMOD_UpdateSlotList(slot->module);
    PK11_FreeSlot(slot);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PK11SlotInfo* SECMOD_WaitForAnyTokenEvent ( SECMODModule *  mod,
unsigned long  flags,
PRIntervalTime  latency 
)

Definition at line 1057 of file pk11util.c.

{
    CK_SLOT_ID id;
    CK_RV crv;
    PK11SlotInfo *slot;

    if (!pk11_getFinalizeModulesOption() ||
        ((mod->cryptokiVersion.major == 2) &&
         (mod->cryptokiVersion.minor < 1))) { 
        /* if we are sharing the module with other software in our
         * address space, we can't reliably use C_WaitForSlotEvent(),
         * and if the module is version 2.0, C_WaitForSlotEvent() doesn't
         * exist */
       return secmod_HandleWaitForSlotEvent(mod, flags, latency);
    }
    /* first the the PKCS #11 call */
    PZ_Lock(mod->refLock);
    if (mod->evControlMask & SECMOD_END_WAIT) {
       goto end_wait;
    }
    mod->evControlMask |= SECMOD_WAIT_PKCS11_EVENT;
    PZ_Unlock(mod->refLock);
    crv = PK11_GETTAB(mod)->C_WaitForSlotEvent(flags, &id, NULL);
    PZ_Lock(mod->refLock);
    mod->evControlMask &= ~SECMOD_WAIT_PKCS11_EVENT;
    /* if we are in end wait, short circuit now, don't even risk
     * going into secmod_HandleWaitForSlotEvent */
    if (mod->evControlMask & SECMOD_END_WAIT) {
       goto end_wait;
    }
    PZ_Unlock(mod->refLock);
    if (crv == CKR_FUNCTION_NOT_SUPPORTED) {
       /* module doesn't support that call, simulate it */
       return secmod_HandleWaitForSlotEvent(mod, flags, latency);
    }
    if (crv != CKR_OK) {
       /* we can get this error if finalize was called while we were
        * still running. This is the only way to force a C_WaitForSlotEvent()
        * to return in PKCS #11. In this case, just return that there
        * was no event. */
       if (crv == CKR_CRYPTOKI_NOT_INITIALIZED) {
           PORT_SetError(SEC_ERROR_NO_EVENT);
       } else {
           PORT_SetError(PK11_MapError(crv));
       }
       return NULL;
    }
    slot = SECMOD_FindSlotByID(mod, id);
    if (slot == NULL) {
       /* possibly a new slot that was added? */
       SECMOD_UpdateSlotList(mod);
       slot = SECMOD_FindSlotByID(mod, id);
    }
    /* if we are in the delay period for the "isPresent" call, reset
     * the delay since we know things have probably changed... */
    if (slot && slot->nssToken && slot->nssToken->slot) {
       nssSlot_ResetDelay(slot->nssToken->slot);
    }
    return slot;

    /* must be called with the lock on. */
end_wait:
    mod->evControlMask &= ~SECMOD_END_WAIT;
    PZ_Unlock(mod->refLock);
    PORT_SetError(SEC_ERROR_NO_EVENT);
    return NULL;
}

Here is the caller graph for this function:


Variable Documentation

SECMODModule* defaultDBModule = NULL [static]

Definition at line 56 of file pk11util.c.

SECMODModule* internalModule = NULL [static]

Definition at line 55 of file pk11util.c.

Definition at line 58 of file pk11util.c.

SECMODModuleList* modules = NULL [static]

Definition at line 52 of file pk11util.c.

SECMODModuleList* modulesDB = NULL [static]

Definition at line 53 of file pk11util.c.

SECMODModuleList* modulesUnload = NULL [static]

Definition at line 54 of file pk11util.c.

Definition at line 85 of file pk11slot.c.

SECMODModule* pendingModule = NULL [static]

Definition at line 57 of file pk11util.c.

PK11DefaultArrayEntry PK11_DefaultArray[]

Definition at line 64 of file pk11slot.c.

Definition at line 60 of file pk11util.c.