Beispiel #1
0
int
find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h,
    const char *wanted_slot_label, const char *wanted_token_label,
    unsigned int *slot_num)
{
  SECMODModule *module = h->module;
  PK11SlotInfo *slot;
  unsigned long i;
  int rv;

  if (slot_num == NULL || module == NULL)
    return (-1);

  if (wanted_token_label == NULL){
    rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num);
    return (rv);
  }

  /* wanted_token_label != NULL */
  if (strcmp(wanted_slot_label, "none") == 0) {
    for (i = 0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
	const char *token_label;
	slot = PK11_ReferenceSlot(module->slots[i]);
	token_label = PK11_GetTokenName(slot);
	if (memcmp_pad_max((void *) token_label, strlen(token_label),
	    (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0) {
          h->slot =  slot;
          *slot_num =  PK11_GetSlotID(slot);
	  return (0);
        }
      }
    }
    return (-1);
  } else {
    for (i = 0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
	const char *slot_label;
	const char *token_label;

	slot = PK11_ReferenceSlot(module->slots[i]);
	slot_label = PK11_GetSlotName(slot);
	token_label = PK11_GetTokenName(slot);
	if ((memcmp_pad_max((void *)slot_label, strlen(slot_label),
	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) &&
            (memcmp_pad_max((void *)token_label, strlen(token_label),
	    (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0))
	{
          h->slot =  slot;
          *slot_num =  PK11_GetSlotID(slot);
	  return (0);
        }
      }
    }
    return (-1);
  }
}
static void
sync_initial_tokens_from_driver (GsdSmartcardManager *self,
                                 SECMODModule        *driver,
                                 GHashTable          *smartcards,
                                 GCancellable        *cancellable)
{
        GsdSmartcardManagerPrivate *priv = self->priv;
        int i;

        for (i = 0; i < driver->slotCount; i++) {
                PK11SlotInfo *card;

                card = driver->slots[i];

                if (PK11_IsPresent (card)) {
                        CK_SLOT_ID slot_id;
                        slot_id = PK11_GetSlotID (card);

                        g_debug ("Detected smartcard in slot %d at start up", (int) slot_id);

                        g_hash_table_replace (smartcards,
                                              GINT_TO_POINTER ((int) slot_id),
                                              PK11_ReferenceSlot (card));
                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
                }
        }
}
Beispiel #3
0
static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
                             char *key_file)
{
  PK11SlotInfo *slot;
  SECStatus status;
  CURLcode rv;
  struct ssl_connect_data *ssl = conn->ssl;
  (void)sockindex; /* unused */

  rv = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
  if(CURLE_OK != rv) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return rv;
  }

  slot = PK11_FindSlotByName("PEM Token #1");
  if(!slot)
    return CURLE_SSL_CERTPROBLEM;

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  status = PK11_Authenticate(slot, PR_TRUE,
                             conn->data->set.str[STRING_KEY_PASSWD]);
  PK11_FreeSlot(slot);
  return (SECSuccess == status)
    ? CURLE_OK
    : CURLE_SSL_CERTPROBLEM;
}
Beispiel #4
0
Datei: nss.c Projekt: 0w/moai-dev
static int nss_load_key(struct connectdata *conn, int sockindex, char *key_file)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  PK11SlotInfo * slot = NULL;
  CK_ATTRIBUTE *attrs;
  CK_ATTRIBUTE theTemplate[20];
  CK_BBOOL cktrue = CK_TRUE;
  CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
  CK_SLOT_ID slotID;
  char slotname[SLOTSIZE];
  struct ssl_connect_data *sslconn = &conn->ssl[sockindex];

  attrs = theTemplate;

  /* FIXME: grok the various file types */

  slotID = 1; /* hardcoded for now */

  snprintf(slotname, sizeof(slotname), "PEM Token #%ld", slotID);
  slot = PK11_FindSlotByName(slotname);

  if(!slot)
    return 0;

  PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
  PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
  PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)key_file,
                strlen(key_file)+1); attrs++;

  /* When adding an encrypted key the PKCS#11 will be set as removed */
  sslconn->key = PK11_CreateGenericObject(slot, theTemplate, 3,
                                          PR_FALSE /* isPerm */);
  if(sslconn->key == NULL) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return 0;
  }

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  /* parg is initialized in nss_Init_Tokens() */
  if(PK11_Authenticate(slot, PR_TRUE,
                       conn->data->set.str[STRING_KEY_PASSWD]) != SECSuccess) {

    PK11_FreeSlot(slot);
    return 0;
  }
  PK11_FreeSlot(slot);

  return 1;
