Ejemplo n.º 1
0
PaceOutput PCSCReader::establishPACEChannel(const PaceInput &input) const
{
	PaceOutput output;
	DWORD r, recvlen;
	uint8_t length_CHAT, length_PIN, PinID;
	uint16_t lengthInputData, lengthCertificateDescription;
	BYTE recvbuf[1024];

	if (input.get_chat().size() > 0xff || input.get_pin().size() > 0xff)
		throw PACEException();

	length_CHAT = (uint8_t) input.get_chat().size();
	length_PIN = (uint8_t) input.get_pin().size();
	//FIXME input.get_certificate_description().size();
	// The certificate description we get is in wrong format
	lengthCertificateDescription = 0;
	lengthInputData = sizeof PinID
					  + sizeof length_CHAT + length_CHAT
					  + sizeof length_PIN + length_PIN
					  + sizeof lengthCertificateDescription + lengthCertificateDescription;
	size_t sendlen = 1 + 2 + lengthInputData;
	BYTE *sendbuf = (BYTE *) malloc(sendlen);

	if (!sendbuf)
		throw TransactionFailed();

	switch (input.get_pin_id()) {
		case PaceInput::mrz:
			PinID = PIN_ID_MRZ;
			break;
		case PaceInput::pin:
			PinID = PIN_ID_PIN;
			break;
		case PaceInput::can:
			PinID = PIN_ID_CAN;
			break;
		case PaceInput::puk:
			PinID = PIN_ID_PUK;
			break;
		default:
			PinID = 0;
			break;
	}

	*sendbuf = FUNCTION_EstabishPACEChannel;
	memcpy(sendbuf + 1,
		   &lengthInputData, sizeof lengthInputData);
	memcpy(sendbuf + 1 + sizeof lengthInputData,
		   &PinID, sizeof PinID);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID,
		   &length_CHAT, sizeof length_CHAT);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT,
		   input.get_chat().data(), length_CHAT);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT,
		   &length_PIN, sizeof length_PIN);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT + sizeof length_PIN,
		   input.get_pin().data(), length_PIN);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT + sizeof length_PIN + length_PIN,
		   &lengthCertificateDescription, sizeof lengthCertificateDescription);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT + sizeof length_PIN + length_PIN + sizeof lengthCertificateDescription,
		   input.get_certificate_description().data(), lengthCertificateDescription);
	hexdump(DEBUG_LEVEL_CARD, "Execute PACE Input Data (FUNCTION=EstabishPACEChannel)", sendbuf, sendlen);
	recvlen = sizeof(recvbuf);
	r = SCardControl(m_hCard, m_ioctl_pace, sendbuf, sendlen,
					 recvbuf, sizeof(recvbuf), &recvlen);
	hexdump(DEBUG_LEVEL_CARD, "Execute PACE Output Data (FUNCTION=EstabishPACEChannel)", recvbuf, recvlen);
	free(sendbuf);
	return parse_EstablishPACEChannel_OutputData(recvbuf, recvlen);
}
Ejemplo n.º 2
0
PaceOutput ExternalReader::establishPACEChannelNative(const PaceInput &input)
{
	PaceOutput paceoutput;

	if (m_hDoPACE) {
		enum PinID pinid = PI_UNDEF;
		switch (input.get_pin_id()) {
			case PaceInput::pin:
				pinid = PI_PIN;
				break;
			case PaceInput::can:
				pinid = PI_CAN;
				break;
			case PaceInput::mrz:
				pinid = PI_MRZ;
				break;
			case PaceInput::puk:
				pinid = PI_PUK;
				break;
			default:
				eCardCore_warn(DEBUG_LEVEL_CARD, "Unknown type of secret");
				break;
		}
		const nPADataBuffer_t pin = {
			(unsigned char *) DATA(input.get_pin()),
			input.get_pin().size()};
		const nPADataBuffer_t chat = {
			(unsigned char *) DATA(input.get_chat()),
			input.get_chat().size()};
		const nPADataBuffer_t chat_required = {
			(unsigned char *) DATA(input.get_chat_required()),
			input.get_chat_required().size()};
		const nPADataBuffer_t chat_optional = {
			(unsigned char *) DATA(input.get_chat_optional()),
			input.get_chat_optional().size()};
		const nPADataBuffer_t certificate_description = {
			(unsigned char *) DATA(input.get_certificate_description()),
			input.get_certificate_description().size()};
		const nPADataBuffer_t transaction_info_hidden = {
			(unsigned char *) DATA(input.get_transaction_info_hidden()),
			input.get_transaction_info_hidden().size()};
		unsigned int result;
		unsigned short status_mse_set_at;
		nPADataBuffer_t ef_cardaccess = {NULL, 0};
		nPADataBuffer_t car_curr = {NULL, 0};
		nPADataBuffer_t car_prev = {NULL, 0};
		nPADataBuffer_t id_icc = {NULL, 0};
		nPADataBuffer_t chat_used = {NULL, 0};

		if (ECARD_SUCCESS == m_hDoPACE(m_hCardReader, pinid, &pin, &chat,
					&chat_required, &chat_optional, &certificate_description,
					&transaction_info_hidden, &result, &status_mse_set_at,
					&ef_cardaccess, &car_curr, &car_prev, &id_icc, &chat_used)) {
			paceoutput.set_result(result);
			paceoutput.set_status_mse_set_at(status_mse_set_at);
			paceoutput.set_ef_cardaccess(buffer2vector(&ef_cardaccess));
			paceoutput.set_car_curr(buffer2vector(&car_curr));
			paceoutput.set_car_prev(buffer2vector(&car_prev));
			paceoutput.set_id_icc(buffer2vector(&id_icc));
			paceoutput.set_chat(buffer2vector(&chat_used));

			free(car_curr.pDataBuffer);
			free(car_prev.pDataBuffer);
			free(ef_cardaccess.pDataBuffer);
			free(id_icc.pDataBuffer);
			free(chat_used.pDataBuffer);
		} else
			eCardCore_warn(DEBUG_LEVEL_CARD, "external PACE failed");
	}

    return paceoutput;
}