/** * Create a new DGN token if token detection and initialization is successful * * @param slot The slot in which a token was detected * @param token Pointer to pointer updated with newly created token structure * @return CKR_OK or any other Cryptoki error code */ static int newDGNToken(struct p11Slot_t *slot, struct p11Token_t **token) { static struct p11TokenDriver esign_token; struct p11Token_t *ptoken; struct p11TokenDriver *drv; struct p11Slot_t *vslot; int rc; FUNC_CALLED(); esign_token = *getStarcosTokenDriver(); esign_token.name = "3.5ID ECC C1 DGN"; esign_token.isCandidate = isCandidate; esign_token.newToken = newDGNToken; esign_token.C_Sign = esign_C_Sign; rc = createStarcosToken(slot, &ptoken, &esign_token, &starcosApplications[1]); if (rc != CKR_OK) FUNC_FAILS(rc, "Base token creation failed"); rc = addToken(slot, ptoken); if (rc != CKR_OK) { FUNC_FAILS(rc, "addToken() failed"); } *token = ptoken; if (context->caller == CALLER_FIREFOX) { FUNC_RETURNS(CKR_OK); } rc = getVirtualSlot(slot, 0, &vslot); if (rc != CKR_OK) FUNC_FAILS(rc, "Virtual slot creation failed"); drv = getDGNTokenDriver(); rc = createStarcosToken(vslot, &ptoken, drv, &starcosApplications[0]); if (rc != CKR_OK) FUNC_FAILS(rc, "Token creation failed"); rc = addToken(vslot, ptoken); if (rc != CKR_OK) FUNC_FAILS(rc, "addToken() failed"); FUNC_RETURNS(CKR_OK); }
int updatePCSCSlots(struct p11SlotPool_t *pool) { struct p11Slot_t *slot,*vslot; LPTSTR readers = NULL; char *filter, *prealloc; DWORD cch = 0; // DWORD cch = SCARD_AUTOALLOCATE; LPTSTR p; LONG rc; int match,vslotcnt,i; FUNC_CALLED(); /* * Create a context if not already done */ if (!globalContext) { rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &globalContext); #ifdef DEBUG debug("SCardEstablishContext: %s\n", pcsc_error_to_string(rc)); #endif if (rc != SCARD_S_SUCCESS) { FUNC_FAILS(CKR_DEVICE_ERROR, "Could not establish context to PC/SC manager"); } } rc = SCardListReaders(globalContext, NULL, NULL, &cch); #ifdef DEBUG debug("SCardListReaders: %s\n", pcsc_error_to_string(rc)); #endif if (rc == SCARD_E_NO_READERS_AVAILABLE) { FUNC_RETURNS(CKR_OK); } if (rc != SCARD_S_SUCCESS) { FUNC_FAILS(CKR_DEVICE_ERROR, "Error listing PC/SC card terminals"); } readers = calloc(cch, 1); rc = SCardListReaders(globalContext, NULL, readers, &cch); #ifdef DEBUG debug("SCardListReaders: %s\n", pcsc_error_to_string(rc)); #endif if (rc == SCARD_E_NO_READERS_AVAILABLE) { FUNC_RETURNS(CKR_OK); } if (rc != SCARD_S_SUCCESS) { FUNC_FAILS(CKR_DEVICE_ERROR, "Error listing PC/SC card terminals"); } filter = getenv("PKCS11_READER_FILTER"); #ifdef DEBUG if (filter) { debug("Reader filter '%s'\n", filter); } #endif /* Determine the total number of readers */ p = readers; while (*p != '\0') { #ifdef DEBUG debug("Found reader '%s'\n", p); #endif /* Check if we already have a slot for the reader */ slot = pool->list; match = FALSE; while (slot) { if (strncmp(slot->readername, p, strlen(p)) == 0) { match = TRUE; break; } slot = slot->next; } /* Skip the reader as we already have a slot for it */ if (match) { p += strlen(p) + 1; slot->closed = FALSE; continue; } if (!matchFilter(p, filter)) { p += strlen(p) + 1; continue; } slot = (struct p11Slot_t *) calloc(1, sizeof(struct p11Slot_t)); if (slot == NULL) { free(readers); FUNC_FAILS(CKR_HOST_MEMORY, "Out of memory"); } /* If a reader filter is defined, then slot ids for that reader are * derived from the reader name using a CRC32 value. If the token * in the reader allocated virtual slots, then these have incremented * slot ids. * * This is not enabled by default to prevent slot id collisions */ if (filter) slot->id = crc32(0, p, strlen(p)); rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &(slot->context)); #ifdef DEBUG debug("SCardEstablishContext: %s\n", pcsc_error_to_string(rc)); #endif if (rc != SCARD_S_SUCCESS) { free(slot); free(readers); FUNC_FAILS(CKR_DEVICE_ERROR, "Could not establish context to PC/SC manager"); } slotCounter++; strbpcpy(slot->info.slotDescription, (char *)p, sizeof(slot->info.slotDescription)); strcpy(slot->readername, (char *)p); strbpcpy(slot->info.manufacturerID, "CardContact", sizeof(slot->info.manufacturerID)); slot->info.hardwareVersion.minor = 0; slot->info.hardwareVersion.major = 0; slot->info.firmwareVersion.major = VERSION_MAJOR; slot->info.firmwareVersion.minor = VERSION_MINOR; slot->info.flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT; // The REINER SCT readers have an APDU buffer limitation of 1014 bytes if (!strncmp((char *)p, "REINER SCT", 10)) { #ifdef DEBUG debug("Detected a REINER SCT reader\n"); #endif if (!strncmp((char *)p, "REINER SCT cyberJack ecom_a", 27)) { #ifdef DEBUG debug("Detected a 'REINER SCT cyberJack ecom_a' reader. Limiting use of Le='000000'\n"); #endif // Some REINER SCT readers fail if Le='000000' returns more than // 1014 bytes. slot->noExtLengthReadAll = 1; } slot->maxRAPDU = 1000; slot->maxCAPDU = 1000; } addSlot(&context->slotPool, slot); #ifdef DEBUG debug("Added slot (%lu, %s) - slot counter is %i\n", slot->id, slot->readername, slotCounter); #endif // The PREALLOCATE option creates two additional virtual slots per card reader. // This is required for Firefox/NSS which sets the friendly flag only for slots that are // already present during the first C_GetSlotList prealloc = getenv("PKCS11_PREALLOCATE_VIRTUAL_SLOTS"); if (prealloc) { vslotcnt = *prealloc; if ((vslotcnt == '1') || (vslotcnt == '2')) { vslotcnt -= '0'; } else { vslotcnt = 2; } #ifdef DEBUG debug("Pre-allocate virtual slots '' %d\n", prealloc, vslotcnt); #endif for (i = 0; i < vslotcnt; i++) { getVirtualSlot(slot, i, &vslot); } } checkForNewPCSCToken(slot); p += strlen(p) + 1; } free(readers); FUNC_RETURNS(CKR_OK); }