#else
  /* If we don't have PK11_CreateGenericObject then we can't load a file-based
   * key.
   */
  (void)conn; /* unused */
  (void)key_file; /* unused */
  return 0;
#endif
}
Beispiel #5
0
static int nss_load_key(struct connectdata *conn, int sockindex,
                        char *key_file)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  PK11SlotInfo *slot;
  SECStatus status;
  struct ssl_connect_data *ssl = conn->ssl;

  if(CURLE_OK != nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE)) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return 0;
  }

  slot = PK11_FindSlotByName("PEM Token #1");
  if(!slot)
    return 0;

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  status = PK11_Authenticate(slot, PR_TRUE,
                             conn->data->set.str[STRING_KEY_PASSWD]);
  PK11_FreeSlot(slot);
  return (SECSuccess == status) ? 1 : 0;
#else
  /* If we don't have PK11_CreateGenericObject then we can't load a file-based
   * key.
   */
  (void)conn; /* unused */
  (void)key_file; /* unused */
  return 0;
#endif
}
Beispiel #6
0
/* Re-insert of a card that has been removed by force removal */
VCardEmulError
vcard_emul_force_card_insert(VReader *vreader)
{
    VReaderEmul *vreader_emul;
    VCard *vcard;

    if (!nss_emul_init || (vreader_card_is_present(vreader) == VREADER_OK)) {
        return VCARD_EMUL_FAIL; /* card is already removed */
    }
    vreader_emul = vreader_get_private(vreader);

    /* if it's a softcard, get the saved vcard from the reader emul structure */
    if (vreader_emul->saved_vcard) {
        vcard = vcard_reference(vreader_emul->saved_vcard);
    } else {
        /* it must be a physical card, rebuild it */
        if (!PK11_IsPresent(vreader_emul->slot)) {
            /* physical card has been removed, not way to reinsert it */
            return VCARD_EMUL_FAIL;
        }
        vcard = vcard_emul_mirror_card(vreader);
    }
    vreader_insert_card(vreader, vcard);
    vcard_free(vcard);

    return VCARD_EMUL_OK;
}
Beispiel #7
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 #8
0
int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot_num)
{
  /* NSS manages the sessions under the covers, use this function to
   * select a slot */
  if (h->slot != NULL) {
    /* we've already selected the slot */
    if (PK11_GetSlotID(h->slot) == slot_num) {
	return 0;
    }
    /* the slot we've selected isn't the one we want to open */
    PK11_FreeSlot(h->slot);
    h->slot = NULL;
  }

  /* look the slot up */
  h->slot = SECMOD_LookupSlot(h->module->moduleID, slot_num);
  if (h->slot == NULL) {
    return -1;
  }

  /* make sure it is present */
  if (!PK11_IsPresent(h->slot)) {
    PK11_FreeSlot(h->slot);
    h->slot = NULL;
    return -1;
  }
  return 0;
}
static void
on_all_drivers_activated (GsdSmartcardManager *self,
                          GAsyncResult        *result,
                          GTask               *task)
{
        GError *error = NULL;
        gboolean driver_activated;
        PK11SlotInfo *login_token;

        driver_activated = activate_all_drivers_async_finish (self, result, &error);

        if (!driver_activated) {
                g_task_return_error (task, error);
                return;
        }

        login_token = gsd_smartcard_manager_get_login_token (self);

        if (login_token || g_getenv ("PKCS11_LOGIN_TOKEN_NAME") != NULL) {
                /* The card used to log in was removed before login completed.
                 * Do removal action immediately
                 */
                if (!login_token || !PK11_IsPresent (login_token))
                        gsd_smartcard_manager_do_remove_action (self);
        }

        g_task_return_boolean (task, TRUE);
        g_object_unref (task);
}
Beispiel #10
0
/*
 * This thread looks for card and reader insertions and puts events on the
 * event queue
 */
