summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelen <jjelen@redhat.com>2018-08-02 11:43:45 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2018-08-02 15:31:44 +0200
commitd8386ee1a98932433f957a1a5eaf3d775878bc87 (patch)
treef52e4599874d29a77216e88a3334f991d899a4e7
parentd3ad1f6f5999ea4dbbff9b8b511622cd6aa6aa59 (diff)
cac: Generate dynamic ACA structures based on the certificates
* So far, the ACA tables were static from existing card. * This change allows adjusting the ACA tables based on the real certificates and PKI applets present in virtual smart card Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Robert Relyea <rrelyea@redhat.com> Message-Id: <20180802094407.4104-14-jjelen@redhat.com>
-rw-r--r--src/cac-aca.c244
-rw-r--r--src/cac-aca.h4
-rw-r--r--src/cac.c31
3 files changed, 198 insertions, 81 deletions
diff --git a/src/cac-aca.c b/src/cac-aca.c
index e303ffa..d6fc465 100644
--- a/src/cac-aca.c
+++ b/src/cac-aca.c
@@ -214,6 +214,7 @@ struct applet_entry {
};
struct service_applet_table {
unsigned num_entries;
+ unsigned num_static_entries;
struct applet_entry entries[];
};
@@ -285,7 +286,19 @@ struct service_applet_table {
*/
struct service_applet_table service_table = {
- 15, {
+ 22, 12, {
+ /* Variable PKI applets entries */
+ {0x61, 7, "\xA0\x00\x00\x00\x79\x01\x00"},
+ {0x62, 7, "\xA0\x00\x00\x00\x79\x01\x01"},
+ {0x63, 7, "\xA0\x00\x00\x00\x79\x01\x02"},
+ {0x64, 7, "\xA0\x00\x00\x00\x79\x01\x03"},
+ {0x65, 7, "\xA0\x00\x00\x00\x79\x01\x04"},
+ {0x66, 7, "\xA0\x00\x00\x00\x79\x01\x05"},
+ {0x67, 7, "\xA0\x00\x00\x00\x79\x01\x06"},
+ {0x68, 7, "\xA0\x00\x00\x00\x79\x01\x07"},
+ {0x69, 7, "\xA0\x00\x00\x00\x79\x01\x08"},
+ {0x6a, 7, "\xA0\x00\x00\x00\x79\x01\x09"},
+ /* static applet entries */
{0x40, 7, "\xA0\x00\x00\x01\x16\x30\x00"},
{0x4F, 7, "\xA0\x00\x00\x01\x16\xDB\x00"},
{0x4B, 7, "\xA0\x00\x00\x00\x79\x02\xFB"},
@@ -294,48 +307,55 @@ struct service_applet_table service_table = {
{0x4E, 7, "\xA0\x00\x00\x00\x79\x02\xFE"},
{0x4D, 7, "\xA0\x00\x00\x00\x79\x02\xFD"},
{0x50, 7, "\xA0\x00\x00\x00\x79\x02\xF2"},
- {0x63, 7, "\xA0\x00\x00\x00\x79\x01\x02"},
{0x51, 7, "\xA0\x00\x00\x00\x79\x02\xF0"},
- {0x61, 7, "\xA0\x00\x00\x00\x79\x01\x00"},
{0x52, 7, "\xA0\x00\x00\x00\x79\x02\xF1"},
- {0x62, 7, "\xA0\x00\x00\x00\x79\x01\x01"},
{0x44, 7, "\xA0\x00\x00\x00\x79\x12\x01"},
{0x45, 7, "\xA0\x00\x00\x00\x79\x12\x02"},
}
};
static struct simpletlv_member *
-cac_aca_get_service_table(size_t *r_len)
+cac_aca_get_service_table(size_t *r_len, unsigned int pki_applets)
{
struct simpletlv_member *r = NULL;
- unsigned char *num_entries = NULL;
+ unsigned char *num_entries_byte = NULL;
unsigned char *entry = NULL;
- size_t i = 0;
+ size_t i, j = 0;
+ unsigned int num_entries;
g_assert_nonnull(r_len);
- r = g_malloc(sizeof(struct simpletlv_member)*(service_table.num_entries+1));
+ num_entries = service_table.num_static_entries + pki_applets;
+ r = g_malloc_n(num_entries + 1, sizeof(struct simpletlv_member));
- num_entries = g_malloc(1);
- *num_entries = service_table.num_entries;
+ num_entries_byte = g_malloc(1);
+ *num_entries_byte = num_entries;
r[0].type = SIMPLETLV_TYPE_LEAF;
r[0].tag = CAC_ACR_SERVICE_NUM_ENTRIES;
r[0].length = 1;
- r[0].value.value = num_entries;
- for (i = 1; i <= service_table.num_entries; i++) {
- r[i].type = SIMPLETLV_TYPE_LEAF;
- r[i].tag = CAC_ACR_SERVICE_ENTRY;
- r[i].length = service_table.entries[i].applet_aid_len + 3;
- entry = g_malloc(r[i].length);
+ r[0].value.value = num_entries_byte;
+ j = 1;
+ for (i = 0; i < service_table.num_entries; i++) {
+ /* Skip unused PKI applets */
+ if (i >= pki_applets && i < 10)
+ continue;
+
+ r[j].type = SIMPLETLV_TYPE_LEAF;
+ r[j].tag = CAC_ACR_SERVICE_ENTRY;
+ r[j].length = service_table.entries[i].applet_aid_len + 3;
+ entry = g_malloc(r[j].length);
entry[0] = service_table.entries[i].applet_id;
entry[1] = CAC_ACR_AID;
entry[2] = service_table.entries[i].applet_aid_len;
memcpy(&entry[3], (unsigned char *) &service_table.entries[i],
service_table.entries[i].applet_aid_len);
- r[i].value.value = entry;
+ r[j].value.value = entry;
+ j++;
}
- *r_len = service_table.num_entries + 1;
+ g_assert_cmpint(j, ==, num_entries + 1);
+
+ *r_len = j;
return r;
}
@@ -357,7 +377,6 @@ enum {
#define ACR_MAX_INSTRUCTIONS 5
#define ACR_MAX_APPLET_OBJECTS 5
-#define ACR_MAX_APPLETS 20
struct cac_ins {
unsigned char code;
@@ -379,7 +398,8 @@ struct acr_applet {
};
struct acr_applets {
unsigned int num_applets;
- struct acr_applet applets[ACR_MAX_APPLETS];
+ unsigned int num_static_applets;
+ struct acr_applet applets[];
};
/* Example:
@@ -422,7 +442,109 @@ struct acr_applets {
*/
struct acr_applets applets_table = {
- 16, {
+ 23, 13, {
+ /* Dynamic PKI applets */
+ {0x61, 2, {
+ {"\x01\x00", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x62, 2, {
+ {"\x01\x01", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x63, 2, {
+ {"\x01\x02", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x64, 2, {
+ {"\x01\x03", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x65, 2, {
+ {"\x01\x04", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x66, 2, {
+ {"\x01\x05", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x67, 2, {
+ {"\x01\x06", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x68, 2, {
+ {"\x01\x07", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x69, 2, {
+ {"\x01\x08", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ {0x6a, 2, {
+ {"\x01\x09", 3, {
+ {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
+ {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
+ {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
+ }},
+ {"\xFF\xFF", 1, {
+ {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
+ }}
+ }},
+ /* Static applets */
{0x1F, 1, {
{"\xFF\xFF", 1, {
{VCARD7816_INS_VERIFY, 0x00, ACR_INS_CONFIG_NONE}
@@ -532,16 +654,6 @@ struct acr_applets applets_table = {
{VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
}}
}},
- {0x63, 2, {
- {"\x01\x02", 3, {
- {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
- {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
- {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
- }},
- {"\xFF\xFF", 1, {
- {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
- }}
- }},
{0x51, 1, {
{"\xFF\xFF", 5, {
{CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
@@ -551,16 +663,6 @@ struct acr_applets applets_table = {
{VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
}}
}},
- {0x61, 2, {
- {"\x01\x00", 3, {
- {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
- {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
- {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
- }},
- {"\xFF\xFF", 1, {
- {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
- }}
- }},
{0x52, 1, {
{"\xFF\xFF", 5, {
{CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
@@ -570,16 +672,6 @@ struct acr_applets applets_table = {
{VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
}}
}},
- {0x62, 2, {
- {"\x01\x01", 3, {
- {CAC_UPDATE_BUFFER, 0x04, ACR_INS_CONFIG_NONE},
- {CAC_READ_BUFFER, 0x00, ACR_INS_CONFIG_NONE},
- {CAC_SIGN_DECRYPT, 0x06, ACR_INS_CONFIG_NONE}
- }},
- {"\xFF\xFF", 1, {
- {VCARD7816_INS_VERIFY, 0x10, ACR_INS_CONFIG_NONE},
- }}
- }},
{0x44, 2, {
{"\x12\x01", 3, {
{CAC_UPDATE_BUFFER, 0x06, ACR_INS_CONFIG_NONE},
@@ -704,7 +796,7 @@ failure:
}
static struct simpletlv_member *
-cac_aca_get_applet_acr_coid(unsigned char *coid)
+cac_aca_get_applet_acr_coid(unsigned int pki_applets, unsigned char *coid)
{
struct simpletlv_member *r = NULL;
size_t i, j;
@@ -712,6 +804,10 @@ cac_aca_get_applet_acr_coid(unsigned char *coid)
r = g_malloc(sizeof(struct simpletlv_member));
for (i = 0; i <= applets_table.num_applets; i++) {
+ /* Skip unused PKI applets */
+ if (i >= pki_applets && i < 10)
+ continue;
+
for (j = 0; j < applets_table.applets[i].num_objects; j++) {
if (memcmp(&applets_table.applets[i].objects[j].id, coid, 2) == 0) {
unsigned int buffer_len = ACR_MAX_INSTRUCTIONS * 6 + 2;
@@ -738,11 +834,12 @@ cac_aca_get_applet_acr_coid(unsigned char *coid)
}
static unsigned char
-aid_to_applet_id(unsigned char *aid, unsigned int aid_len)
+aid_to_applet_id(unsigned int pki_applets, unsigned char *aid, unsigned int aid_len)
{
unsigned int i;
for (i = 0; i < service_table.num_entries; i++) {
- if (aid_len == service_table.entries[i].applet_aid_len
+ if ((i < pki_applets || i >= 10)
+ && aid_len == service_table.entries[i].applet_aid_len
&& memcmp(aid, service_table.entries[i].applet_aid, aid_len) == 0)
return service_table.entries[i].applet_id;
}
@@ -750,37 +847,43 @@ aid_to_applet_id(unsigned char *aid, unsigned int aid_len)
}
static struct simpletlv_member *
-cac_aca_get_applet_acr(size_t *acr_len, unsigned char *aid,
+cac_aca_get_applet_acr(unsigned int pki_applets, size_t *acr_len, unsigned char *aid,
unsigned int aid_len)
{
struct simpletlv_member *r = NULL;
- unsigned char *num_applets = NULL;
+ unsigned char *num_applets_byte = NULL;
size_t i, j = 0;
unsigned char applet_id = 0;
+ unsigned int num_applets = applets_table.num_static_applets + pki_applets;
g_assert_nonnull(acr_len);
if (aid != NULL && aid_len != 0) {
/* We are selecting only one applet*/
- applet_id = aid_to_applet_id(aid, aid_len);
+ applet_id = aid_to_applet_id(pki_applets, aid, aid_len);
if (applet_id == 0)
return NULL;
+
r = g_malloc(sizeof(struct simpletlv_member));
} else {
- r = g_malloc(sizeof(struct simpletlv_member)*(applets_table.num_applets+1));
+ r = g_malloc_n(num_applets + 1, sizeof(struct simpletlv_member));
}
if (!applet_id) {
- num_applets = g_malloc(1);
- *num_applets = applets_table.num_applets;
+ num_applets_byte = g_malloc(1);
+ *num_applets_byte = num_applets;
r[j].tag = CAC_ACR_NUM_APPLETS;
r[j].length = 1;
- r[j].value.value = num_applets;
+ r[j].value.value = num_applets_byte;
r[j].type = SIMPLETLV_TYPE_LEAF;
j++;
}
for (i = 0; i < applets_table.num_applets; i++) {
+ /* Skip unused PKI applets */
+ if (i >= pki_applets && i < 10)
+ continue;
+
if (applet_id && applet_id != applets_table.applets[i].id)
continue;
@@ -791,12 +894,13 @@ cac_aca_get_applet_acr(size_t *acr_len, unsigned char *aid,
goto failure;
j++;
}
+
*acr_len = j;
return r;
failure:
simpletlv_free(r, j);
- g_free(num_applets);
+ g_free(num_applets_byte);
return NULL;
}
@@ -955,7 +1059,7 @@ failure:
}
VCardResponse *
-cac_aca_get_applet_acr_response(VCard *card, int Le,
+cac_aca_get_applet_acr_response(VCard *card, int Le, unsigned int pki_applets,
unsigned char *aid, unsigned int aid_len,
unsigned char *coid)
{
@@ -963,7 +1067,7 @@ cac_aca_get_applet_acr_response(VCard *card, int Le,
unsigned char *acr_buffer = NULL;
size_t properties_len;
const struct simpletlv_member *properties;
- size_t acr_len;
+ size_t acr_len = 0;
struct simpletlv_member *acr = NULL;
size_t list_len;
struct simpletlv_member *list = NULL;
@@ -976,7 +1080,7 @@ cac_aca_get_applet_acr_response(VCard *card, int Le,
/* getting the table for COID (2B) */
acr_len = 1; // returns exactly one element if found
- acr = cac_aca_get_applet_acr_coid(coid);
+ acr = cac_aca_get_applet_acr_coid(pki_applets, coid);
if (!acr) {
/* did not find the COID */
r = vcard_make_response(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA);
@@ -984,7 +1088,7 @@ cac_aca_get_applet_acr_response(VCard *card, int Le,
}
} else {
/* getting the table for AID or the whole */
- acr = cac_aca_get_applet_acr(&acr_len, aid, aid_len);
+ acr = cac_aca_get_applet_acr(pki_applets, &acr_len, aid, aid_len);
if (!acr && aid_len > 0) {
/* did not find the AID */
r = vcard_make_response(VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
@@ -1026,7 +1130,7 @@ cac_aca_get_amp_response(VCard *card, int Le)
unsigned char *amp_buffer = NULL;
size_t properties_len;
const struct simpletlv_member *properties;
- size_t amp_len;
+ size_t amp_len = 0;
struct simpletlv_member *amp = NULL;
size_t list_len;
struct simpletlv_member *list = NULL;
@@ -1062,13 +1166,13 @@ failure:
}
VCardResponse *
-cac_aca_get_service_response(VCard *card, int Le)
+cac_aca_get_service_response(VCard *card, int Le, unsigned int pki_applets)
{
size_t service_buffer_len;
unsigned char *service_buffer = NULL;
size_t properties_len;
const struct simpletlv_member *properties;
- size_t service_len;
+ size_t service_len = 0;
struct simpletlv_member *service = NULL;
size_t list_len;
struct simpletlv_member *list = NULL;
@@ -1076,7 +1180,7 @@ cac_aca_get_service_response(VCard *card, int Le)
/* Prepare the SimpleTLV structures */
properties = cac_aca_get_properties(&properties_len);
- service = cac_aca_get_service_table(&service_len);
+ service = cac_aca_get_service_table(&service_len, pki_applets);
if (service == NULL)
goto failure;
diff --git a/src/cac-aca.h b/src/cac-aca.h
index bbe738f..cb3a606 100644
--- a/src/cac-aca.h
+++ b/src/cac-aca.h
@@ -22,11 +22,11 @@ VCardResponse *
cac_aca_get_acr_response(VCard *card, int Le, unsigned char *acrid);
VCardResponse *
-cac_aca_get_applet_acr_response(VCard *card, int Le,
+cac_aca_get_applet_acr_response(VCard *card, int Le, unsigned int pki_applets,
unsigned char *aid, unsigned int aid_len,
unsigned char *coid);
VCardResponse *
cac_aca_get_amp_response(VCard *card, int Le);
VCardResponse *
-cac_aca_get_service_response(VCard *card, int Le);
+cac_aca_get_service_response(VCard *card, int Le, unsigned int pki_applets);
diff --git a/src/cac.c b/src/cac.c
index cc07923..3b22de5 100644
--- a/src/cac.c
+++ b/src/cac.c
@@ -40,6 +40,7 @@ typedef struct CACCCCAppletDataStruct {
/* private data for ACA container */
typedef struct CACACAAppletDataStruct {
+ unsigned int pki_applets;
/* At the moment mostly in cac-aca.c */
} CACACAAppletData;
@@ -474,10 +475,12 @@ cac_applet_aca_process_apdu(VCard *card, VCardAPDU *apdu,
VCardResponse **response)
{
VCardStatus ret = VCARD_FAIL;
+ CACACAAppletData *aca_applet;
VCardAppletPrivate *applet_private;
applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
assert(applet_private);
+ aca_applet = &(applet_private->u.aca_data);
switch (apdu->a_ins) {
case CAC_GET_ACR:
@@ -519,7 +522,7 @@ cac_applet_aca_process_apdu(VCard *card, VCardAPDU *apdu,
break;
}
*response = cac_aca_get_applet_acr_response(card, apdu->a_Le,
- NULL, 0, NULL);
+ aca_applet->pki_applets, NULL, 0, NULL);
break;
case 0x11:
@@ -531,7 +534,7 @@ cac_applet_aca_process_apdu(VCard *card, VCardAPDU *apdu,
break;
}
*response = cac_aca_get_applet_acr_response(card, apdu->a_Le,
- apdu->a_body, apdu->a_Lc, NULL);
+ aca_applet->pki_applets, apdu->a_body, apdu->a_Lc, NULL);
break;
case 0x12:
@@ -543,7 +546,7 @@ cac_applet_aca_process_apdu(VCard *card, VCardAPDU *apdu,
break;
}
*response = cac_aca_get_applet_acr_response(card, apdu->a_Le,
- NULL, 0, apdu->a_body);
+ aca_applet->pki_applets, NULL, 0, apdu->a_body);
break;
case 0x20:
@@ -562,7 +565,8 @@ cac_applet_aca_process_apdu(VCard *card, VCardAPDU *apdu,
VCARD7816_STATUS_ERROR_DATA_INVALID);
break;
}
- *response = cac_aca_get_service_response(card, apdu->a_Le);
+ *response = cac_aca_get_service_response(card, apdu->a_Le,
+ aca_applet->pki_applets);
break;
default:
*response = vcard_make_response(
@@ -1240,7 +1244,7 @@ cac_new_ccc_applet_private(int cert_count)
buffer[2].value.value = cg_version;
buffer[3].value.value = cardurl[0]; /* ACA */
- if (cert_count > 13) {
+ if (cert_count > 10) {
// XXX too many objects for now
g_debug("Too many PKI objects");
return NULL;
@@ -1396,8 +1400,9 @@ failure:
}
static VCardAppletPrivate *
-cac_new_aca_applet_private(void)
+cac_new_aca_applet_private(int cert_count)
{
+ CACACAAppletData *aca_applet_data;
VCardAppletPrivate *applet_private;
/* ACA applet Properties ex.:
@@ -1417,6 +1422,7 @@ cac_new_aca_applet_private(void)
/* Create the private data structure */
applet_private = g_new0(VCardAppletPrivate, 1);
+ aca_applet_data = &(applet_private->u.aca_data);
if (applet_private == NULL)
goto failure;
@@ -1424,6 +1430,8 @@ cac_new_aca_applet_private(void)
applet_private->properties = properties;
applet_private->properties_len = 1;
+ aca_applet_data->pki_applets = cert_count;
+
return applet_private;
failure:
@@ -1438,12 +1446,12 @@ failure:
* create a new ACA applet
*/
static VCardApplet *
-cac_new_aca_applet(void)
+cac_new_aca_applet(int cert_count)
{
VCardAppletPrivate *applet_private;
VCardApplet *applet;
- applet_private = cac_new_aca_applet_private();
+ applet_private = cac_new_aca_applet_private(cert_count);
if (applet_private == NULL) {
goto failure;
}
@@ -1521,6 +1529,11 @@ cac_card_init(VReader *reader, VCard *card,
/* CAC Cards are VM Cards */
vcard_set_type(card, VCARD_VM);
+ if (cert_count > 10) {
+ g_debug("Too many PKI objects");
+ goto failure;
+ }
+
/* create one PKI applet for each cert */
for (i = 0; i < cert_count; i++) {
applet = cac_new_pki_applet(i, cert[i], cert_len[i], key[i]);
@@ -1531,7 +1544,7 @@ cac_card_init(VReader *reader, VCard *card,
}
/* create a ACA applet, to list access rules */
- applet = cac_new_aca_applet();
+ applet = cac_new_aca_applet(cert_count);
if (applet == NULL) {
goto failure;
}