mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
implement smartcard daemon relay for iso14b cards
This commit is contained in:
parent
4e346e8ca2
commit
db3c86958a
1 changed files with 62 additions and 22 deletions
|
@ -37,6 +37,7 @@
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
|
#include "cmdhf14b.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -1193,7 +1194,7 @@ static void atsToEmulatedAtr(uint8_t *ats, uint8_t *atr, int *atrLen) {
|
||||||
atr[2] = 0x80;
|
atr[2] = 0x80;
|
||||||
atr[3] = 0x01;
|
atr[3] = 0x01;
|
||||||
|
|
||||||
uint8_t tck = 0;
|
uint8_t tck = atr[1] ^ atr[2] ^ atr[3];
|
||||||
for (int i = 0; i < historicalLen; ++i) {
|
for (int i = 0; i < historicalLen; ++i) {
|
||||||
atr[4 + i] = ats[offset + i];
|
atr[4 + i] = ats[offset + i];
|
||||||
tck = tck ^ ats[offset + i];
|
tck = tck ^ ats[offset + i];
|
||||||
|
@ -1203,6 +1204,24 @@ static void atsToEmulatedAtr(uint8_t *ats, uint8_t *atr, int *atrLen) {
|
||||||
*atrLen = 5 + historicalLen;
|
*atrLen = 5 + historicalLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void atqbToEmulatedAtr(uint8_t *atqb, uint8_t cid, uint8_t *atr, int *atrLen) {
|
||||||
|
atr[0] = 0x3B;
|
||||||
|
atr[1] = 0x80 | 8;
|
||||||
|
atr[2] = 0x80;
|
||||||
|
atr[3] = 0x01;
|
||||||
|
|
||||||
|
memcpy(atr + 4, atqb, 7);
|
||||||
|
atr[11] = cid >> 4;
|
||||||
|
|
||||||
|
uint8_t tck = 0;
|
||||||
|
for (int i = 1; i < 12; ++i) {
|
||||||
|
tck = tck ^ atr[i];
|
||||||
|
}
|
||||||
|
atr[12] = tck;
|
||||||
|
|
||||||
|
*atrLen = 13;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdRelay(const char *Cmd) {
|
static int CmdRelay(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "smart relay",
|
CLIParserInit(&ctx, "smart relay",
|
||||||
|
@ -1243,11 +1262,13 @@ static int CmdRelay(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Relaying pm3 to host OS pcsc daemon. Press " _GREEN_("Enter") " to exit");
|
PrintAndLogEx(INFO, "Relaying pm3 to host OS pcsc daemon. Press " _GREEN_("Enter") " to exit");
|
||||||
|
|
||||||
uint8_t cmdbuf[512] = {0};
|
uint8_t cmdbuf[512] = {0};
|
||||||
bool haveCard = false;
|
iso14a_card_select_t selectedCard14a;
|
||||||
iso14a_card_select_t selectedCard;
|
iso14b_card_select_t selectedCard14b;
|
||||||
|
isodep_state_t cardType = ISODEP_INACTIVE;
|
||||||
|
bool fieldActivated = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (haveCard) {
|
if (cardType != ISODEP_INACTIVE) {
|
||||||
int bytesRead = mbedtls_net_recv_timeout(&netCtx, cmdbuf, sizeof(cmdbuf), 100);
|
int bytesRead = mbedtls_net_recv_timeout(&netCtx, cmdbuf, sizeof(cmdbuf), 100);
|
||||||
|
|
||||||
if (bytesRead == MBEDTLS_ERR_SSL_TIMEOUT || bytesRead == MBEDTLS_ERR_SSL_WANT_READ) {
|
if (bytesRead == MBEDTLS_ERR_SSL_TIMEOUT || bytesRead == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||||
|
@ -1258,7 +1279,12 @@ static int CmdRelay(const char *Cmd) {
|
||||||
if (cmdbuf[1] == 0x01 && cmdbuf[2] == 0x04) { // vpcd GET ATR
|
if (cmdbuf[1] == 0x01 && cmdbuf[2] == 0x04) { // vpcd GET ATR
|
||||||
uint8_t atr[20] = {0};
|
uint8_t atr[20] = {0};
|
||||||
int atrLen = 0;
|
int atrLen = 0;
|
||||||
atsToEmulatedAtr(selectedCard.ats, atr, &atrLen);
|
|
||||||
|
if (cardType == ISODEP_NFCA) {
|
||||||
|
atsToEmulatedAtr(selectedCard14a.ats, atr, &atrLen);
|
||||||
|
} else if (cardType == ISODEP_NFCB) {
|
||||||
|
atqbToEmulatedAtr(selectedCard14b.atqb, selectedCard14b.cid, atr, &atrLen);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t res[22] = {0};
|
uint8_t res[22] = {0};
|
||||||
res[1] = atrLen;
|
res[1] = atrLen;
|
||||||
|
@ -1274,11 +1300,21 @@ static int CmdRelay(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, ">> %s", sprint_hex(cmdbuf + 2, apduLen));
|
PrintAndLogEx(INFO, ">> %s", sprint_hex(cmdbuf + 2, apduLen));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExchangeAPDU14a(cmdbuf + 2, apduLen, true, true, apduRes, sizeof(apduRes), &apduResLen) != PM3_SUCCESS) {
|
if (cardType == ISODEP_NFCA) {
|
||||||
haveCard = false;
|
if (ExchangeAPDU14a(cmdbuf + 2, apduLen, !fieldActivated, true, apduRes, sizeof(apduRes), &apduResLen) != PM3_SUCCESS) {
|
||||||
mbedtls_net_close(&netCtx);
|
cardType = ISODEP_INACTIVE;
|
||||||
continue;
|
mbedtls_net_close(&netCtx);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
} else if (cardType == ISODEP_NFCB) {
|
||||||
|
if (exchange_14b_apdu(cmdbuf + 2, apduLen, !fieldActivated, true, apduRes, sizeof(apduRes), &apduResLen, 0)) {
|
||||||
|
cardType = ISODEP_INACTIVE;
|
||||||
|
mbedtls_net_close(&netCtx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldActivated = true;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "<< %s", sprint_hex(apduRes, apduResLen));
|
PrintAndLogEx(INFO, "<< %s", sprint_hex(apduRes, apduResLen));
|
||||||
|
@ -1292,18 +1328,22 @@ static int CmdRelay(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (SelectCard14443A_4(false, false, &selectedCard) == PM3_SUCCESS) {
|
if (IfPm3Iso14443a() && SelectCard14443A_4(false, false, &selectedCard14a) == PM3_SUCCESS) {
|
||||||
if (mbedtls_net_connect(&netCtx, (char *) host, (char *) port, MBEDTLS_NET_PROTO_TCP)) {
|
cardType = ISODEP_NFCA;
|
||||||
PrintAndLogEx(FAILED, "Failed to connect to vpcd socket. Ensure you have vpcd installed and running");
|
} else if (IfPm3Iso14443b() && select_card_14443b_4(false, &selectedCard14b) == PM3_SUCCESS) {
|
||||||
mbedtls_net_close(&netCtx);
|
cardType = ISODEP_NFCB;
|
||||||
mbedtls_net_free(&netCtx);
|
}
|
||||||
DropField();
|
if (cardType != ISODEP_INACTIVE) {
|
||||||
return PM3_EINVARG;
|
fieldActivated = false;
|
||||||
}
|
if (mbedtls_net_connect(&netCtx, (char *) host, (char *) port, MBEDTLS_NET_PROTO_TCP)) {
|
||||||
|
PrintAndLogEx(FAILED, "Failed to connect to vpcd socket. Ensure you have vpcd installed and running");
|
||||||
haveCard = true;
|
mbedtls_net_close(&netCtx);
|
||||||
}
|
mbedtls_net_free(&netCtx);
|
||||||
msleep(300);
|
DropField();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(300);
|
||||||
}
|
}
|
||||||
} while (!kbd_enter_pressed());
|
} while (!kbd_enter_pressed());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue