Beispiel #1
0
/*
 * Find the Slot based on ID and the module.
 */
PK11SlotInfo *
SECMOD_FindSlotByID(SECMODModule *module, CK_SLOT_ID slotID)
{
    int i;
    PK11SlotInfo *slot = NULL;

    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return slot;
    }
    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;
}
Beispiel #2
0
/* nsIEnumerator listModules (); */
NS_IMETHODIMP 
nsPKCS11ModuleDB::ListModules(nsIEnumerator **_retval)
{
  nsNSSShutDownPreventionLock locker;
  nsresult rv = NS_OK;
  /* get isupports array */
  nsCOMPtr<nsISupportsArray> array;
  rv = NS_NewISupportsArray(getter_AddRefs(array));
  if (NS_FAILED(rv)) return rv;
  /* get the default list of modules */
  SECMODModuleList *list = SECMOD_GetDefaultModuleList();
  /* lock down the list for reading */
  SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
  SECMOD_GetReadLock(lock);
  while (list) {
    nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module);
    array->AppendElement(module);
    list = list->next;
  }
  /* Get the modules in the database that didn't load */
  list = SECMOD_GetDeadModuleList();
  while (list) {
    nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module);
    array->AppendElement(module);
    list = list->next;
  }
  SECMOD_ReleaseReadLock(lock);
  rv = array->Enumerate(_retval);
  return rv;
}
Beispiel #3
0
PK11SlotInfo *
SECMOD_FindSlot(SECMODModule *module,const char *name) 
{
    int i;
    char *string;
    PK11SlotInfo *retSlot = NULL;

    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return retSlot;
    }
    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;
}
Beispiel #4
0
/* nsIEnumerator listSlots (); */
NS_IMETHODIMP 
nsPKCS11Module::ListSlots(nsIEnumerator **_retval)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  nsresult rv = NS_OK;
  int i;
  /* get isupports array */
  nsCOMPtr<nsISupportsArray> array;
  rv = NS_NewISupportsArray(getter_AddRefs(array));
  if (NS_FAILED(rv)) return rv;
  /* applications which allow new slot creation (which Firefox now does
   * since it uses the WaitForSlotEvent call) need to hold the
   * ModuleList Read lock to prevent the slot array from changing out
   * from under it. */
  SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
  SECMOD_GetReadLock(lock);
  for (i=0; i<mModule->slotCount; i++) {
    if (mModule->slots[i]) {
      nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(mModule->slots[i]);
      array->AppendElement(slot);
    }
  }
  SECMOD_ReleaseReadLock(lock);
  rv = array->Enumerate(_retval);
  return rv;
}
Beispiel #5
0
PRBool
IsP11KitEnabled(void)
{
    SECMODListLock *lock;
    SECMODModuleList *mlp;
    PRBool found = PR_FALSE;

    lock = SECMOD_GetDefaultModuleListLock();
    if (!lock) {
        PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]);
        return found;
    }

    SECMOD_GetReadLock(lock);

    mlp = SECMOD_GetDefaultModuleList();
    for (; mlp != NULL; mlp = mlp->next) {
        if (IsP11KitProxyModule(mlp->module)) {
            found = PR_TRUE;
            break;
        }
    }

    SECMOD_ReleaseReadLock(lock);
    return found;
}
Beispiel #6
0
/*
 * check to see if the module has removable slots that we may need to
 * watch for.
 */
PRBool
SECMOD_HasRemovableSlots(SECMODModule *mod)
{
    int i;
    PRBool ret = PR_FALSE;

    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return ret;
    }
    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;
    }
    if (mod->slotCount == 0 ) {
	ret = PR_TRUE;
    }
    SECMOD_ReleaseReadLock(moduleLock);
    return ret;
}
Beispiel #7
0
/*
 * find a module by name, and add a reference to it.
 * return that module.
 */
