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 }
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; }
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 }
/* * 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); }
int wait_for_token_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label, const char *wanted_token_label, unsigned int *slot_num) { int rv; rv = -1; do { /* see if the card we're looking for is inserted */ rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label, wanted_token_label, slot_num); if (rv != 0) { PK11SlotInfo *slot; PRIntervalTime slot_poll_interval; /* only for legacy hardware */ /* if the card is not inserted, then block until something happens */ slot_poll_interval = PR_MillisecondsToInterval(PAM_PKCS11_POLL_TIME); slot = SECMOD_WaitForAnyTokenEvent(h->module, 0 /* flags */, slot_poll_interval); /* unexpected error */ if (slot == NULL) { break; } /* something happened, continue loop and check if the card * we're looking for is inserted */ PK11_FreeSlot(slot); continue; } } while (rv != 0); return rv; }
/* * 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; }
// // 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); }
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 }