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