static void
vcard_emul_event_thread(void *arg)
{
    PK11SlotInfo *slot;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    VCard *vcard;
    SECMODModule *module = (SECMODModule *)arg;

    do {
        slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500);
        if (slot == NULL) {
            break;
        }
        vreader = vcard_emul_find_vreader_from_slot(slot);
        if (vreader == NULL) {
            /* new vreader */
            vreader_emul = vreader_emul_new(slot, default_card_type,
                                            default_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            PK11_FreeSlot(slot);
            slot = NULL;
            vreader_add_reader(vreader);
            vreader_free(vreader);
            continue;
        }
        /* card remove/insert */
        vreader_emul = vreader_get_private(vreader);
        if (PK11_IsPresent(slot)) {
            int series = PK11_GetSlotSeries(slot);
            if (series != vreader_emul->series) {
                if (vreader_emul->present) {
                    vreader_insert_card(vreader, NULL);
                }
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_free(vcard);
            }
            vreader_emul->series = series;
            vreader_emul->present = 1;
            vreader_free(vreader);
            PK11_FreeSlot(slot);
            continue;
        }
        if (vreader_emul->present) {
            vreader_insert_card(vreader, NULL);
        }
        vreader_emul->series = 0;
        vreader_emul->present = 0;
        PK11_FreeSlot(slot);
        vreader_free(vreader);
    } while (1);
}
Beispiel #11
0
/* if the card is inserted when we start up, make sure our state is correct */
static void
vcard_emul_init_series(VReader *vreader, VCard *vcard)
{
    VReaderEmul *vreader_emul = vreader_get_private(vreader);
    PK11SlotInfo *slot = vreader_emul->slot;

    vreader_emul->present = PK11_IsPresent(slot);
    vreader_emul->series = PK11_GetSlotSeries(slot);
    if (vreader_emul->present == 0) {
        vreader_insert_card(vreader, NULL);
    }
}
static GList *
get_inserted_tokens_for_operation (GsdSmartcardManager      *self,
                                   WatchSmartcardsOperation *operation)
{
        GList *inserted_tokens = NULL;
        GHashTableIter iter;
        gpointer key, value;

        g_hash_table_iter_init (&iter, operation->smartcards);
        while (g_hash_table_iter_next (&iter, &key, &value)) {
                PK11SlotInfo *card_slot;

                card_slot = (PK11SlotInfo *) value;

                if (PK11_IsPresent (card_slot))
                        inserted_tokens = g_list_prepend (inserted_tokens, card_slot);
        }

        return inserted_tokens;
}
Beispiel #13
0
NS_IMETHODIMP
nsPKCS11Slot::GetStatus(uint32_t *_retval)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  if (PK11_IsDisabled(mSlot))
    *_retval = SLOT_DISABLED;
  else if (!PK11_IsPresent(mSlot))
    *_retval = SLOT_NOT_PRESENT;
  else if (PK11_NeedLogin(mSlot) && PK11_NeedUserInit(mSlot))
    *_retval = SLOT_UNINITIALIZED;
  else if (PK11_NeedLogin(mSlot) && !PK11_IsLoggedIn(mSlot, nullptr))
    *_retval = SLOT_NOT_LOGGED_IN;
  else if (PK11_NeedLogin(mSlot))
    *_retval = SLOT_LOGGED_IN;
  else
    *_retval = SLOT_READY;
  return NS_OK;
}
Beispiel #14
0
/* readonly attribute wstring tokenName; */
NS_IMETHODIMP 
nsPKCS11Slot::GetTokenName(char16_t **aName)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  if (!PK11_IsPresent(mSlot)) {
    *aName = nullptr;
    return NS_OK;
  }

  if (mSeries != PK11_GetSlotSeries(mSlot)) {
    refreshSlotInfo();
  }


  *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot)));
  if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
  return NS_OK;
}
Beispiel #15
0
/*
 * This function will search the slot list to find a slot based on the slot
 * label.  If the wanted_slot_label is "none", then we will return the first
 * slot with the token presented.
 *
 * This function return 0 if it found a matching slot; otherwise, it returns
 * -1.
 */
