Formatting

This commit is contained in:
Lynn Ochs 2022-11-22 17:13:44 +01:00
parent 084866dbbc
commit 3499cde3f8
3 changed files with 195 additions and 178 deletions

View File

@ -4,32 +4,32 @@
#include "poll_desfire.h" #include "poll_desfire.h"
int init(nfc_context **context, nfc_device **device) { int init(nfc_context **context, nfc_device **device) {
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_init(context); nfc_init(context);
if (context == NULL) { if (context == NULL) {
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
} }
device_count = nfc_list_devices(*context, devices, sizeof(devices) / sizeof(devices[0])); device_count = nfc_list_devices(*context, devices, sizeof(devices) / sizeof(devices[0]));
if (device_count <= 0) { if (device_count <= 0) {
errx(EXIT_FAILURE, "No NFC device found."); 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_count > 1) {
if (!device) { printf("More than 1 device available. Using %s\n", devices[0]);
errx(EXIT_FAILURE, "nfc_open() failed."); }
}
if (nfc_initiator_init(*device) < 0) {
errx(EXIT_FAILURE, "Initiator failed.");
}
return 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.");
}
return 0;
} }
void poll_target(nfc_device *device); void poll_target(nfc_device *device);

View File

@ -7,186 +7,204 @@
#include <string.h> #include <string.h>
#include "poll_desfire.h" #include "poll_desfire.h"
#define AID 0x22eaa0 #define AID 0x22eaa0
#define RANDOM_UID_SIZE 8 #define RANDOM_UID_SIZE 8
void init_keys(MifareDESFireKey *null_key, MifareDESFireKey *master_key, char const *name) { void init_keys(MifareDESFireKey *null_key, MifareDESFireKey *master_key, char const *name) {
uint8_t const key_data_null[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t const key_data_null[8] = {0, 0, 0, 0, 0, 0, 0, 0};
*null_key = mifare_desfire_des_key_new_with_version(key_data_null); *null_key = mifare_desfire_des_key_new_with_version(key_data_null);
uint8_t key_data_real[16] = {0}; uint8_t key_data_real[16] = {0};
{ {
FILE *f = fopen(name, "rb"); FILE *f = fopen(name, "rb");
if (!f) { if (!f) {
errx(EXIT_FAILURE, "error opening key file: %s", name); errx(EXIT_FAILURE, "error opening key file: %s", name);
} }
if (fread(key_data_real, 1, sizeof key_data_real, f) < sizeof key_data_real) { if (fread(key_data_real, 1, sizeof key_data_real, f) < sizeof key_data_real) {
errx(EXIT_FAILURE, "key file too small."); errx(EXIT_FAILURE, "key file too small.");
} }
fclose(f); fclose(f);
} }
*master_key = mifare_desfire_aes_key_new(key_data_real); *master_key = mifare_desfire_aes_key_new(key_data_real);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
int error = EXIT_SUCCESS; int error = EXIT_SUCCESS;
nfc_context *context = NULL; nfc_context *context = NULL;
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
MifareDESFireKey key_null, key_master; MifareDESFireKey key_null, key_master;
MifareDESFireAID aid = mifare_desfire_aid_new(AID); MifareDESFireAID aid = mifare_desfire_aid_new(AID);
error = init(&context, &device); error = init(&context, &device);
init_keys(&key_null, &key_master, (argc > 1) ? argv[1] : "key"); init_keys(&key_null, &key_master, (argc > 1) ? argv[1] : "key");
FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout; FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout;
while (true) { while (true) {
tags = freefare_get_tags(device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close(device); nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
for (int id = 0; tags[id]; id++) { for (int id = 0; tags[id]; id++) {
FreefareTag tag = tags[id]; FreefareTag tag = tags[id];
if (MIFARE_DESFIRE != freefare_get_tag_type(tag)) if (MIFARE_DESFIRE != freefare_get_tag_type(tag))
continue; continue;
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 next_tag;
}
if (mifare_desfire_select_application(tag, aid) != 0) { char *tag_uid = freefare_get_tag_uid(tag);
// Check for old card with our key as master key /* Result of various operations */
res = mifare_desfire_authenticate(tag, 0, key_master); int res;
if (res >= 0) {
warnx("Old tag detected: %s", tag_uid);
res = mifare_desfire_change_key(tag, 0, key_master, key_null);
}
// Card needs to have default null key as master
res = mifare_desfire_authenticate(tag, 0, key_null);
if (res < 0) {
warnx("Could not authenticate: %d", res);
goto next_tag;
}
// create application res = mifare_desfire_connect(tag);
res = mifare_desfire_create_application_aes(tag, aid, MDAPP_SETTINGS(0, 1, 0, 0, 1), 1); if (res < 0) {
if (res < 0) { warnx("Can't connect to Mifare DESFire target.");
warnx("Could not create application: %d", res); goto next_tag;
goto next_tag; }
}
// Select it if (mifare_desfire_select_application(tag, aid) != 0) {
res = mifare_desfire_select_application(tag, aid); // Check for old card with our key as master key
if (res < 0) { res = mifare_desfire_authenticate(tag, 0, key_master);
warnx("Application not selectable after creation: %d", res); if (res >= 0) {
goto next_tag; warnx("Old tag detected: %s", tag_uid);
} res =
mifare_desfire_change_key(tag, 0, key_null, key_master);
if (res < 0) {
warnx("Could not change key: %d", res);
goto next_tag;
}
}
// Key should be null // Card needs to have default null key as master
res = mifare_desfire_authenticate_aes(tag, 0, key_null); res = mifare_desfire_authenticate(tag, 0, key_null);
if (res < 0) { if (res < 0) {
warnx("Could not authenticate new application with default key: %d", res); warnx("Could not authenticate: %d", res);
goto next_tag; goto next_tag;
} }
// Update to our key // create application
res = mifare_desfire_change_key(tag, 0, key_master, key_null); res = mifare_desfire_create_application_aes(
if (res < 0) { tag, aid, MDAPP_SETTINGS(0, 1, 0, 0, 1), 1);
warnx("Could not change key of new application to master key: %d", res); if (res < 0) {
goto next_tag; warnx("Could not create application: %d", res);
} goto next_tag;
}
// Authenticate with new key
res = mifare_desfire_authenticate_aes(tag, 0, key_master);
if (res < 0) {
warnx("Could not authenticate new application with our key: %d", res);
goto next_tag;
}
// Create file // Select it
res = mifare_desfire_create_std_data_file(tag, 0, 0, MDAR(0, 0, 0, 0), RANDOM_UID_SIZE); res = mifare_desfire_select_application(tag, aid);
if (res < 0) { if (res < 0) {
warnx("Could not create data file: %d", res); warnx("Application not selectable after creation: %d", res);
goto next_tag; goto next_tag;
} }
// Grab random data for it // Key should be null
unsigned char uid_data[RANDOM_UID_SIZE]; res = mifare_desfire_authenticate_aes(tag, 0, key_null);
{ if (res < 0) {
int fd = open("/dev/urandom", O_RDONLY); warnx(
if (fd < 0) { "Could not authenticate new application with default "
warnx("Could not open /dev/urandom"); "key: %d",
goto next_tag; res);
} goto next_tag;
}
if (RANDOM_UID_SIZE != read(fd, &uid_data[0], RANDOM_UID_SIZE)) { // Update to our key
warnx("Could not read data from /dev/random"); res = mifare_desfire_change_key(tag, 0, key_master, key_null);
goto next_tag; if (res < 0) {
} warnx(
close(fd); "Could not change key of new application to master "
} "key: %d",
res);
goto next_tag;
}
// Write data // Authenticate with new key
res = mifare_desfire_write_data(tag, 0, 0, RANDOM_UID_SIZE, &uid_data[0]); res = mifare_desfire_authenticate_aes(tag, 0, key_master);
if (res < 0) { if (res < 0) {
warnx("Could not write UID data to tag: %d", res); warnx(
goto next_tag; "Could not authenticate new application with our key: "
} "%d",
} res);
goto next_tag;
}
// Authenticate with our key // Create file
res = mifare_desfire_authenticate_aes(tag, 0, key_master); res = mifare_desfire_create_std_data_file(
if (res < 0) { tag, 0, 0, MDAR(0, 0, 0, 0), RANDOM_UID_SIZE);
warnx("Authentication on application failed: %d", res); if (res < 0) {
goto next_tag; warnx("Could not create data file: %d", res);
} goto next_tag;
}
// Grab UID // Grab random data for it
uint8_t data[RANDOM_UID_SIZE]; unsigned char uid_data[RANDOM_UID_SIZE];
res = mifare_desfire_read_data(tag, 0, 0, RANDOM_UID_SIZE, &data[0]); {
if (res != RANDOM_UID_SIZE) { int fd = open("/dev/urandom", O_RDONLY);
warnx("Could not read all bytes from tag: %d", res); if (fd < 0) {
goto next_tag; warnx("Could not open /dev/urandom");
} goto next_tag;
}
// Print out key ID and UID if (RANDOM_UID_SIZE !=
fprintf(out, "%s:", tag_uid); read(fd, &uid_data[0], RANDOM_UID_SIZE)) {
for (int j = 0; j < RANDOM_UID_SIZE; j++) { warnx("Could not read data from /dev/random");
fprintf(out, "%02x", data[j]); goto next_tag;
} }
fprintf(out, "\n"); close(fd);
fflush(out); }
next_tag: // Write data
free(tag_uid); res = mifare_desfire_write_data(tag, 0, 0, RANDOM_UID_SIZE,
&uid_data[0]);
mifare_desfire_disconnect(tag); if (res < 0) {
} warnx("Could not write UID data to tag: %d", res);
goto next_tag;
}
}
while (freefare_selected_tag_is_present(device)) // Authenticate with our key
; res = mifare_desfire_authenticate_aes(tag, 0, key_master);
if (res < 0) {
freefare_free_tags(tags); warnx("Authentication on application failed: %d", res);
fflush(stdout); goto next_tag;
fflush(stderr); }
}
mifare_desfire_key_free(key_null); // Grab UID
mifare_desfire_key_free(key_master); uint8_t data[RANDOM_UID_SIZE];
res = mifare_desfire_read_data(tag, 0, 0, RANDOM_UID_SIZE, &data[0]);
if (res != RANDOM_UID_SIZE) {
warnx("Could not read all bytes from tag: %d", res);
goto next_tag;
}
nfc_close(device); // Print out key ID and UID
nfc_exit(context); fprintf(out, "%s:", tag_uid);
for (int j = 0; j < RANDOM_UID_SIZE; j++) {
fprintf(out, "%02x", data[j]);
}
fprintf(out, "\n");
fflush(out);
exit(error); next_tag:
free(tag_uid);
mifare_desfire_disconnect(tag);
}
while (freefare_selected_tag_is_present(device))
;
freefare_free_tags(tags);
fflush(stdout);
fflush(stderr);
}
mifare_desfire_key_free(key_null);
mifare_desfire_key_free(key_master);
nfc_close(device);
nfc_exit(context);
exit(error);
} }

View File

@ -3,4 +3,3 @@
int init(nfc_context **context, nfc_device **device); int init(nfc_context **context, nfc_device **device);
void poll_target(nfc_device *device); void poll_target(nfc_device *device);