Beispiel #1
0
static PaceOutput
parse_EstablishPACEChannel_OutputData(BYTE *output, size_t output_length)
{
	size_t parsed = 0;
	uint8_t lengthCAR, lengthCARprev;
	uint16_t lengthOutputData, lengthEF_CardAccess, length_IDicc, mse_setat;
	vector<BYTE> CAR, CARprev, EF_CardAccess, IDicc;
	uint32_t result;
	PaceOutput paceoutput;

	/* Output Data */
	if (parsed + sizeof result > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&result, output + parsed, sizeof result);

	switch (result) {
		case 0x00000000:
			break;
		case 0xD0000001:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Längen im Input sind inkonsistent");
			throw PACEException();
		case 0xD0000002:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Unerwartete Daten im Input");
			throw PACEException();
		case 0xD0000003:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Unerwartete Kombination von Daten im Input");
			throw PACEException();
		case 0xE0000001:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Syntaxfehler im Aufbau der TLV-Antwortdaten");
			throw PACEException();
		case 0xE0000002:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Unerwartete/fehlende Objekte in den TLV-Antwortdaten");
			throw PACEException();
		case 0xE0000003:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Der Kartenleser kennt die PIN-ID nicht.");
			throw PACEException();
		case 0xE0000006:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Fehlerhaftes PACE-Token");
			throw PACEException();
		case 0xE0000007:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Zertifikatskette für Terminalauthentisierung kann nicht gebildet werden");
			throw PACEException();
		case 0xE0000008:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Unerwartete Datenstruktur in Rückgabe der Chipauthentisierung");
			throw PACEException();
		case 0xE0000009:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Passive Authentisierung fehlgeschlagen");
			throw PACEException();
		case 0xE000000A:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Fehlerhaftes Chipauthentisierung-Token");
			throw PACEException();
		case 0xF0100001:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Kommunikationsabbruch mit Karte.");
			throw PACEException();
		default:
			eCardCore_warn(DEBUG_LEVEL_CARD, "Reader reported some error: %0X.", result);
			throw PACEException();
	}

	paceoutput.set_result(result);
	parsed += sizeof result;

	/* Output Data */
	if (parsed + sizeof lengthOutputData > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&lengthOutputData, output + parsed, sizeof lengthOutputData);
	parsed += sizeof lengthOutputData;

	if (lengthOutputData != output_length - parsed) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	/* MSE:Set AT */
	if (parsed + sizeof mse_setat > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&mse_setat, output + parsed, sizeof mse_setat);
	paceoutput.set_status_mse_set_at(mse_setat);
	parsed += sizeof mse_setat;

	/* lengthEF_CardAccess */
	if (parsed + 2 > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&lengthEF_CardAccess, output + parsed, sizeof lengthEF_CardAccess);
	parsed += sizeof lengthEF_CardAccess;

	/* EF.CardAccess */
	if (parsed + lengthEF_CardAccess > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	EF_CardAccess.assign(output + parsed, output + parsed + lengthEF_CardAccess);
	paceoutput.set_ef_cardaccess(EF_CardAccess);
	parsed += lengthEF_CardAccess;

	/* lengthCAR */
	if (parsed + sizeof lengthCAR > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&lengthCAR, output + parsed, sizeof lengthCAR);
	parsed += sizeof lengthCAR;

	/* CAR */
	if (parsed + lengthCAR > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	CAR.assign(output + parsed, output + parsed + lengthCAR);
	paceoutput.set_car_curr(CAR);
	parsed += lengthCAR;

	/* lengthCARprev */
	if (parsed + sizeof lengthCARprev > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&lengthCARprev, output + parsed, sizeof lengthCARprev);
	parsed += sizeof lengthCARprev;

	/* CARprev */
	if (parsed + lengthCARprev > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	CARprev.assign(output + parsed, output + parsed + lengthCARprev);
	paceoutput.set_car_prev(CARprev);
	parsed += lengthCARprev;

	/* lengthIDicc */
	if (parsed + sizeof length_IDicc > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	memcpy(&length_IDicc , output + parsed, sizeof length_IDicc);
	parsed += sizeof length_IDicc;

	/* IDicc */
	if (parsed + length_IDicc > output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Malformed Establish PACE Channel output data.");
		throw PACEException();
	}

	IDicc.assign(output + parsed, output + parsed + length_IDicc);
	paceoutput.set_id_icc(IDicc);
	parsed += length_IDicc;

	if (parsed != output_length) {
		eCardCore_warn(DEBUG_LEVEL_CARD, "Overrun by %d bytes", output_length - parsed);
		throw PACEException();
	}

	return paceoutput;
}
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;
}