Example #1
0
/**
 * Transmit APDU using PC/SC
 *
 * @param slot the slot to use for communication
 * @param capdu the command APDU
 * @param capdu_len the length of the command APDU
 * @param rapdu the response APDU
 * @param rapdu_len the length of the response APDU
 * @return -1 for error or length of received response APDU
 */
int transmitAPDUviaPCSC(struct p11Slot_t *slot,
	unsigned char *capdu, size_t capdu_len,
	unsigned char *rapdu, size_t rapdu_len)
{
	LONG rc;
	DWORD lenr;

	FUNC_CALLED();

	if (!slot->card) {
		FUNC_FAILS(-1, "No card handle");
	}

	lenr = rapdu_len;

	rc = SCardTransmit(slot->card, SCARD_PCI_T1, capdu, capdu_len, NULL, rapdu, &lenr);

#ifdef DEBUG
	debug("SCardTransmit: %s\n", pcsc_error_to_string(rc));
#endif

	if (rc != SCARD_S_SUCCESS) {
		FUNC_FAILS(-1, "SCardTransmit failed");
	}

	FUNC_RETURNS(lenr);
}
Example #2
0
int getValidatedToken(struct p11Slot_t *slot, struct p11Token_t **token)
{
	int rc;
	struct p11Slot_t *pslot;

	FUNC_CALLED();

	// Checking for new or removed token is always performed on the
	// primary slot
	pslot = slot;
	if (pslot->primarySlot)
		pslot = pslot->primarySlot;

	p11LockMutex(context->mutex);

#ifdef CTAPI
	rc = getCTAPIToken(pslot, token);
#else
	rc = getPCSCToken(pslot, token);
#endif

	p11UnlockMutex(context->mutex);

	if (rc != CKR_OK)
		return rc;

	return getToken(slot, token);
}
static int starcos_C_DecryptInit(struct p11Object_t *pObject, CK_MECHANISM_PTR mech)
{
	unsigned char *algotlv;

	FUNC_CALLED();

	FUNC_RETURNS(getAlgorithmIdForDecryption(pObject->token, mech->mechanism, &algotlv));
}
Example #4
0
int getToken(struct p11Slot_t *slot, struct p11Token_t **token)
{
	FUNC_CALLED();

	*token = slot->token;

	FUNC_RETURNS(slot->token ? CKR_OK : CKR_TOKEN_NOT_PRESENT);
}
Example #5
0
/*  C_Sign signs data in a single part, where the signature is an appendix to the data. */
CK_DECLARE_FUNCTION(CK_RV, C_Sign)(
		CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pData,
		CK_ULONG ulDataLen,
		CK_BYTE_PTR pSignature,
		CK_ULONG_PTR pulSignatureLen
)
{
	int rv;
	struct p11Object_t *pObject;
	struct p11Slot_t *pSlot;
	struct p11Session_t *pSession;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	rv = findSessionByHandle(&context->sessionPool, hSession, &pSession);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pSession->activeObjectHandle == CK_INVALID_HANDLE) {
		FUNC_FAILS(CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized");
	}

	rv = findSlot(&context->slotPool, pSession->slotID, &pSlot);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	rv = findSlotKey(pSlot, pSession->activeObjectHandle, &pObject);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pObject->C_Sign != NULL) {
		rv = pObject->C_Sign(pObject, pSession->activeMechanism, pData, ulDataLen, pSignature, pulSignatureLen);

		if ((pSignature != NULL) && (rv != CKR_BUFFER_TOO_SMALL)) {
			pSession->activeObjectHandle = CK_INVALID_HANDLE;
		}

		if (rv == CKR_DEVICE_ERROR) {
			rv = handleDeviceError(hSession);
			FUNC_FAILS(rv, "Device error reported");
		}
	} else {
		FUNC_FAILS(CKR_FUNCTION_NOT_SUPPORTED, "Operation not supported by token");
	}

	FUNC_RETURNS(rv);
}
Example #6
0
/*  C_SignInit initializes a signature operation,
    here the signature is an appendix to the data. */