int
find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label,
    unsigned int *slotID)
{
  SECMODModule *module = h->module;
  PK11SlotInfo *slot;
  int rv;
  int i;

  if (slotID == NULL || wanted_slot_label == NULL ||
      strlen(wanted_slot_label) == 0 || module == NULL)
    return (-1);

  if (strcmp(wanted_slot_label, "none") == 0) {
    rv = find_slot_by_number(h, 0, slotID);
    return (rv);
  } else {
    /* wanted_slot_label is not "none"  */
    for (i = 0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
        const char *slot_label;

	slot = PK11_ReferenceSlot(module->slots[i]);
	slot_label = PK11_GetSlotName(slot);
	if (memcmp_pad_max((void *)slot_label, strlen(slot_label),
	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) {
	  h->slot = slot;
	  *slotID = PK11_GetSlotID(slot);
	  return 0;
        }
      }
    }
  }

  return (-1);
}
Beispiel #16
0
static int nss_load_key(struct connectdata *conn, char *key_file)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  PK11SlotInfo * slot = NULL;
  PK11GenericObject *rv;
  CK_ATTRIBUTE *attrs;
  CK_ATTRIBUTE theTemplate[20];
  CK_BBOOL cktrue = CK_TRUE;
  CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
  CK_SLOT_ID slotID;
  char *slotname = NULL;
  pphrase_arg_t *parg = NULL;

  attrs = theTemplate;

  /* FIXME: grok the various file types */

  slotID = 1; /* hardcoded for now */

  slotname = (char *)malloc(SLOTSIZE);
  snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);

  slot = PK11_FindSlotByName(slotname);
  free(slotname);

  if(!slot)
    return 0;

  PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
  PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
  PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)key_file,
                strlen(key_file)+1); attrs++;

  /* When adding an encrypted key the PKCS#11 will be set as removed */
  rv = PK11_CreateGenericObject(slot, theTemplate, 3, PR_FALSE /* isPerm */);
  if(rv == NULL) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return 0;
  }

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  parg = (pphrase_arg_t *) malloc(sizeof(*parg));
  parg->retryCount = 0;
  parg->data = conn->data;
  /* parg is initialized in nss_Init_Tokens() */
  if(PK11_Authenticate(slot, PR_TRUE, parg) != SECSuccess) {
    free(parg);
    return 0;
  }
  free(parg);

  return 1;
#else
  /* If we don't have PK11_CreateGenericObject then we can't load a file-based
   * key.
   */
  (void)conn; /* unused */
  (void)key_file; /* unused */
  return 0;
