diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h
index 52c5c36..776519a 100644
--- a/libfreefare/freefare.h
+++ b/libfreefare/freefare.h
@@ -257,6 +257,14 @@ enum mifare_desfire_file_types {
struct mifare_desfire_aid;
typedef struct mifare_desfire_aid *MifareDESFireAID;
+struct mifare_desfire_df {
+ uint32_t aid;
+ uint16_t fid;
+ uint8_t df_name[16];
+ size_t df_name_len;
+};
+typedef struct mifare_desfire_df MifareDESFireDF;
+
MifareDESFireAID mifare_desfire_aid_new (uint32_t aid);
MifareDESFireAID mifare_desfire_aid_new_with_mad_aid (MadAid mad_aid, uint8_t n);
uint32_t mifare_desfire_aid_get_aid (MifareDESFireAID aid);
@@ -327,8 +335,14 @@ int mifare_desfire_get_key_version (MifareTag tag, uint8_t key_no, uint8_t *ve
int mifare_desfire_create_application (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int mifare_desfire_create_application_3k3des (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int mifare_desfire_create_application_aes (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
+
+int mifare_desfire_create_application_iso (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len);
+int mifare_desfire_create_application_3k3des_iso (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len);
+int mifare_desfire_create_application_aes_iso (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len);
+
int mifare_desfire_delete_application (MifareTag tag, MifareDESFireAID aid);
int mifare_desfire_get_application_ids (MifareTag tag, MifareDESFireAID *aids[], size_t *count);
+int mifare_desfire_get_df_names (MifareTag tag, MifareDESFireDF *dfs[], size_t *count);
void mifare_desfire_free_application_ids (MifareDESFireAID aids[]);
int mifare_desfire_select_application (MifareTag tag, MifareDESFireAID aid);
int mifare_desfire_format_picc (MifareTag tag);
diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c
index e0329c9..10eac12 100644
--- a/libfreefare/mifare_desfire.c
+++ b/libfreefare/mifare_desfire.c
@@ -625,22 +625,28 @@ mifare_desfire_get_key_version (MifareTag tag, uint8_t key_no, uint8_t *version)
int
-create_application (MifareTag tag, MifareDESFireAID aid, uint8_t settings1, uint8_t settings2, uint16_t iso_file_id, char *iso_file_name)
+create_application (MifareTag tag, MifareDESFireAID aid, uint8_t settings1, uint8_t settings2, int want_iso_application, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len)
{
- (void) iso_file_id;
- (void) iso_file_name;
-
ASSERT_ACTIVE (tag);
ASSERT_MIFARE_DESFIRE (tag);
BUFFER_INIT (cmd, 22);
BUFFER_INIT (res, 1 + CMAC_LENGTH);
+ if (want_iso_file_identifiers)
+ settings2 |= 0x20;
+
BUFFER_APPEND (cmd, 0xCA);
BUFFER_APPEND_LE (cmd, aid->data, sizeof (aid->data), sizeof (aid->data));
BUFFER_APPEND (cmd, settings1);
BUFFER_APPEND (cmd, settings2);
+ if (want_iso_application)
+ BUFFER_APPEND_LE (cmd, iso_file_id, sizeof (iso_file_id), sizeof (iso_file_id));
+
+ if (iso_file_name_len)
+ BUFFER_APPEND_BYTES (cmd, iso_file_name, iso_file_name_len);
+
uint8_t *p = mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 0, MDCM_PLAIN | CMAC_COMMAND);
DESFIRE_TRANSCEIVE2 (tag, p, __cmd_n, res);
@@ -654,19 +660,37 @@ create_application (MifareTag tag, MifareDESFireAID aid, uint8_t settings1, uint
int
mifare_desfire_create_application (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no)
{
- return create_application (tag, aid, settings, key_no, 0, NULL);
+ return create_application (tag, aid, settings, key_no, 0, 0, 0, NULL, 0);
+}
+
+int
+mifare_desfire_create_application_iso (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len)
+{
+ return create_application (tag, aid, settings, key_no, 1, want_iso_file_identifiers, iso_file_id, iso_file_name, iso_file_name_len);
}
int
mifare_desfire_create_application_3k3des (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no)
{
- return create_application (tag, aid, settings, APPLICATION_CRYPTO_3K3DES | key_no, 0, NULL);
+ return create_application (tag, aid, settings, APPLICATION_CRYPTO_3K3DES | key_no, 0, 0, 0, NULL, 0);
+}
+
+int
+mifare_desfire_create_application_3k3des_iso (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len)
+{
+ return create_application (tag, aid, settings, APPLICATION_CRYPTO_3K3DES | key_no, 1, want_iso_file_identifiers, iso_file_id, iso_file_name, iso_file_name_len);
}
int
mifare_desfire_create_application_aes (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no)
{
- return create_application (tag, aid, settings, APPLICATION_CRYPTO_AES | key_no, 0, NULL);
+ return create_application (tag, aid, settings, APPLICATION_CRYPTO_AES | key_no, 0, 0, 0, NULL, 0);
+}
+
+int
+mifare_desfire_create_application_aes_iso (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len)
+{
+ return create_application (tag, aid, settings, APPLICATION_CRYPTO_AES | key_no, 1, want_iso_file_identifiers, iso_file_id, iso_file_name, iso_file_name_len);
}
int
@@ -754,6 +778,43 @@ mifare_desfire_get_application_ids (MifareTag tag, MifareDESFireAID *aids[], siz
return 0;
}
+int
+mifare_desfire_get_df_names (MifareTag tag, MifareDESFireDF *dfs[], size_t *count)
+{
+ ASSERT_ACTIVE (tag);
+ ASSERT_MIFARE_DESFIRE (tag);
+
+ *count = 0;
+ *dfs = NULL;
+
+ BUFFER_INIT (cmd, 1);
+ BUFFER_INIT (res, 22 + CMAC_LENGTH);
+
+ BUFFER_APPEND (cmd, 0x6D);
+
+ uint8_t *p = mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 0, MDCM_PLAIN | CMAC_COMMAND);
+
+ do {
+ DESFIRE_TRANSCEIVE2 (tag, p, __cmd_n, res);
+
+ if (__res_n > 1) {
+ MifareDESFireDF *new_dfs;
+ if ((new_dfs = realloc (*dfs, sizeof (*new_dfs) * (*count + 1)))) {
+ new_dfs[*count].aid = le24toh (res);
+ new_dfs[*count].fid = le16toh (*(uint16_t *)(res + 3));
+ memcpy (new_dfs[*count].df_name, res + 5, __res_n - 6);
+ new_dfs[*count].df_name_len = __res_n - 6;
+ *dfs = new_dfs;
+ *count += 1;
+ }
+ }
+
+ p[0] = 0XAF;
+ } while (res[__res_n-1] == 0xAF);
+
+ return 0;
+}
+
void
mifare_desfire_free_application_ids (MifareDESFireAID aids[])
{
diff --git a/test/Makefile.am b/test/Makefile.am
index 6d03098..a56a171 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -66,6 +66,7 @@ test_mifare_desfire_ev1_la_SOURCES = test_mifare_desfire_ev1.c \
test_mifare_desfire_ev1_3des.c \
test_mifare_desfire_ev1_3k3des.c \
test_mifare_desfire_ev1_aes.c \
+ test_mifare_desfire_ev1_iso.c \
mifare_desfire_ev1_fixture.c \
mifare_desfire_ev1_fixture.h
test_mifare_desfire_ev1_la_LIBADD = $(top_builddir)/libfreefare/libfreefare.la \
@@ -88,4 +89,7 @@ echo-cutter:
EXTRA_DIST = run-test.sh
CLEANFILES = *.gcno
+update:
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES)
+
endif
diff --git a/test/test_mifare_desfire_ev1_iso.c b/test/test_mifare_desfire_ev1_iso.c
new file mode 100644
index 0000000..51e22f4
--- /dev/null
+++ b/test/test_mifare_desfire_ev1_iso.c
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (C) 2011, 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
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see
+ *
+ * $Id$
+ */
+
+#include
+
+#include
+#include "freefare_internal.h"
+
+#include "mifare_desfire_ev1_fixture.h"
+#include "common/mifare_desfire_auto_authenticate.h"
+
+#define cut_assert_success(last_command) \
+ do { \
+ cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_picc_error (tag), cut_message ("PICC replied %s", mifare_desfire_error_lookup (mifare_desfire_last_picc_error (tag)))); \
+ cut_assert_not_equal_int (-1, res, cut_message ("Wrong return value")); \
+ } while (0)
+
+void
+test_mifare_desfire_ev1_iso (void)
+{
+ int res;
+ MifareDESFireKey key;
+
+ mifare_desfire_auto_authenticate (tag, 0);
+
+ res = mifare_desfire_format_picc (tag);
+ cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_format_picc()"));
+
+ MifareDESFireDF *dfs;
+ size_t count;
+ res = mifare_desfire_get_df_names (tag, &dfs, &count);
+ cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_get_df_names()"));
+ cut_assert_equal_int (count, 0, cut_message ("Wrong DF count"));
+ cut_assert_null (dfs, cut_message ("DF should be NULL"));
+
+ MifareDESFireAID aid = mifare_desfire_aid_new (0x111110);
+ res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0);
+ cut_assert_success ("mifare_desfire_create_application_iso");
+ free (aid);
+
+ uint8_t app2[] = "App2";
+ aid = mifare_desfire_aid_new (0x222220);
+ res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x222F, app2, sizeof (app2));
+ cut_assert_success ("mifare_desfire_create_application_iso");
+ free (aid);
+
+ uint8_t app3[] = "App3";
+ aid = mifare_desfire_aid_new (0x333330);
+ res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x333F, app3, sizeof (app3));
+ cut_assert_success ("mifare_desfire_create_application_iso");
+ free (aid);
+
+ aid = mifare_desfire_aid_new (0x444440);
+ res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0);
+ cut_assert_equal_int (-1, res, cut_message ("Should fail"));
+ cut_assert_equal_int (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error"));
+
+ res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x444F, app2, sizeof (app2));
+ cut_assert_equal_int (-1, res, cut_message ("Should fail"));
+ cut_assert_equal_int (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error"));
+ free (aid);
+
+
+ res = mifare_desfire_get_df_names (tag, &dfs, &count);
+ cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_df_names()"));
+ cut_assert_equal_int (3, count, cut_message ("Wrong DF count"));
+ cut_assert_not_null (dfs, cut_message ("DF should not be NULL"));
+
+ cut_assert_equal_int (0x111110, dfs[0].aid, cut_message ("Wrong value"));
+ cut_assert_equal_int (0x111F, dfs[0].fid, cut_message ("Wrong value"));
+ cut_assert_equal_int (0, dfs[0].df_name_len, cut_message ("Wrong value"));
+
+ cut_assert_equal_int (0x222220, dfs[1].aid, cut_message ("Wrong value"));
+ cut_assert_equal_int (0x222F, dfs[1].fid, cut_message ("Wrong value"));
+ cut_assert_equal_int (sizeof (app2), dfs[1].df_name_len, cut_message ("Wrong value"));
+ cut_assert_equal_memory (app2, sizeof (app2), dfs[1].df_name, dfs[1].df_name_len, cut_message ("Wrong value"));
+
+ cut_assert_equal_int (0x333330, dfs[2].aid, cut_message ("Wrong value"));
+ cut_assert_equal_int (0x333F, dfs[2].fid, cut_message ("Wrong value"));
+ cut_assert_equal_int (sizeof (app3), dfs[2].df_name_len, cut_message ("Wrong value"));
+ cut_assert_equal_memory (app3, sizeof (app3), dfs[2].df_name, dfs[2].df_name_len, cut_message ("Wrong value"));
+ free (dfs);
+}