SECMODModule *
SECMOD_FindModule(const char *name)
{
    SECMODModuleList *mlp;
    SECMODModule *module = NULL;

    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return module;
    }
    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;
}
/* installs the PKCS11 module & update registry */
SECStatus 
SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
                              unsigned long defaultMechanismFlags,
                              unsigned long cipherEnableFlags,
                              char* modparms, char* nssparms)
{
    SECMODModule *module;
    SECStatus result = SECFailure;
    int s,i;
    PK11SlotInfo* slot;

    PR_SetErrorText(0, NULL);
    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return result;
    }

    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;
}
Beispiel #9
0
NSS_IMPLEMENT PRStatus
STAN_LoadDefaultNSS3TrustDomain (
  void
)
{
    NSSTrustDomain *td;
    SECMODModuleList *mlp;
    SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
    int i;

    if (g_default_trust_domain || g_default_crypto_context) {
	/* Stan is already initialized or a previous shutdown failed. */
	nss_SetError(NSS_ERROR_ALREADY_INITIALIZED);
	return PR_FAILURE;
    }
    td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
    if (!td) {
	return PR_FAILURE;
    }
    /*
     * Deadlock warning: we should never acquire the moduleLock while
     * we hold the tokensLock. We can use the NSSRWLock Rank feature to
     * guarrentee this. tokensLock have a higher rank than module lock.
     */
    td->tokenList = nssList_Create(td->arena, PR_TRUE);
    if (!td->tokenList) {
	goto loser;
    }
    SECMOD_GetReadLock(moduleLock);
    NSSRWLock_LockWrite(td->tokensLock);
    for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) {
	for (i=0; i < mlp->module->slotCount; i++) {
	    STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]);
	}
    }
    td->tokens = nssList_CreateIterator(td->tokenList);
    NSSRWLock_UnlockWrite(td->tokensLock);
    SECMOD_ReleaseReadLock(moduleLock);
    if (!td->tokens) {
	goto loser;
    }
    g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
    if (!g_default_crypto_context) {
	goto loser;
    }
    g_default_trust_domain = td;
    return PR_SUCCESS;

  loser:
    NSSTrustDomain_Destroy(td);
    return PR_FAILURE;
}
/************************************************************************
 *
 * L i s t M o d u l e s
 *
 * Lists all the modules in the database, along with their slots and tokens.
 */
Error
ListModules()
{
    SECMODListLock *lock;
    SECMODModuleList *list;
    SECMODModuleList *deadlist;
    SECMODModuleList *mlp;
    Error ret=UNSPECIFIED_ERR;
    int count = 0;

    lock = SECMOD_GetDefaultModuleListLock();
    if(!lock) {
	PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]);
	return NO_LIST_LOCK_ERR;
    }

    SECMOD_GetReadLock(lock);

    list = SECMOD_GetDefaultModuleList();
    deadlist = SECMOD_GetDeadModuleList();
    if (!list && !deadlist) {
	PR_fprintf(PR_STDERR, errStrings[NO_MODULE_LIST_ERR]);
	ret = NO_MODULE_LIST_ERR;
	goto loser;
    }

    PR_fprintf(PR_STDOUT,
	"\nListing of PKCS #11 Modules\n"
	"-----------------------------------------------------------\n");
    
    for(mlp=list; mlp != NULL; mlp = mlp->next) {
	printModule(mlp->module, &count);
    }
    for (mlp=deadlist; mlp != NULL; mlp = mlp->next) {
	printModule(mlp->module, &count);
    }


    PR_fprintf(PR_STDOUT,
	"-----------------------------------------------------------\n");

    ret = SUCCESS;

