Ejemplo n.º 1
0
static bool rfid_authenticate(MifareTag tag, struct rfid_key *key) {
	int ret;
	bool result = false;

	ret = mifare_desfire_connect(tag);
	if(ret < 0) {
		log("failed to connect to tag");
		return false;
	}

	ret = mifare_desfire_select_application(tag, door_aid);
	if(ret < 0) {
		log("failed to select application");
		goto out_tag;
	}

	MifareDESFireKey dfkey = mifare_desfire_3des_key_new(key->key);

	ret = mifare_desfire_authenticate(tag, 0xD, dfkey);
	if(ret < 0) {
		log("authentication failed");
		goto out_key;
	}

	if(ret == 0)
		result = true;

out_key:
	mifare_desfire_key_free(dfkey);
out_tag:
	mifare_desfire_disconnect(tag);

	return result;
}
void
cut_setup (void)
{
    int res;
    nfc_connstring devices[8];
    size_t device_count;

    nfc_init (&context);
    cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)"));

    device_count = nfc_list_devices (context, devices, 8);
    if (device_count <= 0)
        cut_omit ("No device found");

    for (size_t i = 0; i < device_count; i++) {

        device = nfc_open (context, devices[i]);
        if (!device)
            cut_omit ("nfc_open() failed.");

        tags = freefare_get_tags (device);
        cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed"));

        tag = NULL;
        for (int i=0; tags[i]; i++) {
            if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
                tag = tags[i];
                res = mifare_desfire_connect (tag);
                cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));

                struct mifare_desfire_version_info version_info;
                res = mifare_desfire_get_version (tag, &version_info);
                cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_version"));

                if (version_info.hardware.storage_size < 0x18) {
                    cut_omit ("DESFire EV1 tests require at least a 4K card");
                }

                if ((version_info.hardware.version_major >= 1) &&
                    (version_info.software.version_major >= 1)) {
                    return;
                }

                mifare_desfire_disconnect (tag);
            }
        }
        nfc_close (device);
        device = NULL;
        freefare_free_tags (tags);
        tags = NULL;
    }
    cut_omit ("No MIFARE DESFire EV1 tag on NFC device");
}
Ejemplo n.º 3
0
int
explain_tag (MifareTag tag)
{
    bool aborting = false;

    mifare_desfire_connect (tag);

    MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID);
    if (mifare_desfire_select_application (tag, ucard_info_aid) < 0) {
        freefare_perror (tag, "mifare_desfire_select_application");
        return -1;
    }
    free (ucard_info_aid);

    MifareDESFireKey key = mifare_desfire_aes_key_new (admin_key_data);
    if (mifare_desfire_authenticate_aes (tag, 0, key) < 0) {
        freefare_perror (tag, "mifare_desfire_authenticate_aes");
        return -1;
    }

    uint8_t records[(3+16)*32];
    int records_length;
    records_length = mifare_desfire_read_records_ex (tag, USER_KEYRING_FILENO, 0, 0, records, USER_KEYRING_COMMUNICATION_MODE);
    if (records_length < 0) {
        if (BOUNDARY_ERROR == mifare_desfire_last_picc_error (tag)) {
            warnx ("Card is empty");
            return 0;
        }
        freefare_perror (tag, "mifare_desfire_read_records_ex");
        return -1;
    }

    for (int i = 0; (!aborting) && (i < records_length); i += (3+16)) {
        uint32_t raw_aid = records[i] << 16 | records[i+1] << 8 | records[i+2];

        MifareDESFireAID aid = mifare_desfire_aid_new (raw_aid);
        MifareDESFireKey key = mifare_desfire_des_key_new (records + i + 3);

        if (explain_application (tag, aid, key) < 0)
            aborting = true;

        mifare_desfire_key_free (key);
        free (aid);
    }

    mifare_desfire_disconnect (tag);

    return (aborting) ? -1 : 0;
}
void
cut_teardown (void)
{
    if (tag)
        mifare_desfire_disconnect (tag);

    if (tags) {
        freefare_free_tags (tags);
        tags = NULL;
    }

    if (device)
        nfc_close (device);

    nfc_exit (context);
}
int
main(int argc, char *argv[])
{
    int ch;
    int error = EXIT_SUCCESS;
    nfc_device *device = NULL;
    MifareTag *tags = NULL;

    while ((ch = getopt (argc, argv, "hyK:")) != -1) {
        switch (ch) {
        case 'h':
            usage(argv[0]);
            exit (EXIT_SUCCESS);
            break;
        case 'y':
            configure_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)]

    nfc_connstring devices[8];
    size_t device_count;

    nfc_context *context;
    nfc_init (&context);
    if (context == NULL)
        errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");

    device_count = nfc_list_devices (context, devices, 8);
    if (device_count <= 0)
        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;
        }

        tags = freefare_get_tags (device);
        if (!tags) {
            nfc_close (device);
            errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
        }

        for (int i = 0; (!error) && tags[i]; i++) {
            if (DESFIRE != freefare_get_tag_type (tags[i]))
                continue;

            char *tag_uid = freefare_get_tag_uid (tags[i]);
            char buffer[BUFSIZ];
            int res;

            res = mifare_desfire_connect (tags[i]);
            if (res < 0) {
                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);
            if (res < 0) {
                freefare_perror (tags[i], "mifare_desfire_get_version");
                error = 1;
                break;
            }
            if (info.software.version_major < 1) {
                warnx ("Found old DESFire, skipping");
                continue;
            }
            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);
                do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
            } else {
                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);
                if (res < 0) {
                    freefare_perror (tags[i], "mifare_desfire_authenticate");
                    error = EXIT_FAILURE;
                    break;
                }
                mifare_desfire_key_free (key_picc);

                res = mifare_desfire_set_ats (tags[i], new_ats);
                if (res < 0) {
                    freefare_perror (tags[i], "mifare_desfire_set_ats");
                    error = EXIT_FAILURE;
                    break;
                }

            }

            mifare_desfire_disconnect (tags[i]);
            free (tag_uid);
        }

        freefare_free_tags (tags);
        nfc_close (device);
    }
    nfc_exit (context);
    exit (error);
} /* main() */
Ejemplo n.º 6
0
int
main(int argc, char *argv[])
{
    int ch;
    int error = EXIT_SUCCESS;
    nfc_device *device = NULL;
    MifareTag *tags = NULL;

    while ((ch = getopt (argc, argv, "hyK:")) != -1) {
	switch (ch) {
	    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_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)]

    nfc_connstring devices[8];
    size_t device_count;
    
    nfc_context *context;
    nfc_init (&context);

    device_count = nfc_list_devices (context, devices, 8);
    if (device_count <= 0)
	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;
        }

	tags = freefare_get_tags (device);
	if (!tags) {
	    nfc_close (device);
	    errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
	}

	for (int i = 0; (!error) && tags[i]; i++) {
	    if (DESFIRE != freefare_get_tag_type (tags[i]))
		continue;

	    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);
	    bool format = true;
	    if (format_options.interactive) {
		printf ("Format [yN] ");
		fgets (buffer, BUFSIZ, stdin);
		format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
	    } else {
		printf ("\n");
	    }

	    if (format) {
		int res;

		res = mifare_desfire_connect (tags[i]);
		if (res < 0) {
		    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);
		if (res < 0) {
		    warnx ("Can't authenticate on Mifare DESFire target.");
		    error = EXIT_FAILURE;
		    break;
		}
		mifare_desfire_key_free (key_picc);

		// Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into :
		// bit7-bit4 equal to 0000b
		// bit3 equal to 1b, the configuration of the PICC master key MAY be changeable or frozen
		// 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);
		if (res < 0)
		    errx (EXIT_FAILURE, "ChangeKeySettings failed");
		res = mifare_desfire_format_picc (tags[i]);
		if (res < 0) {
		    warn ("Can't format PICC.");
		    error = EXIT_FAILURE;
		    break;
		}

		mifare_desfire_disconnect (tags[i]);
	    }

	    free (tag_uid);
	}

	freefare_free_tags (tags);
	nfc_close (device);
    }
    nfc_exit (context);
    exit (error);
} /* main() */
Ejemplo n.º 7
0
int
main(int argc, char *argv[])
{
    int error = EXIT_SUCCESS;
    nfc_device *device = NULL;
    MifareTag *tags = NULL;

    if (argc > 1)
	errx (EXIT_FAILURE, "usage: %s", argv[0]);

    nfc_connstring devices[8];
    size_t device_count;

    nfc_context *context;
    nfc_init (&context);
    if (context == NULL)
	errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");

    device_count = nfc_list_devices (context, devices, 8);
    if (device_count <= 0)
	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;
        }

	tags = freefare_get_tags (device);
	if (!tags) {
	    nfc_close (device);
	    errx (EXIT_FAILURE, "Error listing tags.");
	}

	for (int i = 0; (!error) && tags[i]; i++) {
	    if (DESFIRE != freefare_get_tag_type (tags[i]))
		continue;

	    int res;
	    // This is hex-encoded see the https://code.google.com/p/libfreefare/source/browse/libfreefare/freefare.c#189 on how to access the raw data
	    char *tag_uid = freefare_get_tag_uid (tags[i]);

	    res = mifare_desfire_connect (tags[i]);
	    if (res < 0) {
		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);
	    if (res < 0)
		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);
	    if (res < 0)
		errx (EXIT_FAILURE, "Application creation failed");

	    res = mifare_desfire_select_application (tags[i], aid);
	    if (res < 0)
		errx (EXIT_FAILURE, "Application selection failed");

	    res = mifare_desfire_authenticate (tags[i], 0, key);
	    if (res < 0)
		errx (EXIT_FAILURE, "Authentication on application failed");

	    res = mifare_desfire_create_std_data_file (tags[i], 1, MDCM_ENCIPHERED, 0x0000, 20);
	    if (res < 0)
		errx (EXIT_FAILURE, "File creation failed");

	    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");

	    char buffer[20];
	    res = mifare_desfire_read_data (tags[i], 1, 0, 0, buffer);
	    if (res < 0)
		errx (EXIT_FAILURE, "File read failed");

	    res = mifare_desfire_select_application (tags[i], NULL);
	    if (res < 0)
		errx (EXIT_FAILURE, "Master application selection failed");

	    res = mifare_desfire_authenticate (tags[i], 0, key);
	    if (res < 0)
		errx (EXIT_FAILURE, "Authentication on master application failed");

	    res = mifare_desfire_format_picc (tags[i]);
	    if (res < 0)
		errx (EXIT_FAILURE, "PICC format failed");

	    mifare_desfire_key_free (key);
	    free (tag_uid);
	    free (aid);

	    mifare_desfire_disconnect (tags[i]);
	}

	freefare_free_tags (tags);
	nfc_close (device);
    }
    nfc_exit (context);
    exit (error);
} /* main() */
Ejemplo n.º 8
0
int
main (void)
{
    uint8_t issuer_key_data[16];

    nfc_connstring nfc_devices[8];
    size_t nfc_device_count;

    nfc_device_count = nfc_list_devices (NULL, nfc_devices, 8);

    for (size_t n = 0; n < nfc_device_count; n++) {
	nfc_device *nfc_device = nfc_open (NULL, nfc_devices[n]);

	MifareTag *tags = freefare_get_tags (nfc_device);
	for (int i = 0; tags[i]; i++) {
	    MifareTag tag = tags[i];
	    if (DESFIRE == freefare_get_tag_type (tag)) {

		printf ("Fond Mifare DESFire with UID: %s\n", freefare_get_tag_uid (tag));

		printf ("Issuer private key: ");
		char buffer[BUFSIZ];
		system ("stty -echo");
		fgets (buffer, BUFSIZ, stdin);
		system ("stty echo");
		char *p;
		if ((p = strchr (buffer, '\n')))
		    *p = '\0';
		ucard_derivate_password (buffer, strlen (buffer), 16, issuer_key_data);
		memset (buffer, '\0', strlen (buffer));

		MifareDESFireKey key = mifare_desfire_aes_key_new (issuer_key_data);

		MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID);

		int res = mifare_desfire_connect (tag);

		res = mifare_desfire_select_application (tag, ucard_info_aid);
		if (res < 0) {
		    freefare_perror (tag, "mifare_desfire_select_application");
		    goto end;
		}
		res = mifare_desfire_authenticate_aes (tag, 1, key);
		if (res < 0) {
		    freefare_perror (tag, "mifare_desfire_authenticate_aes");
		    goto end;
		}

		char owner_info[BUFSIZ];
		res = mifare_desfire_read_data_ex (tag, 10, 0, 0, owner_info, MDCM_ENCIPHERED);
		if (res < 0) {
		    freefare_perror (tag, "mifare_desfire_read_data");
		    goto end;
		}

		owner_info[res] = '\0';

		printf ("Owner: %s\n", owner_info);

end:
		mifare_desfire_disconnect (tag);

		mifare_desfire_key_free (key);

		free (ucard_info_aid);
	    }
	}

	nfc_close (nfc_device);
    }

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 9
0
int
main (int argc, char *argv[])
{
    /*
     * Collect information
     */

    bool f_flag = false;
    char *p;

    char ch;
    while ((ch = getopt (argc, argv, "f")) != -1) {
	switch (ch) {
	case 'f':
	    f_flag = true;
	    break;
	default:
	    usage (argv[0]);
	    exit (EXIT_FAILURE);
	    break;
	}
    }

    char issuer_address[BUFSIZ];
    fprintf (stderr, "Card issuer address: ");
    fgets (issuer_address, BUFSIZ, stdin);
    if ((p = strchr (issuer_address, '\n')))
	*p = '\0';

    char issuer_password[BUFSIZ];
    read_password ("Issuer password", issuer_password, BUFSIZ);
    fprintf (stderr, "\n");
    uint8_t issuer_password_data[16];
    ucard_derivate_password (issuer_password, strlen (issuer_password), 16, issuer_password_data);
    memset (issuer_password, '\0', strlen (issuer_password));
    MifareDESFireKey card_issuer_key = mifare_desfire_aes_key_new (issuer_password_data);

    char owner_full_name[BUFSIZ];
    fprintf (stderr, "Card owner full user name: ");
    fgets (owner_full_name, BUFSIZ, stdin);
    if ((p = strchr (owner_full_name, '\n')))
	*p = '\0';

    char user_password[BUFSIZ];
    read_password ("User password", user_password, BUFSIZ);
    fprintf (stderr, "\n");
    uint8_t user_key_data[16];
    ucard_derivate_password (user_password, strlen (user_password), 16, user_key_data);
    memset (user_password, '\0', strlen (user_password));
    MifareDESFireKey user_key = mifare_desfire_aes_key_new_with_version (user_key_data, UCARD_AES_KEY_VERSION);

    char admin_password[BUFSIZ];
    read_password ("Admin password", admin_password, BUFSIZ);
    fprintf (stderr, "\n");
    uint8_t admin_key_data[16];
    ucard_derivate_password (admin_password, strlen (admin_password), 16, admin_key_data);
    memset (admin_password, '\0', strlen (admin_password));

    MifareDESFireKey admin_key = mifare_desfire_aes_key_new_with_version (admin_key_data, UCARD_AES_KEY_VERSION);

    uint8_t null_key_data[16] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    MifareDESFireKey null_des_key = mifare_desfire_des_key_new (null_key_data);
    MifareDESFireKey null_aes_key = mifare_desfire_aes_key_new (null_key_data);

    nfc_connstring nfc_devices[8];
    size_t nfc_device_count;

    nfc_device_count = nfc_list_devices (NULL, nfc_devices, 8);

    for (size_t n = 0; n < nfc_device_count; n++) {
	nfc_device *nfc_device = nfc_open(NULL, nfc_devices[n]);

	MifareTag *tags = freefare_get_tags (nfc_device);
	for (int i = 0; tags[i]; i++) {
	    MifareTag tag = tags[i];
	    if (DESFIRE == freefare_get_tag_type (tag)) {

		/* Actually setup the card */

		printf ("Fond Mifare DESFire with UID: %s\n", freefare_get_tag_uid (tag));

		/*
		 * Master Application
		 *
		 * Key  0: Card owner 'user' private key
		 */

		MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID);

		int res = mifare_desfire_connect (tag);
		if (f_flag) {
		    if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, user_key);
		    if (0 == res) res = mifare_desfire_format_picc (tag);
		} else {
		    if (0 == res) res = mifare_desfire_authenticate (tag, 0, null_des_key);
		    if (0 == res) res = mifare_desfire_change_key (tag, 0, user_key, NULL);
		    if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, user_key);
		}
		if (0 == res) res = mifare_desfire_create_application (tag, ucard_info_aid, 0x0F, 0x83);
		if (!f_flag) {
		    if (0 == res) res = mifare_desfire_change_key_settings (tag, 0x01);
		}

		/*
		 * Card information application
		 *
		 * Key  0: Card owner 'admin' private key
		 * Key  1: Card issuer private key
		 * Key  2: Anonymous access public key
		 *
		 * File  9: Card issuer information
		 * File 10: Card owner information
		 * File 11: Keyring
		 */

		if (0 == res) res = mifare_desfire_select_application (tag, ucard_info_aid);
		if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, null_aes_key);
		if (0 == res) res = mifare_desfire_change_key (tag, 0, admin_key, NULL);
		if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, admin_key);
		if (0 == res) res = mifare_desfire_change_key (tag, 1, card_issuer_key, NULL);

		if (0 == res) res = mifare_desfire_create_std_data_file (tag, 9, MDCM_ENCIPHERED, 0x0000, strlen (issuer_address));
		if (0 == res) res = mifare_desfire_write_data (tag, 9, 0, strlen (issuer_address), issuer_address);
		if (strlen (issuer_address) ==  (size_t) res) res = mifare_desfire_change_file_settings (tag, 9, MDCM_ENCIPHERED, 0x2F11);

		if (0 == res) res = mifare_desfire_create_std_data_file (tag, 10, MDCM_ENCIPHERED, 0x0000, strlen (owner_full_name));
		if (0 == res) res = mifare_desfire_write_data (tag, 10, 0, strlen (owner_full_name), owner_full_name);
		if (strlen (owner_full_name) == (size_t) res) res = mifare_desfire_change_file_settings (tag, 10, MDCM_ENCIPHERED, 0x0F11);

		if (0 == res) res = mifare_desfire_create_linear_record_file (tag, 11, MDCM_ENCIPHERED, 0xF20F, 3 + 16, 24);

		if (0 == res) res = mifare_desfire_change_key_settings (tag, 0x01);

		if (res < 0) {
		    fprintf (stderr, "Oops, something went wrong! (%s)\n", freefare_strerror (tag));
		}

		mifare_desfire_disconnect (tag);

		free (ucard_info_aid);
	    }
	}

	nfc_close (nfc_device);
    }

    mifare_desfire_key_free (admin_key);
    mifare_desfire_key_free (user_key);
    mifare_desfire_key_free (card_issuer_key);
    mifare_desfire_key_free (null_aes_key);
    mifare_desfire_key_free (null_des_key);

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 10
0
int
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]);

    nfc_connstring devices[8];
    size_t device_count;

    nfc_context *context;
    nfc_init (&context);
    if (context == NULL)
	errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");

    device_count = nfc_list_devices (context, devices, 8);
    if (device_count <= 0)
	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;
        }

	tags = freefare_get_tags (device);
	if (!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]))
		continue;

	    int res;
	    char *tag_uid = freefare_get_tag_uid (tags[i]);

	    res = mifare_desfire_connect (tags[i]);
	    if (res < 0) {
            warnx ("Can't connect to Mifare DESFire target.");
            error = 1;
            break;
	    }else{
            printf("Connected uid: %s\n", tag_uid);
        }

        uint8_t key_version;
        mifare_desfire_get_key_version (tags[i], 0, &key_version);
        MifareDESFireKey key = malloc(sizeof(MifareDESFireKey));

        res = mifare_desfire_auto_authenticate(tags[i], 0, key);

        if(res < 0){
            printf("Error while geting the master key.....\n"); 
            break;
        }

        MifareDESFireAID aid = mifare_desfire_aid_new (0x112233);
		//res = mifare_desfire_create_application (tags[i], aid, 0xFF, 1);

        size_t count;
        MifareDESFireAID **aids = malloc(sizeof(MifareDESFireAID*)); 
        res = mifare_desfire_get_application_ids(tags[i], aids, &count);

        if(res==0){
            printf("found %d applicaton/s\n", (int)count);
            //struct MifareDESFireAID aidArr[count] = *aids;
            int j;
            for(j=0; j<count; j++){
                // Fails here
                aid = (*aids)[j];
                printf("aid %d: %x\n", j, mifare_desfire_aid_get_aid(aid));

                if(mifare_desfire_aid_get_aid(aid) == 0x112233){
                    if(mifare_desfire_select_application(tags[i], aid) == 0){ 
                      printf("app selected...\n");
                      size_t fileCount = 0;
                      uint8_t **files = malloc(sizeof(uint8_t));
                      int rra = mifare_desfire_get_file_ids(tags[i], files, &fileCount);
                      printf("%d found %d file ids\n", rra, (int)fileCount);
                    }
                }

            }
            printf("ok\n");
        }else{
            printf("error res is %d\n", res);
        }
        
        mifare_desfire_key_free (key);

	    free (tag_uid);

	    mifare_desfire_disconnect (tags[i]);
	}

	freefare_free_tags (tags);
	nfc_close (device);
    }
    nfc_exit (context);
    exit (error);
} /* main() */
int
main(int argc, char *argv[])
{
    int ch;
    int error = EXIT_SUCCESS;
    nfc_device *device = NULL;
    FreefareTag *tags = NULL;

    while ((ch = getopt (argc, argv, "hy")) != -1) {
	switch (ch) {
	case 'h':
	    usage(argv[0]);
	    exit (EXIT_SUCCESS);
	    break;
	case 'y':
	    configure_options.interactive = false;
	    break;
	default:
	    usage(argv[0]);
	    exit (EXIT_FAILURE);
	}
    }
    // Remaining args, if any, are in argv[optind .. (argc-1)]

    nfc_connstring devices[8];
    size_t device_count;

    nfc_context *context;
    nfc_init (&context);
    if (context == NULL)
	errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");

    device_count = nfc_list_devices (context, devices, 8);
    if (device_count <= 0)
	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;
        }

	tags = freefare_get_tags (device);
	if (!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]))
		continue;

	    char *tag_uid = freefare_get_tag_uid (tags[i]);
	    char buffer[BUFSIZ];

	    int res;

	    res = mifare_desfire_connect (tags[i]);
	    if (res < 0) {
		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);
	    if (res < 0) {
		freefare_perror (tags[i], "mifare_desfire_get_version");
		error = 1;
		break;
	    }
	    if (info.software.version_major < 1) {
		warnx ("Found old DESFire, skipping");
		continue;
	    }

	    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);
		do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
	    } else {
		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);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_authenticate");
		    error = EXIT_FAILURE;
		    break;
		}
		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);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_set_default_key");
		    error = EXIT_FAILURE;
		    break;
		}

		/*
		 * Perform some tests to ensure the function actually worked
		 * (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);

		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_create_application");
		    error = EXIT_FAILURE;
		    break;
		}

		res = mifare_desfire_select_application (tags[i], aid);
		if (res < 0) {
		    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);
		if (res < 0) {
		    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);
		    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);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_authenticate");
		    error = EXIT_FAILURE;
		    break;
		}

		free (aid);

		/* Resetdefault settings */

		res = mifare_desfire_select_application (tags[i], NULL);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_select_application");
		    error = EXIT_FAILURE;
		    break;
		}

		default_key = mifare_desfire_des_key_new (null_key_data);

		res = mifare_desfire_authenticate (tags[i], 0, default_key);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_authenticate");
		    error = EXIT_FAILURE;
		    break;
		}

		res = mifare_desfire_set_default_key (tags[i], default_key);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_set_default_key");
		    error = EXIT_FAILURE;
		    break;
		}

		mifare_desfire_key_free (default_key);

		/* Wipeout the card */

		res = mifare_desfire_format_picc (tags[i]);
		if (res < 0) {
		    freefare_perror (tags[i], "mifare_desfire_format_picc");
		    error = EXIT_FAILURE;
		    break;
		}

	    }

	    mifare_desfire_disconnect (tags[i]);
	    free (tag_uid);
	}

	freefare_free_tags (tags);
	nfc_close (device);
    }
    nfc_exit (context);
    exit (error);
}