mirror of
https://github.com/bettse/seader.git
synced 2026-05-12 21:46:02 +00:00
reconstruct the full ATS rather than just sending the historical bytes
rejig card type detection in seader_worker_card_detect
This commit is contained in:
@@ -1101,6 +1101,7 @@ NfcCommand seader_worker_card_detect(
|
||||
uint8_t uid_len,
|
||||
uint8_t* ats,
|
||||
uint8_t ats_len) {
|
||||
UNUSED(atqa);
|
||||
SeaderCredential* credential = seader->credential;
|
||||
|
||||
CardDetails_t* cardDetails = 0;
|
||||
@@ -1109,37 +1110,21 @@ NfcCommand seader_worker_card_detect(
|
||||
|
||||
OCTET_STRING_fromBuf(&cardDetails->csn, (const char*)uid, uid_len);
|
||||
OCTET_STRING_t sak_string = {.buf = &sak, .size = 1};
|
||||
OCTET_STRING_t ats_string = {0};
|
||||
if(ats != NULL) {
|
||||
ats_string.buf = ats;
|
||||
ats_string.size = ats_len;
|
||||
} else {
|
||||
// technically I think this field is only ever meant to be ATS not ATQA
|
||||
// for 14443a-4 cards but in practice, Seos cards seem to fail to read the
|
||||
// ATS but the ATS doesn't matter for Seos as long as it's there otherwise
|
||||
// the SAM thinks it's a part3 card, and filling it with the ATQA is what
|
||||
// we did previously and seemed to work so eh
|
||||
ats_string.buf = atqa;
|
||||
ats_string.size = 2;
|
||||
}
|
||||
OCTET_STRING_t ats_string = {.buf = ats, .size = ats_len};
|
||||
uint8_t protocol_bytes[] = {0x00, 0x00};
|
||||
|
||||
if(sak != 0 && atqa != NULL) { // type 4
|
||||
if(ats != NULL) { // type 4
|
||||
protocol_bytes[1] = FrameProtocol_nfc;
|
||||
OCTET_STRING_fromBuf(
|
||||
&cardDetails->protocol, (const char*)protocol_bytes, sizeof(protocol_bytes));
|
||||
cardDetails->sak = &sak_string;
|
||||
// TODO: Update asn1 to change atqa to ats
|
||||
cardDetails->atqa = &ats_string;
|
||||
credential->isDesfire = seader_mf_df_check_card_type(atqa[0], atqa[1], sak);
|
||||
if(credential->isDesfire) {
|
||||
memcpy(credential->diversifier, uid, uid_len);
|
||||
credential->diversifier_len = uid_len;
|
||||
}
|
||||
} else if(sak != 0 && atqa == NULL) { // MFC
|
||||
protocol_bytes[1] = FrameProtocol_nfc;
|
||||
OCTET_STRING_fromBuf(
|
||||
&cardDetails->protocol, (const char*)protocol_bytes, sizeof(protocol_bytes));
|
||||
cardDetails->sak = &sak_string;
|
||||
} else if(uid_len == 8) { // picopass
|
||||
protocol_bytes[1] = FrameProtocol_iclass;
|
||||
OCTET_STRING_fromBuf(
|
||||
@@ -1147,8 +1132,11 @@ NfcCommand seader_worker_card_detect(
|
||||
memcpy(credential->diversifier, uid, uid_len);
|
||||
credential->diversifier_len = uid_len;
|
||||
credential->isDesfire = false;
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "Unknown card type");
|
||||
} else { // MFC
|
||||
protocol_bytes[1] = FrameProtocol_nfc;
|
||||
OCTET_STRING_fromBuf(
|
||||
&cardDetails->protocol, (const char*)protocol_bytes, sizeof(protocol_bytes));
|
||||
cardDetails->sak = &sak_string;
|
||||
}
|
||||
|
||||
seader_send_card_detected(seader, cardDetails);
|
||||
|
||||
+33
-10
@@ -284,24 +284,47 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
|
||||
const Iso14443_4aData* iso14443_4a_data =
|
||||
nfc_device_get_data(seader->nfc_device, NfcProtocolIso14443_4a);
|
||||
const Iso14443_3aData* iso14443_3a_data = iso14443_4a_get_base_data(iso14443_4a_data);
|
||||
uint32_t ats_len = 0;
|
||||
uint8_t* ats = NULL;
|
||||
|
||||
uint32_t t1_tk_size = 0;
|
||||
if(iso14443_4a_data->ats_data.t1_tk != NULL) {
|
||||
// for some reason Seos cards fail to read the ATS
|
||||
SimpleArray* ats_array = iso14443_4a_data->ats_data.t1_tk;
|
||||
ats_len = simple_array_get_count(ats_array);
|
||||
if(ats_len > 0xFF) {
|
||||
ats_len = 0;
|
||||
}
|
||||
if(ats_len > 0) {
|
||||
ats = simple_array_get_data(ats_array);
|
||||
t1_tk_size = simple_array_get_count(iso14443_4a_data->ats_data.t1_tk);
|
||||
if(t1_tk_size > 0xFF) {
|
||||
t1_tk_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ats_len = 0;
|
||||
uint8_t* ats = malloc(4 + t1_tk_size);
|
||||
furi_assert(ats);
|
||||
|
||||
if(iso14443_4a_data->ats_data.tl > 1) {
|
||||
ats[ats_len++] = iso14443_4a_data->ats_data.t0;
|
||||
if(iso14443_4a_data->ats_data.t0 & ISO14443_4A_ATS_T0_TA1) {
|
||||
ats[ats_len++] = iso14443_4a_data->ats_data.ta_1;
|
||||
}
|
||||
if(iso14443_4a_data->ats_data.t0 & ISO14443_4A_ATS_T0_TB1) {
|
||||
ats[ats_len++] = iso14443_4a_data->ats_data.tb_1;
|
||||
}
|
||||
if(iso14443_4a_data->ats_data.t0 & ISO14443_4A_ATS_T0_TC1) {
|
||||
ats[ats_len++] = iso14443_4a_data->ats_data.tc_1;
|
||||
}
|
||||
|
||||
if(t1_tk_size != 0) {
|
||||
memcpy(
|
||||
ats + ats_len,
|
||||
simple_array_cget_data(iso14443_4a_data->ats_data.t1_tk),
|
||||
t1_tk_size);
|
||||
ats_len += t1_tk_size;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sak = iso14443_3a_get_sak(iso14443_3a_data);
|
||||
|
||||
seader_worker_card_detect(
|
||||
seader, sak, (uint8_t*)iso14443_3a_data->atqa, uid, uid_len, ats, ats_len);
|
||||
|
||||
free(ats);
|
||||
|
||||
// nfc_set_fdt_poll_fc(event.instance, SEADER_POLLER_MAX_FWT);
|
||||
furi_thread_set_current_priority(FuriThreadPriorityLowest);
|
||||
seader_worker->stage = SeaderPollerEventTypeConversation;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
#define SEADER_POLLER_MAX_FWT (200000U)
|
||||
#define SEADER_POLLER_MAX_BUFFER_SIZE (255U)
|
||||
|
||||
// ATS bit definitions
|
||||
#define ISO14443_4A_ATS_T0_TA1 (1U << 4)
|
||||
#define ISO14443_4A_ATS_T0_TB1 (1U << 5)
|
||||
#define ISO14443_4A_ATS_T0_TC1 (1U << 6)
|
||||
|
||||
struct SeaderWorker {
|
||||
FuriThread* thread;
|
||||
Storage* storage;
|
||||
|
||||
Reference in New Issue
Block a user