Example #1
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;
}
Example #2
0
/*
 * return the certificate associated with a derCert 
 */
SECItem *
PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
				 SECItem *name, SECItem **profileTime)
{
    CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
    CK_ATTRIBUTE theTemplate[] = {
	{ CKA_SUBJECT, NULL, 0 },
	{ CKA_CLASS, NULL, 0 },
	{ CKA_NETSCAPE_EMAIL, NULL, 0 },
    };
    CK_ATTRIBUTE smimeData[] =  {
	{ CKA_SUBJECT, NULL, 0 },
	{ CKA_VALUE, NULL, 0 },
    };
    /* if you change the array, change the variable below as well */
    int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
    CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
    CK_ATTRIBUTE *attrs = theTemplate;
    CK_RV crv;
    SECItem *emailProfile = NULL;

    if (!emailAddr || !emailAddr[0]) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return NULL;
    }

    PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
    PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
    PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr)); 
								    attrs++;

    if (*slot) {
    	smimeh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
    } else {
	PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
							PR_FALSE,PR_TRUE,NULL);
	PK11SlotListElement *le;

	if (!list) {
	    return NULL;
	}
	/* loop through all the slots */
	for (le = list->head; le; le = le->next) {
	    smimeh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
	    if (smimeh != CK_INVALID_HANDLE) {
		*slot = PK11_ReferenceSlot(le->slot);
		break;
	    }
	}
	PK11_FreeSlotList(list);
    }
    
    if (smimeh == CK_INVALID_HANDLE) {
	PORT_SetError(SEC_ERROR_NO_KRL);
	return NULL;
    }

    if (profileTime) {
    	PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
    } 
    
    crv = PK11_GetAttributes(NULL,*slot,smimeh,smimeData,2);
    if (crv != CKR_OK) {
	PORT_SetError(PK11_MapError (crv));
	goto loser;
    }

    if (!profileTime) {
	SECItem profileSubject;

	profileSubject.data = (unsigned char*) smimeData[0].pValue;
	profileSubject.len = smimeData[0].ulValueLen;
	if (!SECITEM_ItemsAreEqual(&profileSubject,name)) {
	    goto loser;
	}
    }

    emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));    
    if (emailProfile == NULL) {
	goto loser;
    }

    emailProfile->data = (unsigned char*) smimeData[1].pValue;
    emailProfile->len = smimeData[1].ulValueLen;

    if (profileTime) {
	*profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));    
	if (*profileTime) {
	    (*profileTime)->data = (unsigned char*) smimeData[0].pValue;
	    (*profileTime)->len = smimeData[0].ulValueLen;
	}
    }

loser:
    if (emailProfile == NULL) {
	if (smimeData[1].pValue) {
	    PORT_Free(smimeData[1].pValue);
	}
    }
    if (profileTime == NULL || *profileTime == NULL) {
	if (smimeData[0].pValue) {
	    PORT_Free(smimeData[0].pValue);
	}
    }
    return emailProfile;
}
Example #3
0
nsresult
GetSlotWithMechanism(uint32_t aMechanism,
                     nsIInterfaceRequestor *m_ctx,
                     PK11SlotInfo** aSlot)
{
    nsNSSShutDownPreventionLock locker;
    PK11SlotList * slotList = nullptr;
    PRUnichar** tokenNameList = nullptr;
    nsITokenDialogs * dialogs;
    PRUnichar *unicodeTokenChosen;
    PK11SlotListElement *slotElement, *tmpSlot;
    uint32_t numSlots = 0, i = 0;
    bool canceled;
    nsresult rv = NS_OK;

    *aSlot = nullptr;

    // Get the slot
    slotList = PK11_GetAllTokens(MapGenMechToAlgoMech(aMechanism),
                                 true, true, m_ctx);
    if (!slotList || !slotList->head) {
        rv = NS_ERROR_FAILURE;
        goto loser;
    }

    if (!slotList->head->next) {
        /* only one slot available, just return it */
        *aSlot = slotList->head->slot;
    } else {
        // Gerenate a list of slots and ask the user to choose //
        tmpSlot = slotList->head;
        while (tmpSlot) {
            numSlots++;
            tmpSlot = tmpSlot->next;
        }

        // Allocate the slot name buffer //
        tokenNameList = static_cast<PRUnichar**>(nsMemory::Alloc(sizeof(PRUnichar *) * numSlots));
        if (!tokenNameList) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        i = 0;
        slotElement = PK11_GetFirstSafe(slotList);
        while (slotElement) {
            tokenNameList[i] = UTF8ToNewUnicode(nsDependentCString(PK11_GetTokenName(slotElement->slot)));
            slotElement = PK11_GetNextSafe(slotList, slotElement, false);
            if (tokenNameList[i])
                i++;
            else {
                // OOM. adjust numSlots so we don't free unallocated memory.
                numSlots = i;
                PK11_FreeSlotListElement(slotList, slotElement);
                rv = NS_ERROR_OUT_OF_MEMORY;
                goto loser;
            }
        }

        /* Throw up the token list dialog and get back the token */
        rv = getNSSDialogs((void**)&dialogs,
                           NS_GET_IID(nsITokenDialogs),
                           NS_TOKENDIALOGS_CONTRACTID);

        if (NS_FAILED(rv)) goto loser;

        {
            nsPSMUITracker tracker;
            if (!tokenNameList || !*tokenNameList) {
                rv = NS_ERROR_OUT_OF_MEMORY;
            }
            else if (tracker.isUIForbidden()) {
                rv = NS_ERROR_NOT_AVAILABLE;
            }
            else {
                rv = dialogs->ChooseToken(m_ctx, (const PRUnichar**)tokenNameList, numSlots, &unicodeTokenChosen, &canceled);
            }
        }
        NS_RELEASE(dialogs);
        if (NS_FAILED(rv)) goto loser;

        if (canceled) {
            rv = NS_ERROR_NOT_AVAILABLE;
            goto loser;
        }

        // Get the slot //
        slotElement = PK11_GetFirstSafe(slotList);
        nsAutoString tokenStr(unicodeTokenChosen);
        while (slotElement) {
            if (tokenStr.Equals(NS_ConvertUTF8toUTF16(PK11_GetTokenName(slotElement->slot)))) {
                *aSlot = slotElement->slot;
                PK11_FreeSlotListElement(slotList, slotElement);
                break;
            }
            slotElement = PK11_GetNextSafe(slotList, slotElement, false);
        }
        if(!(*aSlot)) {
            rv = NS_ERROR_FAILURE;
            goto loser;
        }
    }

    // Get a reference to the slot //
    PK11_ReferenceSlot(*aSlot);
loser:
    if (slotList) {
        PK11_FreeSlotList(slotList);
    }
    if (tokenNameList) {
        NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(numSlots, tokenNameList);
    }
    return rv;
}
Example #4
0
//
// 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);
}