loser:
    SECMOD_ReleaseReadLock(lock);
    return ret;
}
static void
activate_all_drivers_async (GsdSmartcardManager *self,
                            GCancellable        *cancellable,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data)
{
        GTask *task;
        SECMODListLock *lock;
        SECMODModuleList *driver_list, *node;
        ActivateAllDriversOperation *operation;

        task = g_task_new (self, cancellable, callback, user_data);
        operation = g_new0 (ActivateAllDriversOperation, 1);
        g_task_set_task_data (task, operation, (GDestroyNotify) g_free);

        lock = SECMOD_GetDefaultModuleListLock ();

        g_assert (lock != NULL);

        SECMOD_GetReadLock (lock);
        driver_list = SECMOD_GetDefaultModuleList ();
        for (node = driver_list; node != NULL; node = node->next) {
                if (!node->module->loaded)
                        continue;

                if (!SECMOD_HasRemovableSlots (node->module))
                        continue;

                if (node->module->dllName == NULL)
                        continue;

                operation->pending_drivers_count++;

                activate_driver (self, node->module,
                                 cancellable,
                                 (GAsyncReadyCallback) on_driver_activated,
                                 task);

        }
        SECMOD_ReleaseReadLock (lock);

        try_to_complete_all_drivers_activation (task);
}
Beispiel #12
0
static PRBool
module_has_removable_hw_slots(SECMODModule *mod)
{
    int i;
    PRBool ret = PR_FALSE;
    SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();

    if (!moduleLock) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return ret;
    }
    SECMOD_GetReadLock(moduleLock);
    for (i = 0; i < mod->slotCount; i++) {
        PK11SlotInfo *slot = mod->slots[i];
        if (PK11_IsRemovable(slot) && PK11_IsHW(slot)) {
            ret = PR_TRUE;
            break;
        }
    }
    SECMOD_ReleaseReadLock(moduleLock);
    return ret;
}
Beispiel #13
0
/* Funtion reports true if module of modType is installed/configured */
PRBool 
SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
{
    PRBool result = PR_FALSE;
    SECMODModuleList *mods;

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

    SECMOD_ReleaseReadLock(moduleLock);
    return result;
}
Beispiel #14
0
void PK11_LogoutAll(void)
{
    SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
    SECMODModuleList *modList = SECMOD_GetDefaultModuleList();
    SECMODModuleList *mlp = NULL;
    int i;

    /* NSS is not initialized, there are not tokens to log out */
    if (lock == NULL) {
	return;
    }

    SECMOD_GetReadLock(lock);
    /* find the number of entries */
    for (mlp = modList; mlp != NULL; mlp = mlp->next) {
	for (i=0; i < mlp->module->slotCount; i++) {
	    PK11_Logout(mlp->module->slots[i]);
	}
    }

    SECMOD_ReleaseReadLock(lock);
}
Beispiel #15
0
/*
 * find the function pointer.
 */
SECMODModule *
secmod_FindModuleByFuncPtr(void *funcPtr) 
{
    SECMODModuleList *mlp;
    SECMODModule *module = NULL;

    SECMOD_GetReadLock(moduleLock);
    for(mlp = modules; mlp != NULL; mlp = mlp->next) {
	/* paranoia, shouldn't ever happen */
	if (!mlp->module) {
	    continue;
	}
	if (funcPtr == mlp->module->functionList) {
	    module = mlp->module;
	    SECMOD_ReferenceModule(module);
	    break;
	}
    }
    SECMOD_ReleaseReadLock(moduleLock);
    if (module == NULL) {
	PORT_SetError(SEC_ERROR_NO_MODULE);
    }
    return module;
}
Beispiel #16
0
/*
 * find a module by ID, and add a reference to it.
 * return that module.
 */
