PollDesfire/poll_desfire.c

134 lines
3.2 KiB
C

#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <nfc/nfc.h>
#include <freefare.h>
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);
}