#endif
}
//
// This is the main loop.
//
void SmartCardMonitoringThread::Execute()
{
  PK11SlotInfo *slot;
  const char *tokenName = nsnull;

  //
  // populate token names for already inserted tokens.
  //
  PK11SlotList *sl =
            PK11_FindSlotsByNames(mModule->dllName, nsnull, nsnull, true);
  PK11SlotListElement *sle;
 
  if (sl) {
    for (sle=PK11_GetFirstSafe(sl); sle; 
                                      sle=PK11_GetNextSafe(sl,sle,false)) {
      SetTokenName(PK11_GetSlotID(sle->slot), 
                  PK11_GetTokenName(sle->slot), PK11_GetSlotSeries(sle->slot));
    }
    PK11_FreeSlotList(sl);
  }

  // loop starts..
  do {
    slot = SECMOD_WaitForAnyTokenEvent(mModule, 0, PR_SecondsToInterval(1)  );
    if (slot == nsnull) {
      break;
    }

    // now we have a potential insertion or removal event, see if the slot
    // is present to determine which it is...
    if (PK11_IsPresent(slot)) {
      // insertion
      CK_SLOT_ID slotID = PK11_GetSlotID(slot);
      PRUint32 series = PK11_GetSlotSeries(slot);

      // skip spurious insertion events...
      if (series != GetTokenSeries(slotID)) {
        // if there's a token name, then we have not yet issued a remove
        // event for the previous token, do so now...
        tokenName = GetTokenName(slotID);
        if (tokenName) {
          SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName);
        }
        tokenName = PK11_GetTokenName(slot);
        // save the token name and series
        SetTokenName(slotID, tokenName, series);
        SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_INSERT), tokenName);
      }
    } else {
      // retrieve token name 
      CK_SLOT_ID slotID = PK11_GetSlotID(slot);
      tokenName = GetTokenName(slotID);
      // if there's not a token name, then the software isn't expecting
      // a (or another) remove event.
      if (tokenName) {
        SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName);
        // clear the token name (after we send it)
        SetTokenName(slotID, nsnull, 0);
      }
    }
    PK11_FreeSlot(slot);

  } while (1);
}
Beispiel #18
0
int find_slot_by_number(pkcs11_handle_t *h, unsigned int slot_num, unsigned int *slotID)
{
  SECMODModule *module = h->module;
  int i;

  /* if module is null,
   * any of the PKCS #11 modules specified in the system config
   * is available, find one */
  if (module == NULL) {
    PK11SlotList *list;
    PK11SlotListElement *le;
    PK11SlotInfo *slot = NULL;

    /* find a slot, we haven't specifically selected a module,
     * so find an appropriate one. */
    /* get them all */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL);
    if (list == NULL) {
	return -1;
    }
    for (le = list->head; le; le = le->next) {
      CK_SLOT_INFO slInfo;
      SECStatus rv;

      slInfo.flags = 0;
      rv = PK11_GetSlotInfo(le->slot, &slInfo);
      if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
	slot = PK11_ReferenceSlot(le->slot);
	module = SECMOD_ReferenceModule(PK11_GetModule(le->slot));
	break;
      }
    }
    PK11_FreeSlotList(list);
    if (slot == NULL) {
	return -1;
    }
    h->slot = slot;
    h->module = module;
    *slotID = PK11_GetSlotID(slot);
    return 0;
  }

  /*
   * we're configured with a specific module, look for a present slot
   * on that module. */
  if (slot_num == 0) {
    /* threaded applications should also acquire the
     * DefaultModuleListLock */
    for (i=0; i < module->slotCount; i++) {
      if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
        h->slot = PK11_ReferenceSlot(module->slots[i]);
        *slotID = PK11_GetSlotID(h->slot);
        return 0;
      }
    }
  }
  /* we're configured for a specific module and token, see if it's present */
  slot_num--;
  if (slot_num < module->slotCount && module->slots &&
      module->slots[slot_num] && PK11_IsPresent(module->slots[slot_num])) {
    h->slot = PK11_ReferenceSlot(module->slots[slot_num]);
    *slotID = PK11_GetSlotID(h->slot);
    return 0;
  }
  return -1;
}
Beispiel #19
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 #20
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 #21
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;
}
Beispiel #22
0
/*
 * This thread looks for card and reader insertions and puts events on the
 * event queue
 */