CK_DECLARE_FUNCTION(CK_RV, C_SignInit)(
		CK_SESSION_HANDLE hSession,
		CK_MECHANISM_PTR pMechanism,
		CK_OBJECT_HANDLE hKey
)
{
	int rv;
	struct p11Object_t *pObject;
	struct p11Slot_t *pSlot;
	struct p11Session_t *pSession;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	rv = findSessionByHandle(&context->sessionPool, hSession, &pSession);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pSession->activeObjectHandle != CK_INVALID_HANDLE) {
		FUNC_FAILS(CKR_OPERATION_ACTIVE, "Operation is already active");
	}

	rv = findSlot(&context->slotPool, pSession->slotID, &pSlot);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	rv = findSlotKey(pSlot, hKey, &pObject);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pObject->C_SignInit != NULL) {
		rv = pObject->C_SignInit(pObject, pMechanism);
		if (rv == CKR_DEVICE_ERROR) {
			rv = handleDeviceError(hSession);
			FUNC_FAILS(rv, "Device error reported");
		}
	} else {
		FUNC_FAILS(CKR_FUNCTION_NOT_SUPPORTED, "Operation not supported by token");
	}

	if (!rv) {
		pSession->activeObjectHandle = pObject->handle;
		pSession->activeMechanism = pMechanism->mechanism;
		rv = CKR_OK;
	}

	FUNC_RETURNS(rv);
}
Example #7
0
int transmitVerifyPinAPDUviaPCSC(struct p11Slot_t *slot,
	unsigned char pinformat, unsigned char minpinsize, unsigned char maxpinsize,
	unsigned char pinblockstring, unsigned char pinlengthformat,
	unsigned char *capdu, size_t capdu_len,
	unsigned char *rapdu, size_t rapdu_len)
{
	LONG rc;
	DWORD lenr;
	PIN_VERIFY_DIRECT_STRUCTURE_t verify;

	FUNC_CALLED();

	if (!slot->card) {
		FUNC_FAILS(-1, "No card handle");
	}

	verify.bTimeOut = 0x00;
	verify.bTimeOut2 = 0x00;
	verify.bmFormatString = pinformat;
	verify.bmPINBlockString = pinblockstring;
	verify.bmPINLengthFormat = pinlengthformat;

	verify.wPINMaxExtraDigit = (minpinsize << 8) | maxpinsize;

	/*
	 * Bit 7-3: RFU
	 * Bit   2: Timout occurred
	 * Bit   1: Validation Key pressed
	 * Bit   0: Max size reached
	 */
	verify.bEntryValidationCondition = 0x02;

	verify.bNumberMessage = 0x01;
	verify.wLangID        = 0x0904;
	verify.bMsgIndex      = 0;

	verify.bTeoPrologue[0]= 0;
	verify.bTeoPrologue[1]= 0;
	verify.bTeoPrologue[2]= 0;

	verify.ulDataLength = capdu_len;
	memcpy(verify.abData, capdu, capdu_len);

	lenr = rapdu_len;

	rc = SCardControl(slot->card, slot->hasFeatureVerifyPINDirect, &verify,  18 + capdu_len + 1, rapdu, rapdu_len, &lenr);

#ifdef DEBUG
	debug("SCardControl (VERIFY_PIN_DIRECT): %s\n", pcsc_error_to_string(rc));
#endif

	if (rc != SCARD_S_SUCCESS) {
		FUNC_FAILS(-1, "SCardControl failed");
	}

	FUNC_RETURNS(lenr);
}
int starcosSelectApplication(struct p11Token_t *token)
{
	struct starcosPrivateData *sc;

	FUNC_CALLED();

	sc = starcosGetPrivateData(token);
	FUNC_RETURNS(starcosSwitchApplication(token, sc->application));
}
Example #9
0
/*  C_EncryptFinal finishes a multiple-part encryption operation. */
CK_DECLARE_FUNCTION(CK_RV, C_EncryptFinal)(
		CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pLastEncryptedPart,
		CK_ULONG_PTR pulLastEncryptedPartLen
)
{
	int rv;
	struct p11Object_t *pObject;
	struct p11Slot_t *pSlot;
	struct p11Session_t *pSession;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	rv = findSessionByHandle(&context->sessionPool, hSession, &pSession);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pSession->activeObjectHandle == CK_INVALID_HANDLE) {
		FUNC_FAILS(CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized");
	}

	rv = findSlot(&context->slotPool, pSession->slotID, &pSlot);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	rv = findSlotKey(pSlot, pSession->activeObjectHandle, &pObject);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pObject->C_EncryptFinal != NULL) {
		rv = pObject->C_EncryptFinal(pObject, pSession->activeMechanism, pLastEncryptedPart, pulLastEncryptedPartLen);
		if (rv == CKR_DEVICE_ERROR) {
			rv = handleDeviceError(hSession);
			FUNC_FAILS(rv, "Device error reported");
		}
	} else {
		FUNC_FAILS(CKR_FUNCTION_NOT_SUPPORTED, "Operation not supported by token");
	}

	if (!rv) {
		pSession->activeObjectHandle = CK_INVALID_HANDLE;
		rv = CKR_OK;
	}

	FUNC_RETURNS(rv);
}
int starcosReadICCSN(struct p11Token_t *token)
{
	static struct bytestring_s EFICCSN = { (unsigned char *)"\x2F\x02", 2 };
	unsigned char scr[12],*s,*d;
	unsigned short SW1SW2;
	struct starcosPrivateData *sc;
	int rc,*sa;

	FUNC_CALLED();

	// Clear currently selected application indicator
	sc = starcosGetPrivateData(token);

	if (token->slot->primarySlot) {
		sa = &(starcosGetPrivateData(getBaseToken(token))->selectedApplication);
	} else {
		sa = &sc->selectedApplication;
	}

	*sa = 0;

	// Select MF
	rc = transmitAPDU(token->slot, 0x00, 0xA4, 0x00, 0x0C,
			0, NULL,
			0, NULL, 0, &SW1SW2);

	if (rc < 0) {
		FUNC_FAILS(rc, "transmitAPDU failed");
	}

	if (SW1SW2 != 0x9000) {
		FUNC_FAILS(-1, "Could not select MF");
	}

	rc = starcosReadTLVEF(token, &EFICCSN, scr, sizeof(scr));

	if (rc < 0)
		FUNC_FAILS(rc, "Reading EF.SN.ICC");
	
	memset(token->info.serialNumber, ' ', sizeof(token->info.serialNumber));

	s = scr + 4;		// Ignore 5A08 and first two bytes as serial number is only 16 digits while ICCSN is 20 digits
	rc -= 4;
	d = token->info.serialNumber;

	while (rc > 0) {
		*d++ = bcddigit(*s >> 4);
		*d++ = bcddigit(*s & 15);
		s++;
		rc--;
	}

	return 0;
}
Example #11
0
/**
 * Encode APDU using either short or extended notation
 *
 * @param CLA the instruction class
 * @param INS the instruction code
 * @param P1 the first parameter
 * @param P2 the second parameter
 * @param Nc number of outgoing bytes
 * @param OutData outgoing command data
 * @param Ne number of bytes expected from card,
 *           -1 for none,
 *           0 for all in short mode,
 *           > 255 in extended mode,
 *           >= 65536 all in extended mode
 * @param apdu buffer receiving the encoded APDU
 * @param apdu_len length of provided buffer
 * @return -1 for error or the length of the encoded APDU otherwise
 */