SECMODModule *
SECMOD_FindModuleByID(SECMODModuleID id) 
{
    SECMODModuleList *mlp;
    SECMODModule *module = NULL;

    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return module;
    }
    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;
}
Beispiel #17
0
VCardEmulError
vcard_emul_init(const VCardEmulOptions *options)
{
    SECStatus rv;
    PRBool ret, has_readers = PR_FALSE;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    SECMODListLock *module_lock;
    SECMODModuleList *module_list;
    SECMODModuleList *mlp;
    int i;

    if (vcard_emul_init_called) {
        return VCARD_EMUL_INIT_ALREADY_INITED;
    }
    vcard_emul_init_called = 1;
    vreader_init();
    vevent_queue_init();

    if (options == NULL) {
        options = &default_options;
    }

    /* first initialize NSS */
    if (options->nss_db) {
        rv = NSS_Init(options->nss_db);
    } else {
        gchar *path;
#ifndef _WIN32
        path = g_strdup("/etc/pki/nssdb");
#else
        if (g_get_system_config_dirs() == NULL ||
            g_get_system_config_dirs()[0] == NULL) {
            return VCARD_EMUL_FAIL;
        }

        path = g_build_filename(
            g_get_system_config_dirs()[0], "pki", "nssdb", NULL);
#endif

        rv = NSS_Init(path);
        g_free(path);
    }
    if (rv != SECSuccess) {
        return VCARD_EMUL_FAIL;
    }
    /* Set password callback function */
    PK11_SetPasswordFunc(vcard_emul_get_password);

    /* set up soft cards emulated by software certs rather than physical cards
     * */
    for (i = 0; i < options->vreader_count; i++) {
        int j;
        int cert_count;
        unsigned char **certs;
        int *cert_len;
        VCardKey **keys;
        PK11SlotInfo *slot;

        slot = PK11_FindSlotByName(options->vreader[i].name);
        if (slot == NULL) {
            continue;
        }
        vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type,
                                        options->vreader[i].type_params);
        vreader = vreader_new(options->vreader[i].vname, vreader_emul,
                              vreader_emul_delete);
        vreader_add_reader(vreader);
        cert_count = options->vreader[i].cert_count;

        ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                      options->vreader[i].cert_count);
        if (ret == PR_FALSE) {
            continue;
        }
        cert_count = 0;
        for (j = 0; j < options->vreader[i].cert_count; j++) {
            /* we should have a better way of identifying certs than by
             * nickname here */
            CERTCertificate *cert = PK11_FindCertFromNickname(
                                        options->vreader[i].cert_name[j],
                                        NULL);
            if (cert == NULL) {
                continue;
            }
            certs[cert_count] = cert->derCert.data;
            cert_len[cert_count] = cert->derCert.len;
            keys[cert_count] = vcard_emul_make_key(slot, cert);
            /* this is safe because the key is still holding a cert reference */
            CERT_DestroyCertificate(cert);
            cert_count++;
        }
        if (cert_count) {
            VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len,
                                                keys, cert_count);
            vreader_insert_card(vreader, vcard);
            vcard_emul_init_series(vreader, vcard);
            /* allow insertion and removal of soft cards */
            vreader_emul->saved_vcard = vcard_reference(vcard);
            vcard_free(vcard);
            vreader_free(vreader);
            has_readers = PR_TRUE;
        }
        g_free(certs);
        g_free(cert_len);
        g_free(keys);
    }

    /* if we aren't suppose to use hw, skip looking up hardware tokens */
    if (!options->use_hw) {
        nss_emul_init = has_readers;
        return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL;
    }

    /* make sure we have some PKCS #11 module loaded */
    module_lock = SECMOD_GetDefaultModuleListLock();
    module_list = SECMOD_GetDefaultModuleList();
    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        if (module_has_removable_hw_slots(module)) {
            break;
        }
    }
    SECMOD_ReleaseReadLock(module_lock);

    /* now examine all the slots, finding which should be readers */
    /* We should control this with options. For now we mirror out any
     * removable hardware slot */
    default_card_type = options->hw_card_type;
    default_type_params = g_strdup(options->hw_type_params);

    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;

        /* Ignore the internal module */
        if (module == NULL || module == SECMOD_GetInternalModule()) {
            continue;
        }

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

            /* only map removable HW slots */
            if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
                continue;
            }
            if (strcmp("E-Gate 0 0", PK11_GetSlotName(slot)) == 0) {
                /*
                 * coolkey <= 1.1.0-20 emulates this reader if it can't find
                 * any hardware readers. This causes problems, warn user of
                 * problems.
                 */
                fprintf(stderr, "known bad coolkey version - see "
                        "https://bugzilla.redhat.com/show_bug.cgi?id=802435\n");
                continue;
            }
            vreader_emul = vreader_emul_new(slot, options->hw_card_type,
                                            options->hw_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            vreader_add_reader(vreader);

            if (PK11_IsPresent(slot)) {
                VCard *vcard;
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_emul_init_series(vreader, vcard);
                vcard_free(vcard);
            }
        }
        vcard_emul_new_event_thread(module);
    }
    SECMOD_ReleaseReadLock(module_lock);
    nss_emul_init = PR_TRUE;

    return VCARD_EMUL_OK;
}
Beispiel #18
0
VCardEmulError
vcard_emul_init(const VCardEmulOptions *options)
{
    SECStatus rv;
    PRBool ret, has_readers = PR_FALSE, need_coolkey_module;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    SECMODListLock *module_lock;
    SECMODModuleList *module_list;
    SECMODModuleList *mlp;
    int i;

    if (vcard_emul_init_called) {
        return VCARD_EMUL_INIT_ALREADY_INITED;
    }
    vcard_emul_init_called = 1;
    vreader_init();
    vevent_queue_init();

    if (options == NULL) {
        options = &default_options;
    }

    /* first initialize NSS */
    if (options->nss_db) {
        rv = NSS_Init(options->nss_db);
    } else {
        rv = NSS_Init("sql:/etc/pki/nssdb");
    }
    if (rv != SECSuccess) {
        return VCARD_EMUL_FAIL;
    }
    /* Set password callback function */
    PK11_SetPasswordFunc(vcard_emul_get_password);

    /* set up soft cards emulated by software certs rather than physical cards
     * */
    for (i = 0; i < options->vreader_count; i++) {
        int j;
        int cert_count;
        unsigned char **certs;
        int *cert_len;
        VCardKey **keys;
        PK11SlotInfo *slot;

        slot = PK11_FindSlotByName(options->vreader[i].name);
        if (slot == NULL) {
            continue;
        }
        vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type,
                                        options->vreader[i].type_params);
        vreader = vreader_new(options->vreader[i].vname, vreader_emul,
                              vreader_emul_delete);
        vreader_add_reader(vreader);
        cert_count = options->vreader[i].cert_count;

        ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                      options->vreader[i].cert_count);
        if (ret == PR_FALSE) {
            continue;
        }
        cert_count = 0;
        for (j = 0; j < options->vreader[i].cert_count; j++) {
            /* we should have a better way of identifying certs than by
             * nickname here */
            CERTCertificate *cert = PK11_FindCertFromNickname(
                                        options->vreader[i].cert_name[j],
                                        NULL);
            if (cert == NULL) {
                continue;
            }
            certs[cert_count] = cert->derCert.data;
            cert_len[cert_count] = cert->derCert.len;
            keys[cert_count] = vcard_emul_make_key(slot, cert);
            /* this is safe because the key is still holding a cert reference */
            CERT_DestroyCertificate(cert);
            cert_count++;
        }
        if (cert_count) {
            VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len,
                                                keys, cert_count);
            vreader_insert_card(vreader, vcard);
            vcard_emul_init_series(vreader, vcard);
            /* allow insertion and removal of soft cards */
            vreader_emul->saved_vcard = vcard_reference(vcard);
            vcard_free(vcard);
            vreader_free(vreader);
            has_readers = PR_TRUE;
        }
        g_free(certs);
        g_free(cert_len);
        g_free(keys);
    }

    /* if we aren't suppose to use hw, skip looking up hardware tokens */
    if (!options->use_hw) {
        nss_emul_init = has_readers;
        return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL;
    }

    /* make sure we have some PKCS #11 module loaded */
    module_lock = SECMOD_GetDefaultModuleListLock();
    module_list = SECMOD_GetDefaultModuleList();
    need_coolkey_module = !has_readers;
    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        if (module_has_removable_hw_slots(module)) {
            need_coolkey_module = PR_FALSE;
            break;
        }
    }
    SECMOD_ReleaseReadLock(module_lock);

    if (need_coolkey_module) {
        SECMODModule *module;
        module = SECMOD_LoadUserModule(
                    (char *)"library=libcoolkeypk11.so name=Coolkey",
                    NULL, PR_FALSE);
        if (module == NULL) {
            return VCARD_EMUL_FAIL;
        }
        SECMOD_DestroyModule(module); /* free our reference, Module will still
                                       * be on the list.
                                       * until we destroy it */
    }

    /* now examine all the slots, finding which should be readers */
    /* We should control this with options. For now we mirror out any
     * removable hardware slot */
    default_card_type = options->hw_card_type;
    default_type_params = strdup(options->hw_type_params);

    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        PRBool has_emul_slots = PR_FALSE;

        if (module == NULL) {
                continue;
        }

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

            /* only map removable HW slots */
            if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
                continue;
            }
            vreader_emul = vreader_emul_new(slot, options->hw_card_type,
                                            options->hw_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            vreader_add_reader(vreader);

            has_readers = PR_TRUE;
            has_emul_slots = PR_TRUE;

            if (PK11_IsPresent(slot)) {
                VCard *vcard;
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_emul_init_series(vreader, vcard);
                vcard_free(vcard);
            }
        }
        if (has_emul_slots) {
            vcard_emul_new_event_thread(module);
        }
    }
    SECMOD_ReleaseReadLock(module_lock);
    nss_emul_init = has_readers;

    return VCARD_EMUL_OK;
}
Beispiel #19
0
/*
 * this handles modules that do not support C_WaitForSlotEvent().
 * The internal flags are stored. Note that C_WaitForSlotEvent() does not
 * have a timeout, so we don't have one for handleWaitForSlotEvent() either.
 */
PK11SlotInfo *
secmod_HandleWaitForSlotEvent(SECMODModule *mod,  unsigned long flags,
						PRIntervalTime latency)
{
    PRBool removableSlotsFound = PR_FALSE;
    int i;
    int error = SEC_ERROR_NO_EVENT;

    if (!moduleLock) {
    	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
	return NULL;
    }
    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];
	    PRUint16 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 ((mod->slotCount !=0) && !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;
}