Run make style to fix style
This commit is contained in:
parent
187481bb4c
commit
73dc0529fa
66 changed files with 5945 additions and 5949 deletions
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2015, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -23,56 +23,56 @@
|
|||
#include <freefare.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
main(void)
|
||||
{
|
||||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
nfc_connstring devices[8];
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx (EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
size_t device_count = nfc_list_devices (context, devices, 8);
|
||||
size_t device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
errx (EXIT_FAILURE, "nfc_open() failed.");
|
||||
errx(EXIT_FAILURE, "nfc_open() failed.");
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing FeliCa tag.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing FeliCa tag.");
|
||||
}
|
||||
|
||||
for (int i = 0; tags[i]; i++) {
|
||||
if (FELICA != freefare_get_tag_type (tags[i]))
|
||||
if (FELICA != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *uid = freefare_get_tag_uid (tags[i]);
|
||||
printf ("Dumping %s tag %s\n", freefare_get_tag_friendly_name (tags[i]), uid);
|
||||
free (uid);
|
||||
printf ("Number\tName\tData\n");
|
||||
char *uid = freefare_get_tag_uid(tags[i]);
|
||||
printf("Dumping %s tag %s\n", freefare_get_tag_friendly_name(tags[i]), uid);
|
||||
free(uid);
|
||||
printf("Number\tName\tData\n");
|
||||
|
||||
for (int block = 0x00; block < 0x0f; block++) {
|
||||
uint8_t buffer[16];
|
||||
|
||||
if (felica_read (tags[i], FELICA_SC_RO, block, buffer, sizeof (buffer)) < 0)
|
||||
errx (EXIT_FAILURE, "Error reading block %d", block);
|
||||
if (felica_read(tags[i], FELICA_SC_RO, block, buffer, sizeof(buffer)) < 0)
|
||||
errx(EXIT_FAILURE, "Error reading block %d", block);
|
||||
|
||||
if (block < 0x0e)
|
||||
printf ("0x%02x\tS_PAD%d\t", block, block);
|
||||
printf("0x%02x\tS_PAD%d\t", block, block);
|
||||
else
|
||||
printf ("0x%02x\tREG\t", block);
|
||||
printf("0x%02x\tREG\t", block);
|
||||
for (int j = 0; j < 16; j++) {
|
||||
printf ("%02x ", buffer[j]);
|
||||
printf("%02x ", buffer[j]);
|
||||
}
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
char *block_names[] = {
|
||||
|
|
@ -84,19 +84,19 @@ main (void)
|
|||
for (int block = 0x80; block < 0x89; block++) {
|
||||
uint8_t buffer[16];
|
||||
|
||||
if (felica_read (tags[i], FELICA_SC_RO, block, buffer, sizeof (buffer)) < 0)
|
||||
errx (EXIT_FAILURE, "Error reading block %d", block);
|
||||
if (felica_read(tags[i], FELICA_SC_RO, block, buffer, sizeof(buffer)) < 0)
|
||||
errx(EXIT_FAILURE, "Error reading block %d", block);
|
||||
|
||||
printf ("0x%02x\t%s\t", block, block_names[block - 0x80]);
|
||||
printf("0x%02x\t%s\t", block, block_names[block - 0x80]);
|
||||
for (int j = 0; j < valid_bytes[block - 0x80]; j++) {
|
||||
printf ("%02x ", buffer[j]);
|
||||
printf("%02x ", buffer[j]);
|
||||
}
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2015, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -44,15 +44,15 @@
|
|||
#define NDEF_BUFFER_SIZE 512
|
||||
|
||||
void
|
||||
usage (char *progname)
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [options]\n", progname);
|
||||
fprintf (stderr, "\nAvailable options:\n");
|
||||
fprintf (stderr, " -o FILE Write NDEF message to FILE\n");
|
||||
fprintf(stderr, "usage: %s [options]\n", progname);
|
||||
fprintf(stderr, "\nAvailable options:\n");
|
||||
fprintf(stderr, " -o FILE Write NDEF message to FILE\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int error = EXIT_SUCCESS;
|
||||
nfc_device *device = NULL;
|
||||
|
|
@ -60,14 +60,14 @@ main (int argc, char *argv[])
|
|||
|
||||
int ch;
|
||||
char *ndef_file = NULL;
|
||||
while ((ch = getopt (argc, argv, "o:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "o:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
ndef_file = optarg;
|
||||
break;
|
||||
case '?':
|
||||
usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,26 +76,26 @@ main (int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
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, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing FeliCa tag.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing FeliCa tag.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
|
|
@ -106,7 +106,7 @@ main (int argc, char *argv[])
|
|||
ssize_t s;
|
||||
|
||||
// FIXME Instead of reading as much as we can, we should read until end of NDEF record (if any is found).
|
||||
while ((ndef_space_left >= 16) && (s = felica_read (tags[i], FELICA_SC_RO, block++, p, 16)) > 0) {
|
||||
while ((ndef_space_left >= 16) && (s = felica_read(tags[i], FELICA_SC_RO, block++, p, 16)) > 0) {
|
||||
p += s;
|
||||
ndef_space_left -= s;
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ main (int argc, char *argv[])
|
|||
payload_length = ndef_record[2];
|
||||
payload_length_length = 1;
|
||||
} else {
|
||||
payload_length = be32toh (*(uint32_t *)(ndef_record + 2));
|
||||
payload_length = be32toh(*(uint32_t *)(ndef_record + 2));
|
||||
payload_length_length = 4;
|
||||
}
|
||||
ndef_record_length += payload_length_length;
|
||||
|
|
@ -139,28 +139,28 @@ main (int argc, char *argv[])
|
|||
|
||||
ndef_message_length += ndef_record_length;
|
||||
if (ndef_message_length > NDEF_BUFFER_SIZE)
|
||||
errx (EXIT_FAILURE, "NDEF message truncated");
|
||||
errx(EXIT_FAILURE, "NDEF message truncated");
|
||||
|
||||
} while ((ndef_record[0] & 0x40) != 0x40);
|
||||
}
|
||||
|
||||
if (ndef_message_length == 0)
|
||||
errx (EXIT_FAILURE, "No NDEF message found");
|
||||
errx(EXIT_FAILURE, "No NDEF message found");
|
||||
|
||||
FILE *f;
|
||||
if (ndef_file)
|
||||
f = fopen (ndef_file, "w");
|
||||
f = fopen(ndef_file, "w");
|
||||
else
|
||||
f = stdout;
|
||||
|
||||
if (fwrite (ndef_message, ndef_message_length, 1, f) != 1)
|
||||
err (EXIT_FAILURE, "Can't write NDEF message");
|
||||
if (fwrite(ndef_message, ndef_message_length, 1, f) != 1)
|
||||
err(EXIT_FAILURE, "Can't write NDEF message");
|
||||
|
||||
fclose (f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
|
||||
* Copyright (C) 2012, Romuald Conty.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -35,18 +35,18 @@
|
|||
|
||||
MifareClassicKey default_keys[40];
|
||||
MifareClassicKey default_keys_int[] = {
|
||||
{ 0xff,0xff,0xff,0xff,0xff,0xff },
|
||||
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 },
|
||||
{ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 },
|
||||
{ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 },
|
||||
{ 0x4d,0x3a,0x99,0xc3,0x51,0xdd },
|
||||
{ 0x1a,0x98,0x2c,0x7e,0x45,0x9a },
|
||||
{ 0xaa,0xbb,0xcc,0xdd,0xee,0xff },
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00 }
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
{ 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 },
|
||||
{ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 },
|
||||
{ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 },
|
||||
{ 0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd },
|
||||
{ 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a },
|
||||
{ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
int format_mifare_classic_1k (FreefareTag tag);
|
||||
int format_mifare_classic_4k (FreefareTag tag);
|
||||
int try_format_sector (FreefareTag tag, MifareClassicSectorNumber sector);
|
||||
int format_mifare_classic_1k(FreefareTag tag);
|
||||
int format_mifare_classic_4k(FreefareTag tag);
|
||||
int try_format_sector(FreefareTag tag, MifareClassicSectorNumber sector);
|
||||
|
||||
static int at_block = 0;
|
||||
static int mod_block = 10;
|
||||
|
|
@ -60,81 +60,81 @@ struct {
|
|||
};
|
||||
|
||||
static void
|
||||
display_progress (void)
|
||||
display_progress(void)
|
||||
{
|
||||
at_block++;
|
||||
if (0 == (at_block % mod_block)) {
|
||||
printf ("%d", at_block);
|
||||
fflush (stdout);
|
||||
printf("%d", at_block);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
printf (".");
|
||||
fflush (stdout);
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
format_mifare_classic_1k (FreefareTag tag)
|
||||
format_mifare_classic_1k(FreefareTag tag)
|
||||
{
|
||||
printf (START_FORMAT_N, 16);
|
||||
printf(START_FORMAT_N, 16);
|
||||
for (int sector = 0; sector < 16; sector++) {
|
||||
if (!try_format_sector (tag, sector))
|
||||
if (!try_format_sector(tag, sector))
|
||||
return 0;
|
||||
}
|
||||
printf (DONE_FORMAT);
|
||||
printf(DONE_FORMAT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
format_mifare_classic_4k (FreefareTag tag)
|
||||
format_mifare_classic_4k(FreefareTag tag)
|
||||
{
|
||||
printf (START_FORMAT_N, 32 + 8);
|
||||
printf(START_FORMAT_N, 32 + 8);
|
||||
for (int sector = 0; sector < (32 + 8); sector++) {
|
||||
if (!try_format_sector (tag, sector))
|
||||
if (!try_format_sector(tag, sector))
|
||||
return 0;
|
||||
}
|
||||
printf (DONE_FORMAT);
|
||||
printf(DONE_FORMAT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
try_format_sector (FreefareTag tag, MifareClassicSectorNumber sector)
|
||||
try_format_sector(FreefareTag tag, MifareClassicSectorNumber sector)
|
||||
{
|
||||
display_progress ();
|
||||
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) {
|
||||
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sector);
|
||||
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) {
|
||||
if (0 == mifare_classic_format_sector (tag, sector)) {
|
||||
mifare_classic_disconnect (tag);
|
||||
display_progress();
|
||||
for (size_t i = 0; i < (sizeof(default_keys) / sizeof(MifareClassicKey)); i++) {
|
||||
MifareClassicBlockNumber block = mifare_classic_sector_last_block(sector);
|
||||
if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_A))) {
|
||||
if (0 == mifare_classic_format_sector(tag, sector)) {
|
||||
mifare_classic_disconnect(tag);
|
||||
return 1;
|
||||
} else if (EIO == errno) {
|
||||
err (EXIT_FAILURE, "sector %d", sector);
|
||||
err(EXIT_FAILURE, "sector %d", sector);
|
||||
}
|
||||
mifare_classic_disconnect (tag);
|
||||
mifare_classic_disconnect(tag);
|
||||
}
|
||||
|
||||
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) {
|
||||
if (0 == mifare_classic_format_sector (tag, sector)) {
|
||||
mifare_classic_disconnect (tag);
|
||||
if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_B))) {
|
||||
if (0 == mifare_classic_format_sector(tag, sector)) {
|
||||
mifare_classic_disconnect(tag);
|
||||
return 1;
|
||||
} else if (EIO == errno) {
|
||||
err (EXIT_FAILURE, "sector %d", sector);
|
||||
err(EXIT_FAILURE, "sector %d", sector);
|
||||
}
|
||||
mifare_classic_disconnect (tag);
|
||||
mifare_classic_disconnect(tag);
|
||||
}
|
||||
}
|
||||
|
||||
warnx ("No known authentication key for sector %d", sector);
|
||||
warnx("No known authentication key for sector %d", sector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-fy] [keyfile]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -f Fast format (only erase MAD)\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf (stderr, " keyfile Use keys from dump in addition to internal default keys\n");
|
||||
fprintf(stderr, "usage: %s [-fy] [keyfile]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -f Fast format (only erase MAD)\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf(stderr, " keyfile Use keys from dump in addition to internal default keys\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -145,47 +145,45 @@ main(int argc, char *argv[])
|
|||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
while ((ch = getopt (argc, argv, "fhy")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "fhy")) != -1) {
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
format_options.fast = true;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
format_options.interactive = false;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
||||
memcpy(default_keys, default_keys_int, sizeof(default_keys_int));
|
||||
|
||||
if ((argc - optind) > 0)
|
||||
{
|
||||
int i, rc;
|
||||
char kbuffer[1024] = {0};
|
||||
memset ( kbuffer, 0, sizeof kbuffer);
|
||||
FILE *fp = fopen(argv[optind], "rb");
|
||||
if (fp == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to open file");
|
||||
for (i = 0; (rc = getc(fp)) != EOF && i < 1024; kbuffer[i++] = rc) { }
|
||||
fclose(fp);
|
||||
if ((argc - optind) > 0) {
|
||||
int i, rc;
|
||||
char kbuffer[1024] = {0};
|
||||
memset(kbuffer, 0, sizeof kbuffer);
|
||||
FILE *fp = fopen(argv[optind], "rb");
|
||||
if (fp == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to open file");
|
||||
for (i = 0; (rc = getc(fp)) != EOF && i < 1024; kbuffer[i++] = rc) { }
|
||||
fclose(fp);
|
||||
|
||||
i = sizeof(default_keys_int) / 6;
|
||||
for(int s = 0; s<16; s++)
|
||||
{
|
||||
int startblock = s * 4;
|
||||
int pos_a = (startblock + 3) * 16;
|
||||
int pos_b = (startblock + 3) * 16 + 10;
|
||||
memcpy((default_keys + i++), kbuffer + pos_a, 6);
|
||||
memcpy((default_keys + i++), kbuffer + pos_b, 6);
|
||||
}
|
||||
i = sizeof(default_keys_int) / 6;
|
||||
for (int s = 0; s < 16; s++) {
|
||||
int startblock = s * 4;
|
||||
int pos_a = (startblock + 3) * 16;
|
||||
int pos_b = (startblock + 3) * 16 + 10;
|
||||
memcpy((default_keys + i++), kbuffer + pos_a, 6);
|
||||
memcpy((default_keys + i++), kbuffer + pos_b, 6);
|
||||
}
|
||||
}
|
||||
|
||||
nfc_connstring devices[8];
|
||||
|
|
@ -193,30 +191,30 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing Mifare Classic tag.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing Mifare Classic tag.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_CLASSIC_1K:
|
||||
case MIFARE_CLASSIC_4K:
|
||||
break;
|
||||
|
|
@ -224,44 +222,44 @@ main(int argc, char *argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
bool format = true;
|
||||
if (format_options.interactive) {
|
||||
printf ("Format [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Format [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (format) {
|
||||
enum freefare_tag_type tt = freefare_get_tag_type (tags[i]);
|
||||
enum freefare_tag_type tt = freefare_get_tag_type(tags[i]);
|
||||
at_block = 0;
|
||||
|
||||
if (format_options.fast) {
|
||||
printf (START_FORMAT_N, (tt == MIFARE_CLASSIC_1K) ? 1 : 2);
|
||||
if (!try_format_sector (tags[i], 0x00))
|
||||
printf(START_FORMAT_N, (tt == MIFARE_CLASSIC_1K) ? 1 : 2);
|
||||
if (!try_format_sector(tags[i], 0x00))
|
||||
break;
|
||||
|
||||
if (tt == MIFARE_CLASSIC_4K)
|
||||
if (!try_format_sector (tags[i], 0x10))
|
||||
if (!try_format_sector(tags[i], 0x10))
|
||||
break;
|
||||
|
||||
printf (DONE_FORMAT);
|
||||
printf(DONE_FORMAT);
|
||||
continue;
|
||||
}
|
||||
switch (tt) {
|
||||
case MIFARE_CLASSIC_1K:
|
||||
mod_block = 4;
|
||||
if (!format_mifare_classic_1k (tags[i]))
|
||||
if (!format_mifare_classic_1k(tags[i]))
|
||||
error = 1;
|
||||
break;
|
||||
case MIFARE_CLASSIC_4K:
|
||||
mod_block = 10;
|
||||
if (!format_mifare_classic_4k (tags[i]))
|
||||
if (!format_mifare_classic_4k(tags[i]))
|
||||
error = 1;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -270,13 +268,13 @@ main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2011, Romain Tartiere, Romuald Conty.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -56,10 +56,10 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s -o FILE\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf (stderr, " -o Extract NDEF message if available in FILE\n");
|
||||
fprintf(stderr, "usage: %s -o FILE\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf(stderr, " -o Extract NDEF message if available in FILE\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -72,11 +72,11 @@ main(int argc, char *argv[])
|
|||
|
||||
int ch;
|
||||
char *ndef_output = NULL;
|
||||
while ((ch = getopt (argc, argv, "hyo:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "hyo:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
read_options.interactive = false;
|
||||
|
|
@ -86,30 +86,30 @@ main(int argc, char *argv[])
|
|||
break;
|
||||
case '?':
|
||||
if (optopt == 'o')
|
||||
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||||
/* FALLTHROUGH */
|
||||
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (ndef_output == NULL) {
|
||||
usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
FILE* message_stream = NULL;
|
||||
FILE* ndef_stream = NULL;
|
||||
FILE *message_stream = NULL;
|
||||
FILE *ndef_stream = NULL;
|
||||
|
||||
if ((strlen (ndef_output) == 1) && (ndef_output[0] == '-')) {
|
||||
if ((strlen(ndef_output) == 1) && (ndef_output[0] == '-')) {
|
||||
message_stream = stderr;
|
||||
ndef_stream = stdout;
|
||||
} else {
|
||||
message_stream = stdout;
|
||||
ndef_stream = fopen(ndef_output, "wb");
|
||||
if (!ndef_stream) {
|
||||
fprintf (stderr, "Could not open file %s.\n", ndef_output);
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "Could not open file %s.\n", ndef_output);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,30 +117,30 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count= nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing MIFARE classic tag.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing MIFARE classic tag.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_CLASSIC_1K:
|
||||
case MIFARE_CLASSIC_4K:
|
||||
break;
|
||||
|
|
@ -148,100 +148,100 @@ main(int argc, char *argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
fprintf (message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
fprintf(message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
|
||||
bool read_ndef = true;
|
||||
if (read_options.interactive) {
|
||||
fprintf (message_stream, "Read NDEF [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
fprintf(message_stream, "Read NDEF [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
fprintf (message_stream, "\n");
|
||||
fprintf(message_stream, "\n");
|
||||
}
|
||||
|
||||
if (read_ndef) {
|
||||
// NFCForum card has a MAD, load it.
|
||||
if (0 == mifare_classic_connect (tags[i])) {
|
||||
if (0 == mifare_classic_connect(tags[i])) {
|
||||
} else {
|
||||
nfc_perror (device, "mifare_classic_connect");
|
||||
nfc_perror(device, "mifare_classic_connect");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((mad = mad_read (tags[i]))) {
|
||||
if ((mad = mad_read(tags[i]))) {
|
||||
// Dump the NFCForum application using MAD information
|
||||
uint8_t buffer[4096];
|
||||
ssize_t len;
|
||||
if ((len = mifare_application_read (tags[i], mad, mad_nfcforum_aid, buffer, sizeof(buffer), mifare_classic_nfcforum_public_key_a, MFC_KEY_A)) != -1) {
|
||||
if ((len = mifare_application_read(tags[i], mad, mad_nfcforum_aid, buffer, sizeof(buffer), mifare_classic_nfcforum_public_key_a, MFC_KEY_A)) != -1) {
|
||||
uint8_t tlv_type;
|
||||
uint16_t tlv_data_len;
|
||||
uint8_t * tlv_data;
|
||||
uint8_t * pbuffer = buffer;
|
||||
uint8_t *tlv_data;
|
||||
uint8_t *pbuffer = buffer;
|
||||
decode_tlv:
|
||||
tlv_data = tlv_decode (pbuffer, &tlv_type, &tlv_data_len);
|
||||
tlv_data = tlv_decode(pbuffer, &tlv_type, &tlv_data_len);
|
||||
switch (tlv_type) {
|
||||
case 0x00:
|
||||
fprintf (message_stream, "NFC Forum application contains a \"NULL TLV\", Skipping...\n"); // According to [ANNFC1K4K], we skip this Tag to read further TLV blocks.
|
||||
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
|
||||
if (pbuffer >= buffer + sizeof(buffer)) {
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
goto decode_tlv;
|
||||
break;
|
||||
case 0x03:
|
||||
fprintf (message_stream, "NFC Forum application contains a \"NDEF Message TLV\".\n");
|
||||
break;
|
||||
case 0xFD:
|
||||
fprintf (message_stream, "NFC Forum application contains a \"Proprietary TLV\", Skipping...\n"); // According to [ANNFC1K4K], we can skip this TLV to read further TLV blocks.
|
||||
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
|
||||
if (pbuffer >= buffer + sizeof(buffer)) {
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
goto decode_tlv;
|
||||
break;
|
||||
case 0xFE:
|
||||
fprintf (stderr, "NFC Forum application contains a \"Terminator TLV\", no available data.\n");
|
||||
case 0x00:
|
||||
fprintf(message_stream, "NFC Forum application contains a \"NULL TLV\", Skipping...\n"); // According to [ANNFC1K4K], we skip this Tag to read further TLV blocks.
|
||||
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
|
||||
if (pbuffer >= buffer + sizeof(buffer)) {
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "NFC Forum application contains an invalid TLV.\n");
|
||||
}
|
||||
goto decode_tlv;
|
||||
break;
|
||||
case 0x03:
|
||||
fprintf(message_stream, "NFC Forum application contains a \"NDEF Message TLV\".\n");
|
||||
break;
|
||||
case 0xFD:
|
||||
fprintf(message_stream, "NFC Forum application contains a \"Proprietary TLV\", Skipping...\n"); // According to [ANNFC1K4K], we can skip this TLV to read further TLV blocks.
|
||||
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
|
||||
if (pbuffer >= buffer + sizeof(buffer)) {
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
goto decode_tlv;
|
||||
break;
|
||||
case 0xFE:
|
||||
fprintf(stderr, "NFC Forum application contains a \"Terminator TLV\", no available data.\n");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "NFC Forum application contains an invalid TLV.\n");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
if (fwrite (tlv_data, 1, tlv_data_len, ndef_stream) != tlv_data_len) {
|
||||
fprintf (stderr, "Could not write to file.\n");
|
||||
if (fwrite(tlv_data, 1, tlv_data_len, ndef_stream) != tlv_data_len) {
|
||||
fprintf(stderr, "Could not write to file.\n");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
free (tlv_data);
|
||||
free(tlv_data);
|
||||
} else {
|
||||
fprintf (stderr, "No NFC Forum application.\n");
|
||||
fprintf(stderr, "No NFC Forum application.\n");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "No MAD detected.\n");
|
||||
fprintf(stderr, "No MAD detected.\n");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
free (mad);
|
||||
free(mad);
|
||||
}
|
||||
|
||||
error:
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
fclose (ndef_stream);
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
fclose(ndef_stream);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -33,14 +33,14 @@
|
|||
#define MIN(a,b) ((a < b) ? a: b)
|
||||
|
||||
MifareClassicKey default_keys[] = {
|
||||
{ 0xff,0xff,0xff,0xff,0xff,0xff },
|
||||
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 },
|
||||
{ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 },
|
||||
{ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 },
|
||||
{ 0x4d,0x3a,0x99,0xc3,0x51,0xdd },
|
||||
{ 0x1a,0x98,0x2c,0x7e,0x45,0x9a },
|
||||
{ 0xaa,0xbb,0xcc,0xdd,0xee,0xff },
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00 }
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
{ 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 },
|
||||
{ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 },
|
||||
{ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 },
|
||||
{ 0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd },
|
||||
{ 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a },
|
||||
{ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
struct mifare_classic_key_and_type {
|
||||
|
|
@ -69,54 +69,54 @@ uint8_t *ndef_msg;
|
|||
size_t ndef_msg_len;
|
||||
|
||||
static int
|
||||
search_sector_key (FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey *key, MifareClassicKeyType *key_type)
|
||||
search_sector_key(FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey *key, MifareClassicKeyType *key_type)
|
||||
{
|
||||
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sector);
|
||||
MifareClassicBlockNumber block = mifare_classic_sector_last_block(sector);
|
||||
|
||||
/*
|
||||
* FIXME: We should not assume that if we have full access to trailer block
|
||||
* we also have a full access to data blocks.
|
||||
*/
|
||||
mifare_classic_disconnect (tag);
|
||||
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) {
|
||||
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) {
|
||||
if ((1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYA, MFC_KEY_A)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYB, MFC_KEY_A))) {
|
||||
memcpy (key, &default_keys[i], sizeof (MifareClassicKey));
|
||||
mifare_classic_disconnect(tag);
|
||||
for (size_t i = 0; i < (sizeof(default_keys) / sizeof(MifareClassicKey)); i++) {
|
||||
if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_A))) {
|
||||
if ((1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYA, MFC_KEY_A)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYB, MFC_KEY_A))) {
|
||||
memcpy(key, &default_keys[i], sizeof(MifareClassicKey));
|
||||
*key_type = MFC_KEY_A;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
mifare_classic_disconnect (tag);
|
||||
mifare_classic_disconnect(tag);
|
||||
|
||||
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) {
|
||||
if ((1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYA, MFC_KEY_B)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYB, MFC_KEY_B))) {
|
||||
memcpy (key, &default_keys[i], sizeof (MifareClassicKey));
|
||||
if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_B))) {
|
||||
if ((1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYA, MFC_KEY_B)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B)) &&
|
||||
(1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYB, MFC_KEY_B))) {
|
||||
memcpy(key, &default_keys[i], sizeof(MifareClassicKey));
|
||||
*key_type = MFC_KEY_B;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
mifare_classic_disconnect (tag);
|
||||
mifare_classic_disconnect(tag);
|
||||
}
|
||||
|
||||
warnx ("No known authentication key for sector 0x%02x\n", sector);
|
||||
warnx("No known authentication key for sector 0x%02x\n", sector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
fix_mad_trailer_block (nfc_device *device, FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey key, MifareClassicKeyType key_type)
|
||||
fix_mad_trailer_block(nfc_device *device, FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey key, MifareClassicKeyType key_type)
|
||||
{
|
||||
MifareClassicBlock block;
|
||||
mifare_classic_trailer_block (&block, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, default_keyb);
|
||||
if (mifare_classic_authenticate (tag, mifare_classic_sector_last_block (sector), key, key_type) < 0) {
|
||||
nfc_perror (device, "fix_mad_trailer_block mifare_classic_authenticate");
|
||||
mifare_classic_trailer_block(&block, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, default_keyb);
|
||||
if (mifare_classic_authenticate(tag, mifare_classic_sector_last_block(sector), key, key_type) < 0) {
|
||||
nfc_perror(device, "fix_mad_trailer_block mifare_classic_authenticate");
|
||||
return -1;
|
||||
}
|
||||
if (mifare_classic_write (tag, mifare_classic_sector_last_block (sector), block) < 0) {
|
||||
nfc_perror (device, "mifare_classic_write");
|
||||
if (mifare_classic_write(tag, mifare_classic_sector_last_block(sector), block) < 0) {
|
||||
nfc_perror(device, "mifare_classic_write");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -125,10 +125,10 @@ fix_mad_trailer_block (nfc_device *device, FreefareTag tag, MifareClassicSectorN
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s -i FILE\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf (stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
|
||||
fprintf(stderr, "usage: %s -i FILE\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf(stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -142,11 +142,11 @@ main(int argc, char *argv[])
|
|||
|
||||
int ch;
|
||||
char *ndef_input = NULL;
|
||||
while ((ch = getopt (argc, argv, "hyi:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "hyi:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
write_options.interactive = false;
|
||||
|
|
@ -156,81 +156,81 @@ main(int argc, char *argv[])
|
|||
break;
|
||||
case '?':
|
||||
if (optopt == 'i')
|
||||
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||||
/* FALLTHROUGH */
|
||||
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (ndef_input == NULL) {
|
||||
ndef_msg = (uint8_t*)ndef_default_msg;
|
||||
ndef_msg_len = sizeof(ndef_default_msg);
|
||||
ndef_msg = (uint8_t *)ndef_default_msg;
|
||||
ndef_msg_len = sizeof(ndef_default_msg);
|
||||
} else {
|
||||
FILE* ndef_stream = NULL;
|
||||
if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) {
|
||||
// FIXME stdin as input have to be readed and buffered in ndef_msg
|
||||
FILE *ndef_stream = NULL;
|
||||
if ((strlen(ndef_input) == 1) && (ndef_input[0] == '-')) {
|
||||
// FIXME stdin as input have to be readed and buffered in ndef_msg
|
||||
ndef_stream = stdin;
|
||||
fprintf (stderr, "stdin as NDEF is not implemented");
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "stdin as NDEF is not implemented");
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
ndef_stream = fopen(ndef_input, "rb");
|
||||
if (!ndef_stream) {
|
||||
fprintf (stderr, "Could not open file %s.\n", ndef_input);
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "Could not open file %s.\n", ndef_input);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fseek(ndef_stream, 0L, SEEK_END);
|
||||
ndef_msg_len = ftell(ndef_stream);
|
||||
fseek(ndef_stream, 0L, SEEK_SET);
|
||||
fseek(ndef_stream, 0L, SEEK_SET);
|
||||
|
||||
if (!(ndef_msg = malloc (ndef_msg_len))) {
|
||||
err (EXIT_FAILURE, "malloc");
|
||||
if (!(ndef_msg = malloc(ndef_msg_len))) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
if (fread (ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len) {
|
||||
fprintf (stderr, "Could not read NDEF from file: %s\n", ndef_input);
|
||||
fclose (ndef_stream);
|
||||
free (ndef_msg);
|
||||
exit (EXIT_FAILURE);
|
||||
if (fread(ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len) {
|
||||
fprintf(stderr, "Could not read NDEF from file: %s\n", ndef_input);
|
||||
fclose(ndef_stream);
|
||||
free(ndef_msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose (ndef_stream);
|
||||
fclose(ndef_stream);
|
||||
}
|
||||
}
|
||||
printf ("NDEF file is %zu bytes long.\n", ndef_msg_len);
|
||||
printf("NDEF file is %zu bytes long.\n", ndef_msg_len);
|
||||
|
||||
struct mifare_classic_key_and_type *card_write_keys;
|
||||
if (!(card_write_keys = malloc (40 * sizeof (*card_write_keys)))) {
|
||||
err (EXIT_FAILURE, "malloc");
|
||||
if (!(card_write_keys = malloc(40 * sizeof(*card_write_keys)))) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
|
||||
nfc_connstring devices[8];
|
||||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing MIFARE classic tag.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing MIFARE classic tag.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_CLASSIC_1K:
|
||||
case MIFARE_CLASSIC_4K:
|
||||
break;
|
||||
|
|
@ -238,35 +238,35 @@ main(int argc, char *argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
|
||||
bool write_ndef = true;
|
||||
if (write_options.interactive) {
|
||||
printf ("Write NDEF [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Write NDEF [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
for (int n = 0; n < 40; n++) {
|
||||
memcpy(card_write_keys[n].key, transport_key, sizeof (transport_key));
|
||||
memcpy(card_write_keys[n].key, transport_key, sizeof(transport_key));
|
||||
card_write_keys[n].type = MFC_KEY_A;
|
||||
}
|
||||
|
||||
if (write_ndef) {
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_CLASSIC_4K:
|
||||
if (!search_sector_key (tags[i], 0x10, &(card_write_keys[0x10].key), &(card_write_keys[0x10].type))) {
|
||||
if (!search_sector_key(tags[i], 0x10, &(card_write_keys[0x10].key), &(card_write_keys[0x10].type))) {
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
/* fallthrough */
|
||||
/* fallthrough */
|
||||
case MIFARE_CLASSIC_1K:
|
||||
if (!search_sector_key (tags[i], 0x00, &(card_write_keys[0x00].key), &(card_write_keys[0x00].type))) {
|
||||
if (!search_sector_key(tags[i], 0x00, &(card_write_keys[0x00].key), &(card_write_keys[0x00].type))) {
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -278,24 +278,24 @@ main(int argc, char *argv[])
|
|||
|
||||
if (!error) {
|
||||
/* Ensure the auth key is always a B one. If not, change it! */
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_CLASSIC_4K:
|
||||
if (card_write_keys[0x10].type != MFC_KEY_B) {
|
||||
if( 0 != fix_mad_trailer_block (device, tags[i], 0x10, card_write_keys[0x10].key, card_write_keys[0x10].type)) {
|
||||
if (0 != fix_mad_trailer_block(device, tags[i], 0x10, card_write_keys[0x10].key, card_write_keys[0x10].type)) {
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
memcpy (&(card_write_keys[0x10].key), &default_keyb, sizeof (MifareClassicKey));
|
||||
memcpy(&(card_write_keys[0x10].key), &default_keyb, sizeof(MifareClassicKey));
|
||||
card_write_keys[0x10].type = MFC_KEY_B;
|
||||
}
|
||||
/* fallthrough */
|
||||
/* fallthrough */
|
||||
case MIFARE_CLASSIC_1K:
|
||||
if (card_write_keys[0x00].type != MFC_KEY_B) {
|
||||
if( 0 != fix_mad_trailer_block (device, tags[i], 0x00, card_write_keys[0x00].key, card_write_keys[0x00].type)) {
|
||||
if (0 != fix_mad_trailer_block(device, tags[i], 0x00, card_write_keys[0x00].key, card_write_keys[0x00].type)) {
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
memcpy (&(card_write_keys[0x00].key), &default_keyb, sizeof (MifareClassicKey));
|
||||
memcpy(&(card_write_keys[0x00].key), &default_keyb, sizeof(MifareClassicKey));
|
||||
card_write_keys[0x00].type = MFC_KEY_B;
|
||||
}
|
||||
break;
|
||||
|
|
@ -306,7 +306,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
size_t encoded_size;
|
||||
uint8_t *tlv_data = tlv_encode (3, ndef_msg, ndef_msg_len, &encoded_size);
|
||||
uint8_t *tlv_data = tlv_encode(3, ndef_msg, ndef_msg_len, &encoded_size);
|
||||
|
||||
/*
|
||||
* At his point, we should have collected all information needed to
|
||||
|
|
@ -314,38 +314,38 @@ main(int argc, char *argv[])
|
|||
*/
|
||||
|
||||
// If the card already has a MAD, load it.
|
||||
if ((mad = mad_read (tags[i]))) {
|
||||
if ((mad = mad_read(tags[i]))) {
|
||||
// If our application already exists, erase it.
|
||||
MifareClassicSectorNumber *sectors, *p;
|
||||
sectors = p = mifare_application_find (mad, mad_nfcforum_aid);
|
||||
sectors = p = mifare_application_find(mad, mad_nfcforum_aid);
|
||||
if (sectors) {
|
||||
while (*p) {
|
||||
if (mifare_classic_authenticate (tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
|
||||
nfc_perror (device, "mifare_classic_authenticate");
|
||||
if (mifare_classic_authenticate(tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
|
||||
nfc_perror(device, "mifare_classic_authenticate");
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
if (mifare_classic_format_sector (tags[i], *p) < 0) {
|
||||
nfc_perror (device, "mifare_classic_format_sector");
|
||||
if (mifare_classic_format_sector(tags[i], *p) < 0) {
|
||||
nfc_perror(device, "mifare_classic_format_sector");
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
free (sectors);
|
||||
mifare_application_free (mad, mad_nfcforum_aid);
|
||||
free(sectors);
|
||||
mifare_application_free(mad, mad_nfcforum_aid);
|
||||
} else {
|
||||
|
||||
// Create a MAD and mark unaccessible sectors in the card
|
||||
if (!(mad = mad_new ((freefare_get_tag_type (tags[i]) == MIFARE_CLASSIC_4K) ? 2 : 1))) {
|
||||
perror ("mad_new");
|
||||
if (!(mad = mad_new((freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_4K) ? 2 : 1))) {
|
||||
perror("mad_new");
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
MifareClassicSectorNumber max_s = 0;
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_CLASSIC_1K:
|
||||
max_s = 15;
|
||||
break;
|
||||
|
|
@ -360,13 +360,13 @@ main(int argc, char *argv[])
|
|||
// Mark unusable sectors as so
|
||||
for (size_t s = max_s; s; s--) {
|
||||
if (s == 0x10) continue;
|
||||
if (!search_sector_key (tags[i], s, &(card_write_keys[s].key), &(card_write_keys[s].type))) {
|
||||
mad_set_aid (mad, s, mad_defect_aid);
|
||||
} else if ((memcmp (card_write_keys[s].key, transport_key, sizeof (transport_key)) != 0) &&
|
||||
if (!search_sector_key(tags[i], s, &(card_write_keys[s].key), &(card_write_keys[s].type))) {
|
||||
mad_set_aid(mad, s, mad_defect_aid);
|
||||
} else if ((memcmp(card_write_keys[s].key, transport_key, sizeof(transport_key)) != 0) &&
|
||||
(card_write_keys[s].type != MFC_KEY_A)) {
|
||||
// Revert to transport configuration
|
||||
if (mifare_classic_format_sector (tags[i], s) < 0) {
|
||||
nfc_perror (device, "mifare_classic_format_sector");
|
||||
if (mifare_classic_format_sector(tags[i], s) < 0) {
|
||||
nfc_perror(device, "mifare_classic_format_sector");
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -374,61 +374,61 @@ main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, mad_nfcforum_aid, encoded_size);
|
||||
MifareClassicSectorNumber *sectors = mifare_application_alloc(mad, mad_nfcforum_aid, encoded_size);
|
||||
if (!sectors) {
|
||||
nfc_perror (device, "mifare_application_alloc");
|
||||
nfc_perror(device, "mifare_application_alloc");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mad_write (tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
|
||||
nfc_perror (device, "mad_write");
|
||||
if (mad_write(tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
|
||||
nfc_perror(device, "mad_write");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
int s = 0;
|
||||
while (sectors[s]) {
|
||||
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sectors[s]);
|
||||
MifareClassicBlockNumber block = mifare_classic_sector_last_block(sectors[s]);
|
||||
MifareClassicBlock block_data;
|
||||
mifare_classic_trailer_block (&block_data, mifare_classic_nfcforum_public_key_a, 0x0, 0x0, 0x0, 0x6, 0x40, default_keyb);
|
||||
if (mifare_classic_authenticate (tags[i], block, card_write_keys[sectors[s]].key, card_write_keys[sectors[s]].type) < 0) {
|
||||
nfc_perror (device, "mifare_classic_authenticate");
|
||||
mifare_classic_trailer_block(&block_data, mifare_classic_nfcforum_public_key_a, 0x0, 0x0, 0x0, 0x6, 0x40, default_keyb);
|
||||
if (mifare_classic_authenticate(tags[i], block, card_write_keys[sectors[s]].key, card_write_keys[sectors[s]].type) < 0) {
|
||||
nfc_perror(device, "mifare_classic_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
if (mifare_classic_write (tags[i], block, block_data) < 0) {
|
||||
nfc_perror (device, "mifare_classic_write");
|
||||
if (mifare_classic_write(tags[i], block, block_data) < 0) {
|
||||
nfc_perror(device, "mifare_classic_write");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
if ((ssize_t) encoded_size != mifare_application_write (tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) {
|
||||
nfc_perror (device, "mifare_application_write");
|
||||
if ((ssize_t) encoded_size != mifare_application_write(tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) {
|
||||
nfc_perror(device, "mifare_application_write");
|
||||
error = EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
free (sectors);
|
||||
free(sectors);
|
||||
|
||||
free (tlv_data);
|
||||
free(tlv_data);
|
||||
|
||||
free (mad);
|
||||
free(mad);
|
||||
}
|
||||
|
||||
error:
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
if (ndef_msg != ndef_default_msg)
|
||||
free (ndef_msg);
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
free(ndef_msg);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
|
||||
free (card_write_keys);
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
free(card_write_keys);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -34,105 +34,105 @@ main(int argc, char *argv[])
|
|||
FreefareTag *tags = NULL;
|
||||
|
||||
if (argc > 1)
|
||||
errx (EXIT_FAILURE, "usage: %s", argv[0]);
|
||||
errx(EXIT_FAILURE, "usage: %s", argv[0]);
|
||||
|
||||
nfc_connstring devices[8];
|
||||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
int res;
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
MifareDESFireKey key = mifare_desfire_des_key_new_with_version (key_data_null);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key);
|
||||
MifareDESFireKey key = mifare_desfire_des_key_new_with_version(key_data_null);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication on master application failed");
|
||||
errx(EXIT_FAILURE, "Authentication on master application failed");
|
||||
|
||||
MadAid mad_aid = { 0x12, 0x34 };
|
||||
MifareDESFireAID aid = mifare_desfire_aid_new_with_mad_aid (mad_aid, 0x5);
|
||||
res = mifare_desfire_create_application (tags[i], aid, 0xFF, 0x1);
|
||||
MifareDESFireAID aid = mifare_desfire_aid_new_with_mad_aid(mad_aid, 0x5);
|
||||
res = mifare_desfire_create_application(tags[i], aid, 0xFF, 0x1);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application creation failed");
|
||||
errx(EXIT_FAILURE, "Application creation failed");
|
||||
|
||||
res = mifare_desfire_select_application (tags[i], aid);
|
||||
res = mifare_desfire_select_application(tags[i], aid);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application selection failed");
|
||||
errx(EXIT_FAILURE, "Application selection failed");
|
||||
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication on application failed");
|
||||
errx(EXIT_FAILURE, "Authentication on application failed");
|
||||
|
||||
res = mifare_desfire_create_std_data_file (tags[i], 1, MDCM_ENCIPHERED, 0x0000, 20);
|
||||
res = mifare_desfire_create_std_data_file(tags[i], 1, MDCM_ENCIPHERED, 0x0000, 20);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "File creation failed");
|
||||
errx(EXIT_FAILURE, "File creation failed");
|
||||
|
||||
const char *s= "Hello World";
|
||||
res = mifare_desfire_write_data (tags[i], 1, 0, strlen (s), s);
|
||||
const char *s = "Hello World";
|
||||
res = mifare_desfire_write_data(tags[i], 1, 0, strlen(s), s);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "File write failed");
|
||||
errx(EXIT_FAILURE, "File write failed");
|
||||
|
||||
char buffer[20];
|
||||
res = mifare_desfire_read_data (tags[i], 1, 0, 0, buffer);
|
||||
res = mifare_desfire_read_data(tags[i], 1, 0, 0, buffer);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "File read failed");
|
||||
errx(EXIT_FAILURE, "File read failed");
|
||||
|
||||
res = mifare_desfire_select_application (tags[i], NULL);
|
||||
res = mifare_desfire_select_application(tags[i], NULL);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Master application selection failed");
|
||||
errx(EXIT_FAILURE, "Master application selection failed");
|
||||
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication on master application failed");
|
||||
errx(EXIT_FAILURE, "Authentication on master application failed");
|
||||
|
||||
res = mifare_desfire_format_picc (tags[i]);
|
||||
res = mifare_desfire_format_picc(tags[i]);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "PICC format failed");
|
||||
errx(EXIT_FAILURE, "PICC format failed");
|
||||
|
||||
mifare_desfire_key_free (key);
|
||||
free (tag_uid);
|
||||
free (aid);
|
||||
mifare_desfire_key_free(key);
|
||||
free(tag_uid);
|
||||
free(aid);
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
} /* main() */
|
||||
|
||||
|
|
|
|||
|
|
@ -50,11 +50,11 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "This application turns Mifare DESFire targets into NFC Forum Type 4 Tags.\n");
|
||||
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf (stderr, " -K Provide another PICC key than the default one\n");
|
||||
fprintf(stderr, "This application turns Mifare DESFire targets into NFC Forum Type 4 Tags.\n");
|
||||
fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf(stderr, " -K Provide another PICC key than the default one\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -65,31 +65,31 @@ main(int argc, char *argv[])
|
|||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
create_options.interactive = false;
|
||||
break;
|
||||
case 'K':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i=7; i>=0; i--) {
|
||||
key_data_picc[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
create_options.interactive = false;
|
||||
break;
|
||||
case 'K':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
key_data_picc[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
||||
|
|
@ -97,54 +97,54 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
device = nfc_open(context, devices[d]);
|
||||
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
// We've to track DESFire version as NDEF mapping is different
|
||||
struct mifare_desfire_version_info info;
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("Found %s with UID %s and software v%d.%d\n", freefare_get_tag_friendly_name (tags[i]), tag_uid, info.software.version_major, info.software.version_minor);
|
||||
printf("Found %s with UID %s and software v%d.%d\n", freefare_get_tag_friendly_name(tags[i]), tag_uid, info.software.version_major, info.software.version_minor);
|
||||
bool create_ndef = true;
|
||||
int ndef_mapping;
|
||||
switch (info.software.version_major) {
|
||||
|
|
@ -159,11 +159,11 @@ main(int argc, char *argv[])
|
|||
ndef_mapping = 2;
|
||||
}
|
||||
if (create_options.interactive) {
|
||||
printf ("Create NDEF app v%d [yN] ", ndef_mapping);
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Create NDEF app v%d [yN] ", ndef_mapping);
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
create_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (create_ndef) {
|
||||
|
|
@ -172,24 +172,24 @@ main(int argc, char *argv[])
|
|||
// Send Mifare DESFire Select Application with AID equal to 000000h to select the PICC level
|
||||
res = mifare_desfire_select_application(tags[i], NULL);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application selection failed");
|
||||
errx(EXIT_FAILURE, "Application selection failed");
|
||||
|
||||
MifareDESFireKey key_picc;
|
||||
MifareDESFireKey key_app;
|
||||
key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
|
||||
key_app = mifare_desfire_des_key_new_with_version (key_data_app);
|
||||
key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
|
||||
key_app = mifare_desfire_des_key_new_with_version(key_data_app);
|
||||
|
||||
// Authentication with PICC master key MAY be needed to issue ChangeKeySettings command
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication with PICC master key failed");
|
||||
errx(EXIT_FAILURE, "Authentication with PICC master key failed");
|
||||
|
||||
MifareDESFireAID aid;
|
||||
if (ndef_mapping == 1) {
|
||||
uint8_t key_settings;
|
||||
uint8_t max_keys;
|
||||
mifare_desfire_get_key_settings(tags[i], &key_settings,&max_keys);
|
||||
if ((key_settings & 0x08) == 0x08){
|
||||
mifare_desfire_get_key_settings(tags[i], &key_settings, &max_keys);
|
||||
if ((key_settings & 0x08) == 0x08) {
|
||||
|
||||
// Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into :
|
||||
// bit7-bit4 equal to 0000b
|
||||
|
|
@ -197,33 +197,33 @@ main(int argc, char *argv[])
|
|||
// bit2 equal to 0b, CreateApplication and DeleteApplication commands are allowed with PICC master key authentication
|
||||
// bit1 equal to 0b, GetApplicationIDs, and GetKeySettings are allowed with PICC master key authentication
|
||||
// bit0 equal to Xb, PICC masterkey MAY be frozen or changeable
|
||||
res = mifare_desfire_change_key_settings (tags[i],0x09);
|
||||
res = mifare_desfire_change_key_settings(tags[i], 0x09);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "ChangeKeySettings failed");
|
||||
errx(EXIT_FAILURE, "ChangeKeySettings failed");
|
||||
}
|
||||
// Mifare DESFire Create Application with AID equal to EEEE10h, key settings equal to 0x09, NumOfKeys equal to 01h
|
||||
aid = mifare_desfire_aid_new(0xEEEE10);
|
||||
res = mifare_desfire_create_application (tags[i], aid, 0x09, 1);
|
||||
res = mifare_desfire_create_application(tags[i], aid, 0x09, 1);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]);
|
||||
errx(EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]);
|
||||
// Mifare DESFire SelectApplication (Select previously creates application)
|
||||
res = mifare_desfire_select_application(tags[i], aid);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application selection failed");
|
||||
free (aid);
|
||||
errx(EXIT_FAILURE, "Application selection failed");
|
||||
free(aid);
|
||||
// Authentication with NDEF Tag Application master key (Authentication with key 0)
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_app);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_app);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
// Mifare DESFire ChangeKeySetting with key settings equal to 00001001b
|
||||
res = mifare_desfire_change_key_settings (tags[i],0x09);
|
||||
res = mifare_desfire_change_key_settings(tags[i], 0x09);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "ChangeKeySettings failed");
|
||||
errx(EXIT_FAILURE, "ChangeKeySettings failed");
|
||||
// Mifare DESFire CreateStdDataFile with FileNo equal to 03h (CC File DESFire FID), ComSet equal to 00h,
|
||||
// AccesRights equal to E000h, File Size bigger equal to 00000Fh
|
||||
res = mifare_desfire_create_std_data_file(tags[i],0x03,MDCM_PLAIN,0xE000,0x00000F);
|
||||
res = mifare_desfire_create_std_data_file(tags[i], 0x03, MDCM_PLAIN, 0xE000, 0x00000F);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "CreateStdDataFile failed");
|
||||
errx(EXIT_FAILURE, "CreateStdDataFile failed");
|
||||
// Mifare DESFire WriteData to write the content of the CC File with CClEN equal to 000Fh,
|
||||
// Mapping Version equal to 10h,MLe equal to 003Bh, MLc equal to 0034h, and NDEF File Control TLV
|
||||
// equal to T =04h, L=06h, V=E1 04 (NDEF ISO FID=E104h) 0E E0 (NDEF File size =3808 Bytes) 00 (free read access)
|
||||
|
|
@ -239,39 +239,38 @@ main(int argc, char *argv[])
|
|||
0x00, // free read access
|
||||
0x00 // free write acces
|
||||
};
|
||||
res = mifare_desfire_write_data(tags[i],0x03,0,sizeof(capability_container_file_content),capability_container_file_content);
|
||||
if (res>0){
|
||||
res = mifare_desfire_write_data(tags[i], 0x03, 0, sizeof(capability_container_file_content), capability_container_file_content);
|
||||
if (res > 0) {
|
||||
// Mifare DESFire CreateStdDataFile with FileNo equal to 04h (NDEF FileDESFire FID), CmmSet equal to 00h, AccessRigths
|
||||
// equal to EEE0h, FileSize equal to 000EE0h (3808 Bytes)
|
||||
res = mifare_desfire_create_std_data_file(tags[i],0x04,MDCM_PLAIN,0xEEE0,0x000EE0);
|
||||
res = mifare_desfire_create_std_data_file(tags[i], 0x04, MDCM_PLAIN, 0xEEE0, 0x000EE0);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "CreateStdDataFile failed");
|
||||
errx(EXIT_FAILURE, "CreateStdDataFile failed");
|
||||
} else {
|
||||
errx (EXIT_FAILURE, "Write CC file content failed");
|
||||
errx(EXIT_FAILURE, "Write CC file content failed");
|
||||
}
|
||||
}
|
||||
else if (ndef_mapping == 2) {
|
||||
} else if (ndef_mapping == 2) {
|
||||
// Mifare DESFire Create Application with AID equal to 000001h, key settings equal to 0x0F, NumOfKeys equal to 01h,
|
||||
// 2 bytes File Identifiers supported, File-ID equal to E110h
|
||||
aid = mifare_desfire_aid_new(0x000001);
|
||||
uint8_t app[] = {0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
|
||||
res = mifare_desfire_create_application_iso (tags[i], aid, 0x0F, 0x21, 0, 0xE110, app, sizeof (app));
|
||||
res = mifare_desfire_create_application_iso(tags[i], aid, 0x0F, 0x21, 0, 0xE110, app, sizeof(app));
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]);
|
||||
errx(EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]);
|
||||
// Mifare DESFire SelectApplication (Select previously creates application)
|
||||
res = mifare_desfire_select_application(tags[i], aid);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application selection failed");
|
||||
free (aid);
|
||||
errx(EXIT_FAILURE, "Application selection failed");
|
||||
free(aid);
|
||||
// Authentication with NDEF Tag Application master key (Authentication with key 0)
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_app);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_app);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
// Mifare DESFire CreateStdDataFile with FileNo equal to 01h (DESFire FID), ComSet equal to 00h,
|
||||
// AccesRights equal to E000h, File Size bigger equal to 00000Fh, ISO File ID equal to E103h
|
||||
res = mifare_desfire_create_std_data_file_iso(tags[i],0x01,MDCM_PLAIN,0xE000,0x00000F,0xE103);
|
||||
res = mifare_desfire_create_std_data_file_iso(tags[i], 0x01, MDCM_PLAIN, 0xE000, 0x00000F, 0xE103);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "CreateStdDataFileIso failed");
|
||||
errx(EXIT_FAILURE, "CreateStdDataFileIso failed");
|
||||
// Mifare DESFire WriteData to write the content of the CC File with CClEN equal to 000Fh,
|
||||
// Mapping Version equal to 20h,MLe equal to 003Bh, MLc equal to 0034h, and NDEF File Control TLV
|
||||
// equal to T =04h, L=06h, V=E1 04 (NDEF ISO FID=E104h) 0xNNNN (NDEF File size = 0x0800/0x1000/0x1E00 bytes)
|
||||
|
|
@ -295,26 +294,26 @@ main(int argc, char *argv[])
|
|||
ndefmaxsize = 0x1E00;
|
||||
capability_container_file_content[11] = ndefmaxsize >> 8;
|
||||
capability_container_file_content[12] = ndefmaxsize & 0xFF;
|
||||
res = mifare_desfire_write_data(tags[i],0x01,0,sizeof(capability_container_file_content),capability_container_file_content);
|
||||
if (res>0){
|
||||
res = mifare_desfire_write_data(tags[i], 0x01, 0, sizeof(capability_container_file_content), capability_container_file_content);
|
||||
if (res > 0) {
|
||||
// Mifare DESFire CreateStdDataFile with FileNo equal to 02h (DESFire FID), CmmSet equal to 00h, AccessRigths
|
||||
// equal to EEE0h, FileSize equal to ndefmaxsize (0x000800, 0x001000 or 0x001E00)
|
||||
res = mifare_desfire_create_std_data_file_iso(tags[i],0x02,MDCM_PLAIN,0xEEE0,ndefmaxsize, 0xE104);
|
||||
res = mifare_desfire_create_std_data_file_iso(tags[i], 0x02, MDCM_PLAIN, 0xEEE0, ndefmaxsize, 0xE104);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "CreateStdDataFileIso failed");
|
||||
errx(EXIT_FAILURE, "CreateStdDataFileIso failed");
|
||||
} else {
|
||||
errx (EXIT_FAILURE, "Write CC file content failed");
|
||||
errx(EXIT_FAILURE, "Write CC file content failed");
|
||||
}
|
||||
}
|
||||
mifare_desfire_key_free (key_picc);
|
||||
mifare_desfire_key_free (key_app);
|
||||
mifare_desfire_key_free(key_picc);
|
||||
mifare_desfire_key_free(key_app);
|
||||
}
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
free (tag_uid);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
free(tag_uid);
|
||||
}
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -44,10 +44,10 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf (stderr, " -K Provide another PICC key than the default one\n");
|
||||
fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf(stderr, " -K Provide another PICC key than the default one\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -58,11 +58,11 @@ main(int argc, char *argv[])
|
|||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
configure_options.interactive = false;
|
||||
|
|
@ -70,18 +70,18 @@ main(int argc, char *argv[])
|
|||
case 'K':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i=7; i>=0; i--) {
|
||||
for (i = 7; i >= 0; i--) {
|
||||
key_data_picc[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
|
@ -90,94 +90,94 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; (!error) && (d < device_count); d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure we've at least an EV1 version
|
||||
struct mifare_desfire_version_info info;
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (info.software.version_major < 1) {
|
||||
warnx ("Found old DESFire, skipping");
|
||||
warnx("Found old DESFire, skipping");
|
||||
continue;
|
||||
}
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
bool do_it = true;
|
||||
|
||||
if (configure_options.interactive) {
|
||||
printf ("Change ATS? [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Change ATS? [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (do_it) {
|
||||
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_authenticate");
|
||||
freefare_perror(tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
mifare_desfire_key_free (key_picc);
|
||||
mifare_desfire_key_free(key_picc);
|
||||
|
||||
res = mifare_desfire_set_ats (tags[i], new_ats);
|
||||
res = mifare_desfire_set_ats(tags[i], new_ats);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_set_ats");
|
||||
freefare_perror(tags[i], "mifare_desfire_set_ats");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
free (tag_uid);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
} /* main() */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -43,9 +43,9 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-y]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf(stderr, "usage: %s [-y]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -56,18 +56,18 @@ main(int argc, char *argv[])
|
|||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
while ((ch = getopt (argc, argv, "hy")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "hy")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
configure_options.interactive = false;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
|
@ -76,85 +76,85 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; (!error) && (d < device_count); d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure we've at least an EV1 version
|
||||
struct mifare_desfire_version_info info;
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (info.software.version_major < 1) {
|
||||
warnx ("Found old DESFire, skipping");
|
||||
warnx("Found old DESFire, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
bool do_it = true;
|
||||
|
||||
if (configure_options.interactive) {
|
||||
printf ("Change default key? [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Change default key? [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (do_it) {
|
||||
|
||||
MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version (null_key_data);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, default_key);
|
||||
MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version(null_key_data);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, default_key);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_authenticate");
|
||||
freefare_perror(tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
mifare_desfire_key_free (default_key);
|
||||
mifare_desfire_key_free(default_key);
|
||||
|
||||
MifareDESFireKey new_key = mifare_desfire_des_key_new (new_key_data);
|
||||
mifare_desfire_key_set_version (new_key, NEW_KEY_VERSION);
|
||||
res = mifare_desfire_set_default_key (tags[i], new_key);
|
||||
free (new_key);
|
||||
MifareDESFireKey new_key = mifare_desfire_des_key_new(new_key_data);
|
||||
mifare_desfire_key_set_version(new_key, NEW_KEY_VERSION);
|
||||
res = mifare_desfire_set_default_key(tags[i], new_key);
|
||||
free(new_key);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_set_default_key");
|
||||
freefare_perror(tags[i], "mifare_desfire_set_default_key");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -164,92 +164,92 @@ main(int argc, char *argv[])
|
|||
* (it's hard to create a unit-test to do so).
|
||||
*/
|
||||
|
||||
MifareDESFireAID aid = mifare_desfire_aid_new (0x112233);
|
||||
res = mifare_desfire_create_application (tags[i], aid, 0xFF, 1);
|
||||
MifareDESFireAID aid = mifare_desfire_aid_new(0x112233);
|
||||
res = mifare_desfire_create_application(tags[i], aid, 0xFF, 1);
|
||||
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_create_application");
|
||||
freefare_perror(tags[i], "mifare_desfire_create_application");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
res = mifare_desfire_select_application (tags[i], aid);
|
||||
res = mifare_desfire_select_application(tags[i], aid);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_select_application");
|
||||
freefare_perror(tags[i], "mifare_desfire_select_application");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t version;
|
||||
res = mifare_desfire_get_key_version (tags[i], 0, &version);
|
||||
res = mifare_desfire_get_key_version(tags[i], 0, &version);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_key_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_key_version");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (version != NEW_KEY_VERSION) {
|
||||
fprintf (stderr, "Wrong key version: %02x (expected %02x).\n", version, NEW_KEY_VERSION);
|
||||
fprintf(stderr, "Wrong key version: %02x (expected %02x).\n", version, NEW_KEY_VERSION);
|
||||
error = EXIT_FAILURE;
|
||||
/* continue */
|
||||
}
|
||||
|
||||
new_key = mifare_desfire_des_key_new (new_key_data);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, new_key);
|
||||
free (new_key);
|
||||
new_key = mifare_desfire_des_key_new(new_key_data);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, new_key);
|
||||
free(new_key);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_authenticate");
|
||||
freefare_perror(tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
free (aid);
|
||||
free(aid);
|
||||
|
||||
/* Resetdefault settings */
|
||||
|
||||
res = mifare_desfire_select_application (tags[i], NULL);
|
||||
res = mifare_desfire_select_application(tags[i], NULL);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_select_application");
|
||||
freefare_perror(tags[i], "mifare_desfire_select_application");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
default_key = mifare_desfire_des_key_new (null_key_data);
|
||||
default_key = mifare_desfire_des_key_new(null_key_data);
|
||||
|
||||
res = mifare_desfire_authenticate (tags[i], 0, default_key);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, default_key);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_authenticate");
|
||||
freefare_perror(tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
res = mifare_desfire_set_default_key (tags[i], default_key);
|
||||
res = mifare_desfire_set_default_key(tags[i], default_key);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_set_default_key");
|
||||
freefare_perror(tags[i], "mifare_desfire_set_default_key");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
mifare_desfire_key_free (default_key);
|
||||
mifare_desfire_key_free(default_key);
|
||||
|
||||
/* Wipeout the card */
|
||||
|
||||
res = mifare_desfire_format_picc (tags[i]);
|
||||
res = mifare_desfire_format_picc(tags[i]);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_format_picc");
|
||||
freefare_perror(tags[i], "mifare_desfire_format_picc");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
free (tag_uid);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -40,10 +40,10 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf (stderr, " -K Provide another PICC key than the default one\n");
|
||||
fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf(stderr, " -K Provide another PICC key than the default one\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -54,11 +54,11 @@ main(int argc, char *argv[])
|
|||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
configure_options.interactive = false;
|
||||
|
|
@ -66,18 +66,18 @@ main(int argc, char *argv[])
|
|||
case 'K':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i=7; i>=0; i--) {
|
||||
for (i = 7; i >= 0; i--) {
|
||||
key_data_picc[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
|
@ -86,127 +86,127 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; (!error) && (d < device_count); d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure we've at least an EV1 version
|
||||
struct mifare_desfire_version_info info;
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (info.software.version_major < 1) {
|
||||
warnx ("Found old DESFire, skipping");
|
||||
warnx("Found old DESFire, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
bool do_it = true;
|
||||
|
||||
size_t tag_uid_len = strlen (tag_uid) / 2;
|
||||
size_t tag_uid_len = strlen(tag_uid) / 2;
|
||||
switch (tag_uid_len) {
|
||||
case 7: // Regular UID
|
||||
if (configure_options.interactive) {
|
||||
printf ("Configure random UID (this cannot be undone) [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Configure random UID (this cannot be undone) [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (do_it) {
|
||||
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_authenticate");
|
||||
freefare_perror(tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
mifare_desfire_key_free (key_picc);
|
||||
mifare_desfire_key_free(key_picc);
|
||||
|
||||
res = mifare_desfire_set_configuration (tags[i], false, true);
|
||||
res = mifare_desfire_set_configuration(tags[i], false, true);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_set_configuration");
|
||||
freefare_perror(tags[i], "mifare_desfire_set_configuration");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4: // Random UID
|
||||
{} // Compilation fails if label is directly followed by the declaration rather than a statement
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
mifare_desfire_key_free (key_picc);
|
||||
|
||||
char *old_tag_uid;
|
||||
res = mifare_desfire_get_card_uid (tags[i], &old_tag_uid);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_card_uid");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("Old card UID: %s\n", old_tag_uid);
|
||||
free (old_tag_uid);
|
||||
|
||||
{} // Compilation fails if label is directly followed by the declaration rather than a statement
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
|
||||
if (res < 0) {
|
||||
freefare_perror(tags[i], "mifare_desfire_authenticate");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
default: // Should not happen
|
||||
warnx ("Unsupported UID length %d.", (int) tag_uid_len);
|
||||
}
|
||||
mifare_desfire_key_free(key_picc);
|
||||
|
||||
char *old_tag_uid;
|
||||
res = mifare_desfire_get_card_uid(tags[i], &old_tag_uid);
|
||||
if (res < 0) {
|
||||
freefare_perror(tags[i], "mifare_desfire_get_card_uid");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
free (tag_uid);
|
||||
printf("Old card UID: %s\n", old_tag_uid);
|
||||
free(old_tag_uid);
|
||||
|
||||
break;
|
||||
default: // Should not happen
|
||||
warnx("Unsupported UID length %d.", (int) tag_uid_len);
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
} /* main() */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -40,10 +40,10 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf (stderr, " -K Provide another PICC key than the default one\n");
|
||||
fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
|
||||
fprintf(stderr, " -K Provide another PICC key than the default one\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -54,30 +54,30 @@ main(int argc, char *argv[])
|
|||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
format_options.interactive = false;
|
||||
break;
|
||||
case 'K':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
format_options.interactive = false;
|
||||
break;
|
||||
case 'K':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i=7; i>=0; i--) {
|
||||
key_data_picc[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
key_data_picc[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
|
@ -86,63 +86,63 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; (!error) && (d < device_count); d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
bool format = true;
|
||||
if (format_options.interactive) {
|
||||
printf ("Format [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Format [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (format) {
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
|
||||
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
|
||||
if (res < 0) {
|
||||
warnx ("Can't authenticate on Mifare DESFire target.");
|
||||
warnx("Can't authenticate on Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
mifare_desfire_key_free (key_picc);
|
||||
mifare_desfire_key_free(key_picc);
|
||||
|
||||
// Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into :
|
||||
// bit7-bit4 equal to 0000b
|
||||
|
|
@ -150,26 +150,26 @@ main(int argc, char *argv[])
|
|||
// bit2 equal to 1b, CreateApplication and DeleteApplication commands are allowed without PICC master key authentication
|
||||
// bit1 equal to 1b, GetApplicationIDs, and GetKeySettings are allowed without PICC master key authentication
|
||||
// bit0 equal to 1b, PICC masterkey MAY be frozen or changeable
|
||||
res = mifare_desfire_change_key_settings (tags[i],0x0F);
|
||||
res = mifare_desfire_change_key_settings(tags[i], 0x0F);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "ChangeKeySettings failed");
|
||||
res = mifare_desfire_format_picc (tags[i]);
|
||||
errx(EXIT_FAILURE, "ChangeKeySettings failed");
|
||||
res = mifare_desfire_format_picc(tags[i]);
|
||||
if (res < 0) {
|
||||
warn ("Can't format PICC.");
|
||||
warn("Can't format PICC.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
}
|
||||
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
} /* main() */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -32,117 +32,117 @@ main(int argc, char *argv[])
|
|||
FreefareTag *tags = NULL;
|
||||
|
||||
if (argc > 1)
|
||||
errx (EXIT_FAILURE, "usage: %s", argv[0]);
|
||||
errx(EXIT_FAILURE, "usage: %s", argv[0]);
|
||||
|
||||
nfc_connstring devices[8];
|
||||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
device = nfc_open(context, devices[d]);
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
int res;
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
|
||||
struct mifare_desfire_version_info info;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("===> Version information for tag %s:\n", tag_uid);
|
||||
printf ("UID: 0x%02x%02x%02x%02x%02x%02x%02x\n", info.uid[0], info.uid[1], info.uid[2], info.uid[3], info.uid[4], info.uid[5], info.uid[6]);
|
||||
printf ("Batch number: 0x%02x%02x%02x%02x%02x\n", info.batch_number[0], info.batch_number[1], info.batch_number[2], info.batch_number[3], info.batch_number[4]);
|
||||
printf ("Production date: week %x, 20%02x\n", info.production_week, info.production_year);
|
||||
printf ("Hardware Information:\n");
|
||||
printf (" Vendor ID: 0x%02x\n", info.hardware.vendor_id);
|
||||
printf (" Type: 0x%02x\n", info.hardware.type);
|
||||
printf (" Subtype: 0x%02x\n", info.hardware.subtype);
|
||||
printf (" Version: %d.%d\n", info.hardware.version_major, info.hardware.version_minor);
|
||||
printf (" Storage size: 0x%02x (%s%d bytes)\n", info.hardware.storage_size, (info.hardware.storage_size & 1) ? ">" : "=", 1 << (info.hardware.storage_size >> 1));
|
||||
printf (" Protocol: 0x%02x\n", info.hardware.protocol);
|
||||
printf ("Software Information:\n");
|
||||
printf (" Vendor ID: 0x%02x\n", info.software.vendor_id);
|
||||
printf (" Type: 0x%02x\n", info.software.type);
|
||||
printf (" Subtype: 0x%02x\n", info.software.subtype);
|
||||
printf (" Version: %d.%d\n", info.software.version_major, info.software.version_minor);
|
||||
printf (" Storage size: 0x%02x (%s%d bytes)\n", info.software.storage_size, (info.software.storage_size & 1) ? ">" : "=", 1 << (info.software.storage_size >> 1));
|
||||
printf (" Protocol: 0x%02x\n", info.software.protocol);
|
||||
printf("===> Version information for tag %s:\n", tag_uid);
|
||||
printf("UID: 0x%02x%02x%02x%02x%02x%02x%02x\n", info.uid[0], info.uid[1], info.uid[2], info.uid[3], info.uid[4], info.uid[5], info.uid[6]);
|
||||
printf("Batch number: 0x%02x%02x%02x%02x%02x\n", info.batch_number[0], info.batch_number[1], info.batch_number[2], info.batch_number[3], info.batch_number[4]);
|
||||
printf("Production date: week %x, 20%02x\n", info.production_week, info.production_year);
|
||||
printf("Hardware Information:\n");
|
||||
printf(" Vendor ID: 0x%02x\n", info.hardware.vendor_id);
|
||||
printf(" Type: 0x%02x\n", info.hardware.type);
|
||||
printf(" Subtype: 0x%02x\n", info.hardware.subtype);
|
||||
printf(" Version: %d.%d\n", info.hardware.version_major, info.hardware.version_minor);
|
||||
printf(" Storage size: 0x%02x (%s%d bytes)\n", info.hardware.storage_size, (info.hardware.storage_size & 1) ? ">" : "=", 1 << (info.hardware.storage_size >> 1));
|
||||
printf(" Protocol: 0x%02x\n", info.hardware.protocol);
|
||||
printf("Software Information:\n");
|
||||
printf(" Vendor ID: 0x%02x\n", info.software.vendor_id);
|
||||
printf(" Type: 0x%02x\n", info.software.type);
|
||||
printf(" Subtype: 0x%02x\n", info.software.subtype);
|
||||
printf(" Version: %d.%d\n", info.software.version_major, info.software.version_minor);
|
||||
printf(" Storage size: 0x%02x (%s%d bytes)\n", info.software.storage_size, (info.software.storage_size & 1) ? ">" : "=", 1 << (info.software.storage_size >> 1));
|
||||
printf(" Protocol: 0x%02x\n", info.software.protocol);
|
||||
|
||||
uint8_t settings;
|
||||
uint8_t max_keys;
|
||||
res = mifare_desfire_get_key_settings (tags[i], &settings, &max_keys);
|
||||
res = mifare_desfire_get_key_settings(tags[i], &settings, &max_keys);
|
||||
if (res == 0) {
|
||||
printf ("Master Key settings (0x%02x):\n", settings);
|
||||
printf (" 0x%02x configuration changeable;\n", settings & 0x08);
|
||||
printf (" 0x%02x PICC Master Key not required for create / delete;\n", settings & 0x04);
|
||||
printf (" 0x%02x Free directory list access without PICC Master Key;\n", settings & 0x02);
|
||||
printf (" 0x%02x Allow changing the Master Key;\n", settings & 0x01);
|
||||
} else if (AUTHENTICATION_ERROR == mifare_desfire_last_picc_error (tags[i])) {
|
||||
printf ("Master Key settings: LOCKED\n");
|
||||
printf("Master Key settings (0x%02x):\n", settings);
|
||||
printf(" 0x%02x configuration changeable;\n", settings & 0x08);
|
||||
printf(" 0x%02x PICC Master Key not required for create / delete;\n", settings & 0x04);
|
||||
printf(" 0x%02x Free directory list access without PICC Master Key;\n", settings & 0x02);
|
||||
printf(" 0x%02x Allow changing the Master Key;\n", settings & 0x01);
|
||||
} else if (AUTHENTICATION_ERROR == mifare_desfire_last_picc_error(tags[i])) {
|
||||
printf("Master Key settings: LOCKED\n");
|
||||
} else {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_key_settings");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_key_settings");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t version;
|
||||
mifare_desfire_get_key_version (tags[i], 0, &version);
|
||||
printf ("Master Key version: %d (0x%02x)\n", version, version);
|
||||
mifare_desfire_get_key_version(tags[i], 0, &version);
|
||||
printf("Master Key version: %d (0x%02x)\n", version, version);
|
||||
|
||||
uint32_t size;
|
||||
res = mifare_desfire_free_mem (tags[i], &size);
|
||||
printf ("Free memory: ");
|
||||
res = mifare_desfire_free_mem(tags[i], &size);
|
||||
printf("Free memory: ");
|
||||
if (0 == res) {
|
||||
printf ("%d bytes\n", size);
|
||||
printf("%d bytes\n", size);
|
||||
} else {
|
||||
printf ("unknown\n");
|
||||
printf("unknown\n");
|
||||
}
|
||||
|
||||
printf ("Use random UID: %s\n", (strlen (tag_uid) / 2 == 4) ? "yes" : "no");
|
||||
printf("Use random UID: %s\n", (strlen(tag_uid) / 2 == 4) ? "yes" : "no");
|
||||
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
} /* main() */
|
||||
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "This application reads a NDEF payload from a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n");
|
||||
fprintf (stderr, "usage: %s [-y] -o FILE [-k 11223344AABBCCDD]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf (stderr, " -o Extract NDEF message if available in FILE\n");
|
||||
fprintf (stderr, " -k Provide another NDEF Tag Application key than the default one\n");
|
||||
fprintf(stderr, "This application reads a NDEF payload from a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n");
|
||||
fprintf(stderr, "usage: %s [-y] -o FILE [-k 11223344AABBCCDD]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf(stderr, " -o Extract NDEF message if available in FILE\n");
|
||||
fprintf(stderr, " -k Provide another NDEF Tag Application key than the default one\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -71,53 +71,53 @@ main(int argc, char *argv[])
|
|||
FreefareTag *tags = NULL;
|
||||
|
||||
char *ndef_output = NULL;
|
||||
while ((ch = getopt (argc, argv, "hyo:k:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
read_options.interactive = false;
|
||||
break;
|
||||
case 'o':
|
||||
ndef_output = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i=7; i>=0; i--) {
|
||||
key_data_app[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
while ((ch = getopt(argc, argv, "hyo:k:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
read_options.interactive = false;
|
||||
break;
|
||||
case 'o':
|
||||
ndef_output = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
key_data_app[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
||||
if (ndef_output == NULL) {
|
||||
usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
FILE* message_stream = NULL;
|
||||
FILE* ndef_stream = NULL;
|
||||
FILE *message_stream = NULL;
|
||||
FILE *ndef_stream = NULL;
|
||||
|
||||
if ((strlen (ndef_output) == 1) && (ndef_output[0] == '-')) {
|
||||
if ((strlen(ndef_output) == 1) && (ndef_output[0] == '-')) {
|
||||
message_stream = stderr;
|
||||
ndef_stream = stdout;
|
||||
} else {
|
||||
message_stream = stdout;
|
||||
ndef_stream = fopen(ndef_output, "wb");
|
||||
if (!ndef_stream) {
|
||||
fprintf (stderr, "Could not open file %s.\n", ndef_output);
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "Could not open file %s.\n", ndef_output);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,72 +125,72 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
device = nfc_open(context, devices[d]);
|
||||
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
fprintf (message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
fprintf(message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
|
||||
bool read_ndef = true;
|
||||
if (read_options.interactive) {
|
||||
fprintf (message_stream, "Read NDEF [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
fprintf(message_stream, "Read NDEF [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
fprintf (message_stream, "\n");
|
||||
fprintf(message_stream, "\n");
|
||||
}
|
||||
|
||||
if (read_ndef) {
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
// We've to track DESFire version as NDEF mapping is different
|
||||
struct mifare_desfire_version_info info;
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
MifareDESFireKey key_app;
|
||||
key_app = mifare_desfire_des_key_new_with_version (key_data_app);
|
||||
key_app = mifare_desfire_des_key_new_with_version(key_data_app);
|
||||
|
||||
// Mifare DESFire SelectApplication (Select application)
|
||||
MifareDESFireAID aid;
|
||||
if (info.software.version_major==0)
|
||||
if (info.software.version_major == 0)
|
||||
aid = mifare_desfire_aid_new(0xEEEE10);
|
||||
else
|
||||
// There is no more relationship between DESFire AID and ISO AID...
|
||||
|
|
@ -198,80 +198,80 @@ main(int argc, char *argv[])
|
|||
aid = mifare_desfire_aid_new(0x000001);
|
||||
res = mifare_desfire_select_application(tags[i], aid);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
|
||||
free (aid);
|
||||
errx(EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
|
||||
free(aid);
|
||||
|
||||
// Authentication with NDEF Tag Application master key (Authentication with key 0)
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_app);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_app);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
|
||||
// Read Capability Container file E103
|
||||
uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data()
|
||||
if (info.software.version_major==0)
|
||||
res = mifare_desfire_read_data (tags[i], 0x03, 0, 2, lendata);
|
||||
if (info.software.version_major == 0)
|
||||
res = mifare_desfire_read_data(tags[i], 0x03, 0, 2, lendata);
|
||||
else
|
||||
// There is no more relationship between DESFire FID and ISO FileID...
|
||||
// Let's assume it's in FID 01h as proposed in the spec
|
||||
res = mifare_desfire_read_data (tags[i], 0x01, 0, 2, lendata);
|
||||
res = mifare_desfire_read_data(tags[i], 0x01, 0, 2, lendata);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Read CC len failed");
|
||||
errx(EXIT_FAILURE, "Read CC len failed");
|
||||
uint16_t cclen = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]);
|
||||
if (cclen < 15)
|
||||
errx (EXIT_FAILURE, "CC too short IMHO");
|
||||
if (!(cc_data = malloc(cclen+20))) // cf FIXME in mifare_desfire.c read_data()
|
||||
errx (EXIT_FAILURE, "malloc");
|
||||
if (info.software.version_major==0)
|
||||
res = mifare_desfire_read_data (tags[i], 0x03, 0, cclen, cc_data);
|
||||
errx(EXIT_FAILURE, "CC too short IMHO");
|
||||
if (!(cc_data = malloc(cclen + 20))) // cf FIXME in mifare_desfire.c read_data()
|
||||
errx(EXIT_FAILURE, "malloc");
|
||||
if (info.software.version_major == 0)
|
||||
res = mifare_desfire_read_data(tags[i], 0x03, 0, cclen, cc_data);
|
||||
else
|
||||
res = mifare_desfire_read_data (tags[i], 0x01, 0, cclen, cc_data);
|
||||
res = mifare_desfire_read_data(tags[i], 0x01, 0, cclen, cc_data);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Read CC data failed");
|
||||
errx(EXIT_FAILURE, "Read CC data failed");
|
||||
// Search NDEF File Control TLV
|
||||
uint8_t off = 7;
|
||||
while (((off+7) < cclen) && (cc_data[off] != 0x04)) {
|
||||
while (((off + 7) < cclen) && (cc_data[off] != 0x04)) {
|
||||
// Skip TLV
|
||||
off += cc_data[off+1] + 2;
|
||||
off += cc_data[off + 1] + 2;
|
||||
}
|
||||
if (off+7 >= cclen)
|
||||
errx (EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
|
||||
if (cc_data[off+2] != 0xE1)
|
||||
errx (EXIT_FAILURE, "Unknown NDEF File reference in CC");
|
||||
if (off + 7 >= cclen)
|
||||
errx(EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
|
||||
if (cc_data[off + 2] != 0xE1)
|
||||
errx(EXIT_FAILURE, "Unknown NDEF File reference in CC");
|
||||
uint8_t file_no;
|
||||
if (info.software.version_major==0)
|
||||
file_no = cc_data[off+3];
|
||||
if (info.software.version_major == 0)
|
||||
file_no = cc_data[off + 3];
|
||||
else
|
||||
// There is no more relationship between DESFire FID and ISO FileID...
|
||||
// Let's assume it's in FID 02h as proposed in the spec
|
||||
file_no = 2;
|
||||
uint16_t ndefmaxlen = (((uint16_t) cc_data[off+4]) << 8) + ((uint16_t) cc_data[off+5]);
|
||||
fprintf (message_stream, "Max NDEF size: %i bytes\n", ndefmaxlen);
|
||||
if (!(ndef_msg = malloc(ndefmaxlen+20))) // cf FIXME in mifare_desfire.c read_data()
|
||||
errx (EXIT_FAILURE, "malloc");
|
||||
uint16_t ndefmaxlen = (((uint16_t) cc_data[off + 4]) << 8) + ((uint16_t) cc_data[off + 5]);
|
||||
fprintf(message_stream, "Max NDEF size: %i bytes\n", ndefmaxlen);
|
||||
if (!(ndef_msg = malloc(ndefmaxlen + 20))) // cf FIXME in mifare_desfire.c read_data()
|
||||
errx(EXIT_FAILURE, "malloc");
|
||||
|
||||
res = mifare_desfire_read_data (tags[i], file_no, 0, 2, lendata);
|
||||
res = mifare_desfire_read_data(tags[i], file_no, 0, 2, lendata);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Read NDEF len failed");
|
||||
errx(EXIT_FAILURE, "Read NDEF len failed");
|
||||
ndef_msg_len = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]);
|
||||
fprintf (message_stream, "NDEF size: %i bytes\n", ndef_msg_len);
|
||||
fprintf(message_stream, "NDEF size: %i bytes\n", ndef_msg_len);
|
||||
if (ndef_msg_len + 2 > ndefmaxlen)
|
||||
errx (EXIT_FAILURE, "Declared NDEF size larger than max NDEF size");
|
||||
res = mifare_desfire_read_data (tags[i], file_no, 2, ndef_msg_len, ndef_msg);
|
||||
errx(EXIT_FAILURE, "Declared NDEF size larger than max NDEF size");
|
||||
res = mifare_desfire_read_data(tags[i], file_no, 2, ndef_msg_len, ndef_msg);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Read data failed");
|
||||
if (fwrite (ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len)
|
||||
errx (EXIT_FAILURE, "Write to file failed");
|
||||
free (cc_data);
|
||||
free (ndef_msg);
|
||||
mifare_desfire_key_free (key_app);
|
||||
errx(EXIT_FAILURE, "Read data failed");
|
||||
if (fwrite(ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len)
|
||||
errx(EXIT_FAILURE, "Write to file failed");
|
||||
free(cc_data);
|
||||
free(ndef_msg);
|
||||
mifare_desfire_key_free(key_app);
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
}
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,12 +62,12 @@ struct {
|
|||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf (stderr, "This application writes a NDEF payload into a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n");
|
||||
fprintf (stderr, "usage: %s [-y] -i FILE [-k 11223344AABBCCDD]\n", progname);
|
||||
fprintf (stderr, "\nOptions:\n");
|
||||
fprintf (stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf (stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
|
||||
fprintf (stderr, " -k Provide another NDEF Tag Application key than the default one\n");
|
||||
fprintf(stderr, "This application writes a NDEF payload into a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n");
|
||||
fprintf(stderr, "usage: %s [-y] -i FILE [-k 11223344AABBCCDD]\n", progname);
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -y Do not ask for confirmation\n");
|
||||
fprintf(stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
|
||||
fprintf(stderr, " -k Provide another NDEF Tag Application key than the default one\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -79,146 +79,146 @@ main(int argc, char *argv[])
|
|||
FreefareTag *tags = NULL;
|
||||
|
||||
char *ndef_input = NULL;
|
||||
while ((ch = getopt (argc, argv, "hyi:k:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
write_options.interactive = false;
|
||||
break;
|
||||
case 'i':
|
||||
ndef_input = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i=7; i>=0; i--) {
|
||||
key_data_app[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
while ((ch = getopt(argc, argv, "hyi:k:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'y':
|
||||
write_options.interactive = false;
|
||||
break;
|
||||
case 'i':
|
||||
ndef_input = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
if (strlen(optarg) != 16) {
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint64_t n = strtoull(optarg, NULL, 16);
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
key_data_app[i] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Remaining args, if any, are in argv[optind .. (argc-1)]
|
||||
|
||||
if (ndef_input == NULL) {
|
||||
ndef_msg_len = sizeof(ndef_default_msg) + 2;
|
||||
if (!(ndef_msg = malloc (ndef_msg_len))) {
|
||||
err (EXIT_FAILURE, "malloc");
|
||||
}
|
||||
ndef_msg[0] = (uint8_t) ((ndef_msg_len - 2) >> 8);
|
||||
ndef_msg[1] = (uint8_t) (ndef_msg_len - 2);
|
||||
memcpy(ndef_msg + 2, ndef_default_msg, ndef_msg_len - 2);
|
||||
ndef_msg_len = sizeof(ndef_default_msg) + 2;
|
||||
if (!(ndef_msg = malloc(ndef_msg_len))) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
ndef_msg[0] = (uint8_t)((ndef_msg_len - 2) >> 8);
|
||||
ndef_msg[1] = (uint8_t)(ndef_msg_len - 2);
|
||||
memcpy(ndef_msg + 2, ndef_default_msg, ndef_msg_len - 2);
|
||||
} else {
|
||||
FILE* ndef_stream = NULL;
|
||||
if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) {
|
||||
// FIXME stdin as input have to be readed and buffered in ndef_msg
|
||||
FILE *ndef_stream = NULL;
|
||||
if ((strlen(ndef_input) == 1) && (ndef_input[0] == '-')) {
|
||||
// FIXME stdin as input have to be readed and buffered in ndef_msg
|
||||
ndef_stream = stdin;
|
||||
fprintf (stderr, "stdin as NDEF is not implemented");
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "stdin as NDEF is not implemented");
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
ndef_stream = fopen(ndef_input, "rb");
|
||||
if (!ndef_stream) {
|
||||
fprintf (stderr, "Could not open file %s.\n", ndef_input);
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "Could not open file %s.\n", ndef_input);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fseek(ndef_stream, 0L, SEEK_END);
|
||||
ndef_msg_len = ftell(ndef_stream) + 2;
|
||||
fseek(ndef_stream, 0L, SEEK_SET);
|
||||
fseek(ndef_stream, 0L, SEEK_SET);
|
||||
|
||||
if (!(ndef_msg = malloc (ndef_msg_len))) {
|
||||
err (EXIT_FAILURE, "malloc");
|
||||
if (!(ndef_msg = malloc(ndef_msg_len))) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
ndef_msg[0] = (uint8_t) ((ndef_msg_len - 2) >> 8);
|
||||
ndef_msg[1] = (uint8_t) (ndef_msg_len - 2);
|
||||
if (fread (ndef_msg + 2, 1, ndef_msg_len - 2, ndef_stream) != ndef_msg_len - 2) {
|
||||
fprintf (stderr, "Could not read NDEF from file: %s\n", ndef_input);
|
||||
fclose (ndef_stream);
|
||||
exit (EXIT_FAILURE);
|
||||
ndef_msg[0] = (uint8_t)((ndef_msg_len - 2) >> 8);
|
||||
ndef_msg[1] = (uint8_t)(ndef_msg_len - 2);
|
||||
if (fread(ndef_msg + 2, 1, ndef_msg_len - 2, ndef_stream) != ndef_msg_len - 2) {
|
||||
fprintf(stderr, "Could not read NDEF from file: %s\n", ndef_input);
|
||||
fclose(ndef_stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose (ndef_stream);
|
||||
fclose(ndef_stream);
|
||||
}
|
||||
}
|
||||
printf ("NDEF file is %zu bytes long.\n", ndef_msg_len);
|
||||
printf("NDEF file is %zu bytes long.\n", ndef_msg_len);
|
||||
|
||||
nfc_connstring devices[8];
|
||||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, 8);
|
||||
device_count = nfc_list_devices(context, devices, 8);
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found.");
|
||||
errx(EXIT_FAILURE, "No NFC device found.");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
device = nfc_open (context, devices[d]);
|
||||
device = nfc_open(context, devices[d]);
|
||||
|
||||
if (!device) {
|
||||
warnx ("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
if (!device) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
tags = freefare_get_tags (device);
|
||||
tags = freefare_get_tags(device);
|
||||
if (!tags) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing tags.");
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
|
||||
continue;
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
|
||||
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
|
||||
bool write_ndef = true;
|
||||
if (write_options.interactive) {
|
||||
printf ("Write NDEF [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
printf("Write NDEF [yN] ");
|
||||
fgets(buffer, BUFSIZ, stdin);
|
||||
write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
|
||||
} else {
|
||||
printf ("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (write_ndef) {
|
||||
int res;
|
||||
|
||||
res = mifare_desfire_connect (tags[i]);
|
||||
res = mifare_desfire_connect(tags[i]);
|
||||
if (res < 0) {
|
||||
warnx ("Can't connect to Mifare DESFire target.");
|
||||
warnx("Can't connect to Mifare DESFire target.");
|
||||
error = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
// We've to track DESFire version as NDEF mapping is different
|
||||
struct mifare_desfire_version_info info;
|
||||
res = mifare_desfire_get_version (tags[i], &info);
|
||||
res = mifare_desfire_get_version(tags[i], &info);
|
||||
if (res < 0) {
|
||||
freefare_perror (tags[i], "mifare_desfire_get_version");
|
||||
freefare_perror(tags[i], "mifare_desfire_get_version");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
MifareDESFireKey key_app;
|
||||
key_app = mifare_desfire_des_key_new_with_version (key_data_app);
|
||||
key_app = mifare_desfire_des_key_new_with_version(key_data_app);
|
||||
|
||||
// Mifare DESFire SelectApplication (Select application)
|
||||
MifareDESFireAID aid;
|
||||
if (info.software.version_major==0)
|
||||
if (info.software.version_major == 0)
|
||||
aid = mifare_desfire_aid_new(0xEEEE10);
|
||||
else
|
||||
// There is no more relationship between DESFire AID and ISO AID...
|
||||
|
|
@ -227,74 +227,74 @@ main(int argc, char *argv[])
|
|||
|
||||
res = mifare_desfire_select_application(tags[i], aid);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
|
||||
free (aid);
|
||||
errx(EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
|
||||
free(aid);
|
||||
|
||||
// Authentication with NDEF Tag Application master key (Authentication with key 0)
|
||||
res = mifare_desfire_authenticate (tags[i], 0, key_app);
|
||||
res = mifare_desfire_authenticate(tags[i], 0, key_app);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
|
||||
|
||||
// Read Capability Container file E103
|
||||
uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data()
|
||||
|
||||
if (info.software.version_major==0)
|
||||
res = mifare_desfire_read_data (tags[i], 0x03, 0, 2, lendata);
|
||||
if (info.software.version_major == 0)
|
||||
res = mifare_desfire_read_data(tags[i], 0x03, 0, 2, lendata);
|
||||
else
|
||||
// There is no more relationship between DESFire FID and ISO FileID...
|
||||
// Let's assume it's in FID 01h as proposed in the spec
|
||||
res = mifare_desfire_read_data (tags[i], 0x01, 0, 2, lendata);
|
||||
res = mifare_desfire_read_data(tags[i], 0x01, 0, 2, lendata);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Read CC len failed");
|
||||
errx(EXIT_FAILURE, "Read CC len failed");
|
||||
uint16_t cclen = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]);
|
||||
if (cclen < 15)
|
||||
errx (EXIT_FAILURE, "CC too short IMHO");
|
||||
errx(EXIT_FAILURE, "CC too short IMHO");
|
||||
if (!(cc_data = malloc(cclen + 20))) // cf FIXME in mifare_desfire.c read_data()
|
||||
errx (EXIT_FAILURE, "malloc");
|
||||
if (info.software.version_major==0)
|
||||
res = mifare_desfire_read_data (tags[i], 0x03, 0, cclen, cc_data);
|
||||
errx(EXIT_FAILURE, "malloc");
|
||||
if (info.software.version_major == 0)
|
||||
res = mifare_desfire_read_data(tags[i], 0x03, 0, cclen, cc_data);
|
||||
else
|
||||
res = mifare_desfire_read_data (tags[i], 0x01, 0, cclen, cc_data);
|
||||
res = mifare_desfire_read_data(tags[i], 0x01, 0, cclen, cc_data);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, "Read CC data failed");
|
||||
errx(EXIT_FAILURE, "Read CC data failed");
|
||||
// Search NDEF File Control TLV
|
||||
uint8_t off = 7;
|
||||
while (((off+7) < cclen) && (cc_data[off] != 0x04)) {
|
||||
while (((off + 7) < cclen) && (cc_data[off] != 0x04)) {
|
||||
// Skip TLV
|
||||
off += cc_data[off+1] + 2;
|
||||
off += cc_data[off + 1] + 2;
|
||||
}
|
||||
if (off+7 >= cclen)
|
||||
errx (EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
|
||||
if (cc_data[off+2] != 0xE1)
|
||||
errx (EXIT_FAILURE, "Unknown NDEF File reference in CC");
|
||||
if (off + 7 >= cclen)
|
||||
errx(EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
|
||||
if (cc_data[off + 2] != 0xE1)
|
||||
errx(EXIT_FAILURE, "Unknown NDEF File reference in CC");
|
||||
uint8_t file_no;
|
||||
if (info.software.version_major==0)
|
||||
file_no = cc_data[off+3];
|
||||
if (info.software.version_major == 0)
|
||||
file_no = cc_data[off + 3];
|
||||
else
|
||||
// There is no more relationship between DESFire FID and ISO FileID...
|
||||
// Let's assume it's in FID 02h as proposed in the spec
|
||||
file_no = 2;
|
||||
uint16_t ndefmaxlen = (((uint16_t) cc_data[off+4]) << 8) + ((uint16_t) cc_data[off+5]);
|
||||
fprintf (stdout, "Max NDEF size: %i bytes\n", ndefmaxlen);
|
||||
uint16_t ndefmaxlen = (((uint16_t) cc_data[off + 4]) << 8) + ((uint16_t) cc_data[off + 5]);
|
||||
fprintf(stdout, "Max NDEF size: %i bytes\n", ndefmaxlen);
|
||||
if (ndef_msg_len > ndefmaxlen)
|
||||
errx (EXIT_FAILURE, "Supplied NDEF larger than max NDEF size");
|
||||
errx(EXIT_FAILURE, "Supplied NDEF larger than max NDEF size");
|
||||
|
||||
//Mifare DESFire WriteData to write the content of the NDEF File with NLEN equal to NDEF Message length and NDEF Message
|
||||
res = mifare_desfire_write_data(tags[i], file_no, 0, ndef_msg_len, (uint8_t *) ndef_msg);
|
||||
if (res < 0)
|
||||
errx (EXIT_FAILURE, " Write data failed");
|
||||
errx(EXIT_FAILURE, " Write data failed");
|
||||
|
||||
free(cc_data);
|
||||
mifare_desfire_key_free (key_app);
|
||||
mifare_desfire_key_free(key_app);
|
||||
|
||||
mifare_desfire_disconnect (tags[i]);
|
||||
mifare_desfire_disconnect(tags[i]);
|
||||
}
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
free (ndef_msg);
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
free(ndef_msg);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
nfc_exit (context);
|
||||
exit (error);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/*-
|
||||
* Copyright (C) 2012, Romain Tartiere.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
|
|
@ -22,41 +22,41 @@
|
|||
#include <freefare.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int error = EXIT_SUCCESS;
|
||||
nfc_device *device = NULL;
|
||||
FreefareTag *tags = NULL;
|
||||
|
||||
if (argc > 1)
|
||||
errx (EXIT_FAILURE, "usage: %s", argv[0]);
|
||||
errx(EXIT_FAILURE, "usage: %s", argv[0]);
|
||||
|
||||
nfc_connstring devices[8];
|
||||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, sizeof (devices) / sizeof (*devices));
|
||||
device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
|
||||
if (device_count <= 0)
|
||||
errx (EXIT_FAILURE, "No NFC device found");
|
||||
errx(EXIT_FAILURE, "No NFC device found");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
if (!(device = nfc_open (context, devices[d]))) {
|
||||
warnx ("nfc_open() failed.");
|
||||
if (!(device = nfc_open(context, devices[d]))) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(tags = freefare_get_tags (device))) {
|
||||
nfc_close (device);
|
||||
errx (EXIT_FAILURE, "Error listing tags.");
|
||||
if (!(tags = freefare_get_tags(device))) {
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
||||
for (int i = 0; (!error) && tags[i]; i++) {
|
||||
switch (freefare_get_tag_type (tags[i])) {
|
||||
switch (freefare_get_tag_type(tags[i])) {
|
||||
case MIFARE_ULTRALIGHT:
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
break;
|
||||
|
|
@ -64,28 +64,28 @@ main (int argc, char *argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||
printf ("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name (tags[i]));
|
||||
if (freefare_get_tag_type (tags[i]) == MIFARE_ULTRALIGHT_C) {
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
printf("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name(tags[i]));
|
||||
if (freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT_C) {
|
||||
FreefareTag tag = tags[i];
|
||||
int res;
|
||||
MifareDESFireKey key;
|
||||
uint8_t key1_3des_data[16] = { 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46 };
|
||||
key = mifare_desfire_3des_key_new (key1_3des_data);
|
||||
if (mifare_ultralight_connect (tag) < 0)
|
||||
errx (EXIT_FAILURE, "Error connecting to tag.");
|
||||
res = mifare_ultralightc_authenticate (tag, key);
|
||||
printf ("Authentication with default key: %s\n", res ? "fail" : "success");
|
||||
mifare_desfire_key_free (key);
|
||||
mifare_ultralight_disconnect (tag);
|
||||
}
|
||||
free (tag_uid);
|
||||
key = mifare_desfire_3des_key_new(key1_3des_data);
|
||||
if (mifare_ultralight_connect(tag) < 0)
|
||||
errx(EXIT_FAILURE, "Error connecting to tag.");
|
||||
res = mifare_ultralightc_authenticate(tag, key);
|
||||
printf("Authentication with default key: %s\n", res ? "fail" : "success");
|
||||
mifare_desfire_key_free(key);
|
||||
mifare_ultralight_disconnect(tag);
|
||||
}
|
||||
free(tag_uid);
|
||||
}
|
||||
|
||||
freefare_free_tags (tags);
|
||||
nfc_close (device);
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
}
|
||||
|
||||
nfc_exit (context);
|
||||
nfc_exit(context);
|
||||
exit(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ main(int argc, char *argv[])
|
|||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, sizeof (devices) / sizeof (*devices));
|
||||
device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
|
||||
if (device_count <= 0)
|
||||
errx(EXIT_FAILURE, "No NFC device found");
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ main(int argc, char *argv[])
|
|||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices(context, devices, sizeof (devices) / sizeof (*devices));
|
||||
device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
|
||||
if (device_count <= 0)
|
||||
errx(EXIT_FAILURE, "No NFC device found");
|
||||
|
||||
|
|
@ -71,14 +71,14 @@ main(int argc, char *argv[])
|
|||
if (ntag21x_connect(tag) < 0)
|
||||
errx(EXIT_FAILURE, "Error connecting to tag.");
|
||||
|
||||
uint8_t pwd[4] = {0xff,0xff,0xff,0xff};
|
||||
uint8_t pack[2] = {0xaa,0xaa};
|
||||
uint8_t pack_old[2] = {0x00,0x00};
|
||||
uint8_t pwd[4] = {0xff, 0xff, 0xff, 0xff};
|
||||
uint8_t pack[2] = {0xaa, 0xaa};
|
||||
uint8_t pack_old[2] = {0x00, 0x00};
|
||||
|
||||
NTAG21xKey key;
|
||||
NTAG21xKey key_old;
|
||||
key = ntag21x_key_new(pwd,pack); // Creating key
|
||||
key_old = ntag21x_key_new(pwd,pack_old); // Creating key
|
||||
key = ntag21x_key_new(pwd, pack); // Creating key
|
||||
key_old = ntag21x_key_new(pwd, pack_old); // Creating key
|
||||
|
||||
uint8_t auth0 = 0x00; // Buffer for auth0 byte
|
||||
|
||||
|
|
@ -89,48 +89,48 @@ main(int argc, char *argv[])
|
|||
MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters
|
||||
*/
|
||||
res = ntag21x_get_info(tag);
|
||||
if(res < 0) {
|
||||
if (res < 0) {
|
||||
printf("Error getting info from tag\n");
|
||||
break;
|
||||
}
|
||||
// Authenticate with tag
|
||||
res = ntag21x_authenticate(tag,key);
|
||||
if(res < 0) {
|
||||
res = ntag21x_authenticate(tag, key);
|
||||
if (res < 0) {
|
||||
printf("Error getting info from tag\n");
|
||||
break;
|
||||
}
|
||||
// Get auth byte from tag
|
||||
res = ntag21x_get_auth(tag,&auth0);
|
||||
if(res < 0) {
|
||||
res = ntag21x_get_auth(tag, &auth0);
|
||||
if (res < 0) {
|
||||
printf("Error getting auth0 byte from tag\n");
|
||||
break;
|
||||
}
|
||||
printf("Old auth0: %#02x\n",auth0);
|
||||
printf("Old auth0: %#02x\n", auth0);
|
||||
// Set old key
|
||||
res = ntag21x_set_key(tag,key_old);
|
||||
if(res < 0) {
|
||||
res = ntag21x_set_key(tag, key_old);
|
||||
if (res < 0) {
|
||||
printf("Error setting key tag\n");
|
||||
break;
|
||||
}
|
||||
// Disable password protection (when auth0 byte > last page)
|
||||
res = ntag21x_set_auth(tag,0xff);
|
||||
if(res<0) {
|
||||
res = ntag21x_set_auth(tag, 0xff);
|
||||
if (res < 0) {
|
||||
printf("Error setting auth0 byte \n");
|
||||
break;
|
||||
}
|
||||
// Disable read & write pwd protection -> (default: write only protection)
|
||||
res = ntag21x_access_disable(tag,NTAG_PROT);
|
||||
if(res < 0) {
|
||||
res = ntag21x_access_disable(tag, NTAG_PROT);
|
||||
if (res < 0) {
|
||||
printf("Error setting access byte \n");
|
||||
break;
|
||||
}
|
||||
// Get auth byte from tag
|
||||
res = ntag21x_get_auth(tag,&auth0);
|
||||
if(res < 0) {
|
||||
res = ntag21x_get_auth(tag, &auth0);
|
||||
if (res < 0) {
|
||||
printf("Error getting auth0 byte from tag\n");
|
||||
break;
|
||||
}
|
||||
printf("New auth0: %#02x\n",auth0);
|
||||
printf("New auth0: %#02x\n", auth0);
|
||||
}
|
||||
|
||||
ntag21x_disconnect(tag);
|
||||
|
|
|
|||
|
|
@ -36,22 +36,22 @@ main(int argc, char *argv[])
|
|||
size_t device_count;
|
||||
|
||||
nfc_context *context;
|
||||
nfc_init (&context);
|
||||
nfc_init(&context);
|
||||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices (context, devices, sizeof (devices) / sizeof (*devices));
|
||||
device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
|
||||
if (device_count <= 0)
|
||||
errx(EXIT_FAILURE, "No NFC device found");
|
||||
|
||||
for (size_t d = 0; d < device_count; d++) {
|
||||
if (!(device = nfc_open (context, devices[d]))) {
|
||||
if (!(device = nfc_open(context, devices[d]))) {
|
||||
warnx("nfc_open() failed.");
|
||||
error = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(tags = freefare_get_tags (device))) {
|
||||
if (!(tags = freefare_get_tags(device))) {
|
||||
nfc_close(device);
|
||||
errx(EXIT_FAILURE, "Error listing tags.");
|
||||
}
|
||||
|
|
@ -68,14 +68,14 @@ main(int argc, char *argv[])
|
|||
printf("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name(tags[i]));
|
||||
FreefareTag tag = tags[i];
|
||||
int res;
|
||||
if (ntag21x_connect (tag) < 0)
|
||||
if (ntag21x_connect(tag) < 0)
|
||||
errx(EXIT_FAILURE, "Error connecting to tag.");
|
||||
|
||||
uint8_t pwd[4] = {0xff,0xff,0xff,0xff};
|
||||
uint8_t pack[2] = {0xaa,0xaa};
|
||||
uint8_t pwd[4] = {0xff, 0xff, 0xff, 0xff};
|
||||
uint8_t pack[2] = {0xaa, 0xaa};
|
||||
|
||||
NTAG21xKey key;
|
||||
key = ntag21x_key_new(pwd,pack); // Creating key
|
||||
key = ntag21x_key_new(pwd, pack); // Creating key
|
||||
|
||||
uint8_t auth0 = 0x00; // Buffer for auth0 byte
|
||||
uint8_t authlim = 0x00;
|
||||
|
|
@ -86,57 +86,57 @@ main(int argc, char *argv[])
|
|||
MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters
|
||||
*/
|
||||
res = ntag21x_get_info(tag);
|
||||
if(res < 0) {
|
||||
if (res < 0) {
|
||||
printf("Error getting info from tag\n");
|
||||
break;
|
||||
}
|
||||
// Get auth byte from tag
|
||||
res = ntag21x_get_auth(tag,&auth0);
|
||||
if(res < 0) {
|
||||
res = ntag21x_get_auth(tag, &auth0);
|
||||
if (res < 0) {
|
||||
printf("Error getting auth0 byte from tag\n");
|
||||
break;
|
||||
}
|
||||
printf("Old auth0: %#02x\n",auth0);
|
||||
res = ntag21x_get_authentication_limit(tag,&authlim);
|
||||
if(res < 0) {
|
||||
printf("Old auth0: %#02x\n", auth0);
|
||||
res = ntag21x_get_authentication_limit(tag, &authlim);
|
||||
if (res < 0) {
|
||||
printf("Error getting auth0 byte from tag\n");
|
||||
break;
|
||||
}
|
||||
printf("Authlim: %#02x\n",authlim);
|
||||
printf("Authlim: %#02x\n", authlim);
|
||||
// Check if auth is required to set pwd and pack
|
||||
if(auth0 < ntag21x_get_last_page(tag) - 2) { // Check if last 2 pages are protected
|
||||
if (auth0 < ntag21x_get_last_page(tag) - 2) { // Check if last 2 pages are protected
|
||||
printf("Error: pwd and PACK sections are protected with unknown password\n");
|
||||
break;
|
||||
}
|
||||
// Set key
|
||||
res = ntag21x_set_key(tag,key);
|
||||
if(res < 0) {
|
||||
res = ntag21x_set_key(tag, key);
|
||||
if (res < 0) {
|
||||
printf("Error setting key tag\n");
|
||||
break;
|
||||
}
|
||||
// Protect last 6 pages !! It can be hacked if you don't protect last 4 pages where auth0 byte is located
|
||||
res = ntag21x_set_auth(tag,ntag21x_get_last_page(tag)-5);
|
||||
if(res < 0) {
|
||||
res = ntag21x_set_auth(tag, ntag21x_get_last_page(tag) - 5);
|
||||
if (res < 0) {
|
||||
printf("Error setting auth0 byte \n");
|
||||
break;
|
||||
}
|
||||
// Enable read & write pwd protection (default: write only protection)
|
||||
res = ntag21x_access_enable(tag,NTAG_PROT);
|
||||
if(res < 0) {
|
||||
res = ntag21x_access_enable(tag, NTAG_PROT);
|
||||
if (res < 0) {
|
||||
printf("Error setting access byte \n");
|
||||
break;
|
||||
}
|
||||
// Get auth byte from tag
|
||||
res = ntag21x_get_auth(tag,&auth0);
|
||||
if(res < 0) {
|
||||
res = ntag21x_get_auth(tag, &auth0);
|
||||
if (res < 0) {
|
||||
printf("Error getting auth0 byte from tag\n");
|
||||
break;
|
||||
}
|
||||
printf("New auth0: %#02x\n",auth0);
|
||||
printf("New auth0: %#02x\n", auth0);
|
||||
}
|
||||
ntag21x_disconnect (tag);
|
||||
ntag21x_disconnect(tag);
|
||||
ntag21x_key_free(key); // Delete key
|
||||
free (tag_uid);
|
||||
free(tag_uid);
|
||||
}
|
||||
freefare_free_tags(tags);
|
||||
nfc_close(device);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ main(int argc, char *argv[])
|
|||
if (context == NULL)
|
||||
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
|
||||
|
||||
device_count = nfc_list_devices(context, devices, sizeof (devices) / sizeof (*devices));
|
||||
device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
|
||||
if (device_count <= 0)
|
||||
errx(EXIT_FAILURE, "No NFC device found");
|
||||
|
||||
|
|
@ -65,13 +65,13 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
char *tag_uid = freefare_get_tag_uid(tags[i]);
|
||||
printf("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name (tags[i]));
|
||||
printf("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name(tags[i]));
|
||||
FreefareTag tag = tags[i];
|
||||
int res;
|
||||
if (ntag21x_connect(tag) < 0)
|
||||
errx(EXIT_FAILURE, "Error connecting to tag.");
|
||||
|
||||
uint8_t data [4] = {0xfa,0xca,0xac,0xad}; // Data to write on tag
|
||||
uint8_t data [4] = {0xfa, 0xca, 0xac, 0xad}; // Data to write on tag
|
||||
uint8_t read[4]; // Buffer for reading data from tag
|
||||
|
||||
bool flag_match = true;
|
||||
|
|
@ -82,28 +82,28 @@ main(int argc, char *argv[])
|
|||
MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters
|
||||
*/
|
||||
res = ntag21x_get_info(tag);
|
||||
if(res < 0) {
|
||||
if (res < 0) {
|
||||
printf("Error getting info from tag\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// writing to tag 4 bytes on page 0x27 (check specs for NTAG21x before changing page number !!!)
|
||||
res = ntag21x_write(tag,0x27,data);
|
||||
if(res < 0) {
|
||||
res = ntag21x_write(tag, 0x27, data);
|
||||
if (res < 0) {
|
||||
printf("Error writing to tag\n");
|
||||
break;
|
||||
}
|
||||
res = ntag21x_fast_read4(tag,0x27,read); // Reading page from tag (4 bytes), you can also use ntag21x_read4 or ntag21x_read (16 bytes) or ntag21x_fast_read (start_page to end_page)
|
||||
if(res < 0) {
|
||||
res = ntag21x_fast_read4(tag, 0x27, read); // Reading page from tag (4 bytes), you can also use ntag21x_read4 or ntag21x_read (16 bytes) or ntag21x_fast_read (start_page to end_page)
|
||||
if (res < 0) {
|
||||
printf("Error reading tag\n");
|
||||
break;
|
||||
}
|
||||
for(int i=0;i < 4;i++) // Checking if we can read what we have written earlyer
|
||||
if(data[i] != read[i]) {
|
||||
for (int i = 0; i < 4; i++) // Checking if we can read what we have written earlyer
|
||||
if (data[i] != read[i]) {
|
||||
flag_match = false;
|
||||
break;
|
||||
}
|
||||
if(!flag_match)
|
||||
if (!flag_match)
|
||||
printf("Data don't match\n");
|
||||
else
|
||||
printf("Data match\n");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue