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