static void
vcard_emul_event_thread(void *arg)
{
    PK11SlotInfo *slot;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    VCard *vcard;
    SECMODModule *module = (SECMODModule *)arg;

    do {
        /*
         * XXX - the latency value doesn't matter one bit. you only get no
         * blocking (flags |= CKF_DONT_BLOCK) or PKCS11_WAIT_LATENCY (==500),
         * hard coded in coolkey.  And it isn't coolkey's fault - the timeout
         * value we pass get's dropped on the floor before C_WaitForSlotEvent
         * is called.
         */
        slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500);
        if (slot == NULL) {
            /* this could be just a no event indication */
            if (PORT_GetError() == SEC_ERROR_NO_EVENT) {
                continue;
            }
            break;
        }
        vreader = vcard_emul_find_vreader_from_slot(slot);
        if (vreader == NULL) {
            /* new vreader */
            vreader_emul = vreader_emul_new(slot, default_card_type,
                                            default_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            PK11_FreeSlot(slot);
            slot = NULL;
            vreader_add_reader(vreader);
            vreader_free(vreader);
            continue;
        }
        /* card remove/insert */
        vreader_emul = vreader_get_private(vreader);
        if (PK11_IsPresent(slot)) {
            int series = PK11_GetSlotSeries(slot);
            if (series != vreader_emul->series) {
                if (vreader_emul->present) {
                    vreader_insert_card(vreader, NULL);
                }
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_free(vcard);
            }
            vreader_emul->series = series;
            vreader_emul->present = 1;
            vreader_free(vreader);
            PK11_FreeSlot(slot);
            continue;
        }
        if (vreader_emul->present) {
            vreader_insert_card(vreader, NULL);
        }
        vreader_emul->series = 0;
        vreader_emul->present = 0;
        PK11_FreeSlot(slot);
        vreader_free(vreader);
    } while (1);
}
static gboolean
watch_one_event_from_driver (GsdSmartcardManager       *self,
                             WatchSmartcardsOperation  *operation,
                             GCancellable              *cancellable,
                             GError                   **error)
{
        GsdSmartcardManagerPrivate *priv = self->priv;
        PK11SlotInfo *card, *old_card;
        CK_SLOT_ID slot_id;
        gulong handler_id;
        int old_slot_series = -1, slot_series;

        handler_id = g_cancellable_connect (cancellable,
                                            G_CALLBACK (on_watch_cancelled),
                                            operation,
                                            NULL);

        card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1));

        g_cancellable_disconnect (cancellable, handler_id);

        if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                g_warning ("smartcard event function cancelled");
                return FALSE;
        }

        if (card == NULL) {
                int error_code;

                error_code = PORT_GetError ();

                operation->number_of_consecutive_errors++;
                if (operation->number_of_consecutive_errors > 10) {
                     g_warning ("Got %d consecutive smartcard errors, so giving up.",
                                operation->number_of_consecutive_errors);

                     g_set_error (error,
                                  GSD_SMARTCARD_MANAGER_ERROR,
                                  GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
                                  "encountered unexpected error while "
                                  "waiting for smartcard events (error %x)",
                                  error_code);
                     return FALSE;
                }

                g_warning ("Got potentially spurious smartcard event error: %x.", error_code);

                g_usleep (0.5 * G_USEC_PER_SEC);
                return TRUE;
        }
        operation->number_of_consecutive_errors = 0;

        slot_id = PK11_GetSlotID (card);
        slot_series = PK11_GetSlotSeries (card);

        old_card = g_hash_table_lookup (operation->smartcards, GINT_TO_POINTER ((int) slot_id));

        /* If there is a different card in the slot now than
         * there was before, then we need to emit a removed signal
         * for the old card
         */
        if (old_card != NULL) {
                old_slot_series = PK11_GetSlotSeries (old_card);

                if (old_slot_series != slot_series) {
                        /* Card registered with slot previously is
                         * different than this card, so update its
                         * exported state to track the implicit missed
                         * removal
                         */
                        gsd_smartcard_service_sync_token (priv->service, old_card, cancellable);
                }

                g_hash_table_remove (operation->smartcards, GINT_TO_POINTER ((int) slot_id));
        }

        if (PK11_IsPresent (card)) {
                g_debug ("Detected smartcard insertion event in slot %d", (int) slot_id);

                g_hash_table_replace (operation->smartcards,
                                      GINT_TO_POINTER ((int) slot_id),
                                      PK11_ReferenceSlot (card));

                gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        } else if (old_card == NULL) {
                /* If the just removed smartcard is not known to us then
                 * ignore the removal event. NSS sends a synthentic removal
                 * event for slots that are empty at startup
                 */
                g_debug ("Detected slot %d is empty in reader", (int) slot_id);
        } else {
                g_debug ("Detected smartcard removal event in slot %d", (int) slot_id);

                /* If the just removed smartcard is known to us then
                 * we need to update its exported state to reflect the
                 * removal
                 */
                if (old_slot_series == slot_series)
                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        }

        PK11_FreeSlot (card);

        return TRUE;
}