int encodeCommandAPDU(
		unsigned char CLA, unsigned char INS, unsigned char P1, unsigned char P2,
		size_t Nc, unsigned char *OutData, int Ne,
		unsigned char *apdu, size_t apdu_len)
{
	unsigned char *po;

	FUNC_CALLED();

	if (apdu == NULL)
		FUNC_FAILS(-1, "Output buffer not defined");

	if (Nc + 9 > apdu_len)
		FUNC_FAILS(-1, "Nc larger than output buffer");

	if (Nc && (OutData == NULL))
		FUNC_FAILS(-1, "OutData not defined for Nc > 0");

	apdu[0] = CLA;
	apdu[1] = INS;
	apdu[2] = P1;
	apdu[3] = P2;
	po = apdu + 4;

	if (OutData && Nc) {
		if ((Nc <= 255) && (Ne <= 255)) {		// Case 3s or 4s
			*po++ = (unsigned char)Nc;
		} else {
			*po++ = 0;							// Case 3e or 3e
			*po++ = (unsigned char)(Nc >> 8);
			*po++ = (unsigned char)(Nc & 0xFF);
		}
		memcpy(po, OutData, Nc);
		po += Nc;
	}

	if (Ne >= 0) {								// Case 2 or 4
		if ((Ne <= 255) && (Nc <= 255)) {		// Case 2s or 4s
			*po++ = (unsigned char)Ne;
		} else {
			if (Ne >= 65536)					// Request all for extended APDU
				Ne = 0;

			if (!OutData)						// Case 4e
				*po++ = 0;

			*po++ = (unsigned char)(Ne >> 8);
			*po++ = (unsigned char)(Ne & 0xFF);
		}
	}

	FUNC_RETURNS(po - apdu);
}
Example #12
0
static int sc_hsm_C_Decrypt(struct p11Object_t *pObject, CK_MECHANISM_TYPE mech, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
{
	int rc, algo;
	unsigned short SW1SW2;
	unsigned char scr[256];

	FUNC_CALLED();

	if (pData == NULL) {
		*pulDataLen = pObject->keysize >> 3;
		FUNC_RETURNS(CKR_OK);
	}
Example #13
0
/*  C_CancelFunction cancelled a function running in parallel
    with an application. Now legacy! */
CK_DECLARE_FUNCTION(CK_RV, C_CancelFunction)(
		CK_SESSION_HANDLE hSession
)
{
	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	FUNC_RETURNS(CKR_FUNCTION_NOT_PARALLEL);
}
Example #14
0
static int sc_hsm_C_DecryptInit(struct p11Object_t *pObject, CK_MECHANISM_PTR mech)
{
	int algo;

	FUNC_CALLED();

	algo = getAlgorithmIdForDecryption(mech->mechanism);
	if (algo < 0) {
		FUNC_FAILS(CKR_MECHANISM_INVALID, "Mechanism not supported");
	}

	FUNC_RETURNS(CKR_OK);
}
Example #15
0
/*  C_SignUpdate continues a multiple-part signature operation,
    processing another data part. */
CK_DECLARE_FUNCTION(CK_RV, C_SignUpdate)(
		CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pPart,
		CK_ULONG ulPartLen
)
{
	CK_RV rv;
	struct p11Object_t *pObject;
	struct p11Slot_t *pSlot;
	struct p11Session_t *pSession;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	rv = findSessionByHandle(&context->sessionPool, hSession, &pSession);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pSession->activeObjectHandle == CK_INVALID_HANDLE) {
		FUNC_FAILS(CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized");
	}

	rv = findSlot(&context->slotPool, pSession->slotID, &pSlot);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	rv = findSlotKey(pSlot, pSession->activeObjectHandle, &pObject);

	if (rv != CKR_OK) {
		FUNC_RETURNS(rv);
	}

	if (pObject->C_SignUpdate != NULL) {
		rv = pObject->C_SignUpdate(pObject, pSession->activeMechanism, pPart, ulPartLen);
		if (rv == CKR_DEVICE_ERROR) {
			rv = handleDeviceError(hSession);
			FUNC_FAILS(rv, "Device error reported");
		}
	} else {
		rv = appendToCryptoBuffer(pSession, pPart, ulPartLen);
	}

	FUNC_RETURNS(rv);
}
Example #16
0
int updateSlots(struct p11SlotPool_t *pool)
{
	int rc;

	FUNC_CALLED();

#ifdef CTAPI
	rc = updateCTAPISlots(pool);
#else
	rc = updatePCSCSlots(pool);
#endif

	FUNC_RETURNS(rc);
}
Example #17
0
int closePCSCSlot(struct p11Slot_t *slot)
{
	LONG rc;

	FUNC_CALLED();

#ifdef DEBUG
	debug("Trying to close slot (%i, %s)\n", slot->id, slot->readername);
#endif

	slotCounter--;

	if (slotCounter == 0 && globalContext) {
#ifdef DEBUG
		debug("Releasing global PC/SC context\n");
#endif
		rc = SCardReleaseContext(globalContext);

#ifdef DEBUG
		debug("SCardReleaseContext (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rc));
#endif

		globalContext = 0;
	}

	/* No token in slot */
	if (!slot->card) {
		slot->closed = TRUE;
		FUNC_RETURNS(CKR_OK);
	}

	rc = SCardDisconnect(slot->card, SCARD_UNPOWER_CARD);

#ifdef DEBUG
	debug("SCardDisconnect (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rc));
	debug("Releasing slot specific PC/SC context - slot counter is %i\n", slotCounter);
#endif

	rc = SCardReleaseContext(slot->context);

#ifdef DEBUG
	debug("SCardReleaseContext (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rc));
#endif

	slot->context = 0;
	slot->card = 0;
	slot->closed = TRUE;

	FUNC_RETURNS(CKR_OK);
}
Example #18
0
int getPCSCToken(struct p11Slot_t *slot, struct p11Token_t **token)
{
	int rc;

	FUNC_CALLED();

	if (slot->token) {
		rc = checkForRemovedPCSCToken(slot);
	} else {
		rc = checkForNewPCSCToken(slot);
	}

	*token = slot->token;
	FUNC_RETURNS(rc);
}
Example #19
0
/*  C_DigestKey continues a multiple-part message-digesting operation by
    digesting the value of a secret key. */
CK_DECLARE_FUNCTION(CK_RV, C_DigestKey)(
		CK_SESSION_HANDLE hSession,
		CK_OBJECT_HANDLE hKey
)
{
	CK_RV rv = CKR_FUNCTION_NOT_SUPPORTED;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	FUNC_RETURNS(rv);
}
Example #20
0
/*  C_DigestFinal finishes a multiple-part message-digesting operation. */
CK_DECLARE_FUNCTION(CK_RV, C_DigestFinal)(
		CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pDigest,
		CK_ULONG_PTR pulDigestLen
)
{
	CK_RV rv = CKR_FUNCTION_NOT_SUPPORTED;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	FUNC_RETURNS(rv);
}
Example #21
0
static int checkPINStatus(struct p11Slot_t *slot)
{
	int rc;
	unsigned short SW1SW2;
	FUNC_CALLED();

	rc = transmitAPDU(slot, 0x00, 0x20, 0x00, 0x81,
			0, NULL,
			0, NULL, 0, &SW1SW2);

	if (rc < 0) {
		FUNC_FAILS(rc, "transmitAPDU failed");
	}

	FUNC_RETURNS(SW1SW2);
}
Example #22
0
/*  C_SignRecoverInit initializes a signature operation, where the data
    can be recovered from the signature. */
CK_DECLARE_FUNCTION(CK_RV, C_SignRecoverInit)(
		CK_SESSION_HANDLE hSession,
		CK_MECHANISM_PTR pMechanism,
		CK_OBJECT_HANDLE hKey
)
{
	CK_RV rv = CKR_FUNCTION_NOT_SUPPORTED;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	FUNC_RETURNS(rv);
}
int starcosCheckPINStatus(struct p11Slot_t *slot, unsigned char pinref)
{
	int rc;
	unsigned short SW1SW2;
	FUNC_CALLED();

	rc = transmitAPDU(slot, 0x00, 0x20, 0x00, pinref,
			0, NULL,
			0, NULL, 0, &SW1SW2);

	if (rc < 0) {
		FUNC_FAILS(rc, "transmitAPDU failed");
	}

	FUNC_RETURNS(SW1SW2);
}
Example #24
0
/*  C_GenerateRandom generates random or pseudo-random data. */
CK_DECLARE_FUNCTION(CK_RV, C_GenerateRandom)(
		CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pRandomData,
		CK_ULONG ulRandomLen
)
{
	CK_RV rv = CKR_FUNCTION_NOT_SUPPORTED;

	FUNC_CALLED();

	if (context == NULL) {
		FUNC_FAILS(CKR_CRYPTOKI_NOT_INITIALIZED, "C_Initialize not called");
	}

	FUNC_RETURNS(rv);
}
Example #25
0
/**
 * checkForRemovedPCSCToken looks into a specific slot for a removed token.
 *
 * @param slot       Pointer to slot structure.
 *
 * @return
 *                   <P><TABLE>
 *                   <TR><TD>Code</TD><TD>Meaning</TD></TR>
 *                   <TR>
 *                   <TD>CKR_OK                                 </TD>
 *                   <TD>Success                                </TD>
 *                   </TR>
 *                   <TR>
 *                   <TD>CKR_HOST_MEMORY                        </TD>
 *                   <TD>Error getting memory (malloc)          </TD>
 *                   </TR>
 *                   <TR>
 *                   <TD>CKR_GENERAL_ERROR                      </TD>
 *                   <TD>Error opening slot directory           </TD>
 *                   </TR>
 *                   </TABLE></P>
 */
static int checkForRemovedPCSCToken(struct p11Slot_t *slot)
{
	int rc;
	LONG rv;

	FUNC_CALLED();

	if (slot->closed) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	if (!slot->card) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	rv = SCardStatus(slot->card, NULL, 0, 0, 0, 0, 0);

#ifdef DEBUG
	debug("SCardStatus: %s\n", pcsc_error_to_string(rv));
#endif

	if (rv == SCARD_S_SUCCESS) {
		FUNC_RETURNS(CKR_OK);
	} else if ((rv == SCARD_W_REMOVED_CARD) || (rv == SCARD_E_INVALID_HANDLE) || (rv == SCARD_E_READER_UNAVAILABLE)) {
		rc = removeToken(slot);
		if (rc != CKR_OK) {
			FUNC_RETURNS(rc);
		}

		rc = SCardDisconnect(slot->card, SCARD_UNPOWER_CARD);

#ifdef DEBUG
		debug("SCardDisconnect (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rc));
#endif

		// Check if a new token was inserted in the meantime
		rc = checkForNewPCSCToken(slot);

		if (rc == CKR_TOKEN_NOT_PRESENT) {
			FUNC_RETURNS(CKR_DEVICE_REMOVED);
		}
	} else {
		FUNC_FAILS(CKR_DEVICE_ERROR, "Error getting PC/SC card terminal status");
	}

	FUNC_RETURNS(rc);
}
Example #26
0
int closeSlot(struct p11Slot_t *slot)
{
	int rc;

	FUNC_CALLED();

	if (slot->primarySlot)
		FUNC_RETURNS(CKR_OK);

#ifdef CTAPI
	rc = closeCTAPISlot(slot);
#else
	rc = closePCSCSlot(slot);
#endif

	FUNC_RETURNS(rc);
}
Example #27
0
/**
 * 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);
}
static int starcos_C_Decrypt(struct p11Object_t *pObject, CK_MECHANISM_TYPE mech, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
{
	int rc, len;
	unsigned char *d,*s;
	unsigned short SW1SW2;
	unsigned char scr[257];
	struct p11Slot_t *slot;

	FUNC_CALLED();

	if (ulEncryptedDataLen != 256)
		FUNC_FAILS(CKR_ENCRYPTED_DATA_LEN_RANGE, "Cryptogram size must be 256 byte");

	if (pData == NULL) {
		*pulDataLen = pObject->keysize >> 3;
		FUNC_RETURNS(CKR_OK);
	}
Example #29
0
int getVirtualSlot(struct p11Slot_t *slot, int index, struct p11Slot_t **vslot)
{
	struct p11Slot_t *newslot;
	char postfix[3];

	FUNC_CALLED();

	if ((index < 0) || (index > sizeof(slot->virtualSlots) / sizeof(*slot->virtualSlots)))
		FUNC_FAILS(CKR_ARGUMENTS_BAD, "Index must not exceed size of virtual slot list");

	if (slot->primarySlot)
		FUNC_FAILS(CKR_ARGUMENTS_BAD, "Slot is a virtual slot");

	if (slot->virtualSlots[index]) {
		*vslot = slot->virtualSlots[index];
		FUNC_RETURNS(CKR_OK);
	}

	newslot = (struct p11Slot_t *) calloc(1, sizeof(struct p11Slot_t));

	if (newslot == NULL)
		FUNC_FAILS(CKR_HOST_MEMORY, "Out of memory");

	*newslot = *slot;
	newslot->token = NULL;
	newslot->next = NULL;
	newslot->primarySlot = slot;

	/* If we already have a pre-allocated slot id, then assign the next id value */
	if (slot->id != 0)
		newslot->id = slot->id + index + 1;

	slot->virtualSlots[index] = newslot;

	postfix[0] = '.';
	postfix[1] = '2' + index;
	postfix[2] = 0;

	appendStr(newslot->info.slotDescription, sizeof(slot->info.slotDescription), postfix);

	addSlot(&context->slotPool, newslot);

	*vslot = newslot;
	FUNC_RETURNS(CKR_OK);
}
Example #30
0
int unlockPCSCSlot(struct p11Slot_t *slot)
{
	DWORD dwActiveProtocol;
	LONG rv;

	FUNC_CALLED();

	rv = SCardReconnect(slot->card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD, &dwActiveProtocol);

#ifdef DEBUG
	debug("SCardReconnect (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rv));
#endif

	if (rv != SCARD_S_SUCCESS)
		FUNC_FAILS(CKR_DEVICE_ERROR, "Could not reconnect to card");

	FUNC_RETURNS(CKR_OK);
}