#include #include #include #include #include #include int main(int argc, char **argv) { int error = EXIT_SUCCESS; nfc_device *device = NULL; FreefareTag *tags = NULL; nfc_connstring devices[8]; size_t device_count; nfc_context *context; nfc_init(&context); if (context == NULL) { errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); } uint8_t const key_data_null[8] = {0, 0, 0, 0, 0, 0, 0, 0}; MifareDESFireKey key_null = mifare_desfire_des_key_new_with_version(key_data_null); uint8_t key_data_real[16] = {0}; { char const *name = (argc > 1) ? argv[1] : "key"; FILE *f = fopen(name, "rb"); if (!f) { errx(EXIT_FAILURE, "error opening key file: %s", name); } if (fread(key_data_real, 1, sizeof key_data_real, f) < sizeof key_data_real) { errx(EXIT_FAILURE, "key file too small."); } fclose(f); } MifareDESFireKey key_real = mifare_desfire_aes_key_new(key_data_real); FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout; device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(devices[0])); if (device_count <= 0) { errx(EXIT_FAILURE, "No NFC device found."); } if (device_count > 1) { printf("More than 1 device available. Using %s\n", devices[0]); } device = nfc_open(context, devices[0]); if (!device) { errx(EXIT_FAILURE, "nfc_open() failed."); } if (nfc_initiator_init(device) < 0) { errx(EXIT_FAILURE, "Initiator failed."); } while (true) { /* Poll for targets */ const nfc_modulation nmModulations = {.nmt = NMT_ISO14443A, .nbr = NBR_106}; nfc_target target; nfc_initiator_poll_target(device, &nmModulations, 1, 10, 1, &target); /* Got at least one, read tag list */ tags = freefare_get_tags(device); if (!tags) { nfc_close(device); errx(EXIT_FAILURE, "Error listing tags."); } if (!tags[0]) { goto free_tags; } FreefareTag tag = tags[0]; if (MIFARE_DESFIRE != freefare_get_tag_type(tag)) goto free_tags; char *tag_uid = freefare_get_tag_uid(tag); /* Result of various operations */ int res; res = mifare_desfire_connect(tag); if (res < 0) { warnx("Can't connect to Mifare DESFire target."); goto free_tag; } res = mifare_desfire_authenticate(tag, 0, key_null); if (res >= 0) { // Default key still active, create new key res = mifare_desfire_change_key(tag, 0, key_real, key_null); if (res < 0) { warnx("Error changing key"); goto free_tag; } } res = mifare_desfire_authenticate_aes(tag, 0, key_real); if (res < 0) { warnx("Authentication on master application failed"); goto free_tag; } else { fprintf(out, "%s\n", tag_uid); fflush(out); } wait_disconnect: while (0 == nfc_initiator_target_is_present(device, 0)) ; mifare_desfire_disconnect(tag); free_tag: free(tag_uid); free_tags: freefare_free_tags(tags); fflush(stdout); fflush(stderr); } mifare_desfire_key_free(key_null); mifare_desfire_key_free(key_real); nfc_close(device); nfc_exit(context); exit(error); }