diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 51bab689..5854e3ab 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -72,12 +72,10 @@ /* ISO 7816 CLA values used by COOLKEY */ #define ISO7816_CLASS 0x00 -#define GLOBAL_PLATFORM_CLASS 0x80 #define COOLKEY_CLASS 0xb0 /* ISO 71816 INS values used by COOLKEY */ #define ISO7816_INS_SELECT_FILE 0xa4 -#define ISO7816_INS_GET_DATA 0xca /* COOLKEY specific INS values (public) */ #define COOLKEY_INS_GET_LIFE_CYCLE 0xf2 @@ -137,30 +135,6 @@ typedef struct coolkey_status { u8 logged_in_identities[2]; } coolkey_status_t; -/* returned by the iso get status apdu with the global platform cplc data parameters */ -typedef struct global_platform_cplc_data { - u8 tag[2]; - u8 length; - u8 ic_fabricator[2]; - u8 ic_type[2]; - u8 os_id[2]; - u8 os_date[2]; - u8 os_level[2]; - u8 fabrication_data[2]; - u8 ic_serial_number[4]; - u8 ic_batch[2]; - u8 module_fabricator[2]; - u8 packing_data[2]; - u8 icc_manufacturer[2]; - u8 ic_embedding_data[2]; - u8 pre_personalizer[2]; - u8 ic_pre_personalization_data[2]; - u8 ic_pre_personalization_id[4]; - u8 ic_personalizaer[2]; - u8 ic_personalization_data[2]; - u8 ic_personalization_id[4]; -} global_platform_cplc_data_t; - /* format of the coolkey_cuid, either constructed from cplc data or read from the combined object */ typedef struct coolkey_cuid { u8 ic_fabricator[2]; @@ -1089,25 +1063,6 @@ coolkey_get_life_cycle(sc_card_t *card, coolkey_life_cycle_t *life_cycle) return SC_SUCCESS; } - -/* should be general global platform call */ -static int -coolkey_get_cplc_data(sc_card_t *card, global_platform_cplc_data_t *cplc_data) -{ - size_t len = sizeof(global_platform_cplc_data_t); - u8 *receive_buf = (u8 *)cplc_data; - int rc; - - rc = coolkey_apdu_io(card, GLOBAL_PLATFORM_CLASS, ISO7816_INS_GET_DATA, 0x9f, 0x7f, - NULL, 0, &receive_buf, &len, NULL, 0); - /* We expect this will fill the whole structure in the argument. - * If we got something else, report error */ - if ((size_t)rc < sizeof(cplc_data)) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_CORRUPTED_DATA); - } - LOG_FUNC_RETURN(card->ctx, rc); -} - /* select the coolkey applet */ static int coolkey_select_applet(sc_card_t *card) { @@ -2240,7 +2195,7 @@ static int coolkey_initialize(sc_card_t *card) goto cleanup; } - r = coolkey_get_cplc_data(card, &cplc_data); + r = gp_get_cplc_data(card, &cplc_data); if (r < 0) { goto cleanup; } diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c index 4a7756f2..61dbdb76 100644 --- a/src/libopensc/gp.c +++ b/src/libopensc/gp.c @@ -25,6 +25,13 @@ #endif #include "internal.h" +#include "gp.h" + +/* ISO 7816 CLA values */ +#define GLOBAL_PLATFORM_CLASS 0x80 + +/* ISO 71816 INS values */ +#define ISO7816_INS_GET_DATA 0xca /* The AID of the Card Manager defined by Open Platform 2.0.1 specification */ static const struct sc_aid gp_card_manager = { @@ -50,7 +57,6 @@ gp_select_aid(struct sc_card *card, const struct sc_aid *aid) apdu.datalen = aid->len; rv = sc_transmit_apdu(card, &apdu); - if (rv < 0) return rv; @@ -82,3 +88,34 @@ gp_select_isd_rid(struct sc_card *card) rv = gp_select_aid(card, &gp_isd_rid); LOG_FUNC_RETURN(card->ctx, rv); } + +/* Get Card Production Life-Cycle information */ +int +gp_get_cplc_data(struct sc_card *card, global_platform_cplc_data_t *cplc_data) +{ + size_t len = sizeof(global_platform_cplc_data_t); + u8 *receive_buf = (u8 *)cplc_data; + struct sc_apdu apdu; + int rc; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, ISO7816_INS_GET_DATA, 0x9f, 0x7f); + apdu.cla = GLOBAL_PLATFORM_CLASS; + apdu.resp = receive_buf; + apdu.resplen = len; + apdu.le = len; + + rc = sc_transmit_apdu(card, &apdu); + if (rc < 0) + LOG_FUNC_RETURN(card->ctx, rc); + + rc = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (rc < 0) + LOG_FUNC_RETURN(card->ctx, rc); + + /* We expect this will fill the whole structure in the argument. + * If we got something else, report error */ + if ((size_t)apdu.resplen < sizeof(cplc_data)) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CORRUPTED_DATA); + } + LOG_FUNC_RETURN(card->ctx, apdu.resplen); +} diff --git a/src/libopensc/gp.h b/src/libopensc/gp.h index dd4e73b6..de49e343 100644 --- a/src/libopensc/gp.h +++ b/src/libopensc/gp.h @@ -32,9 +32,34 @@ extern "C" { #endif +/* returned by the iso get status apdu with the global platform cplc data parameters */ +typedef struct global_platform_cplc_data { + u8 tag[2]; + u8 length; + u8 ic_fabricator[2]; + u8 ic_type[2]; + u8 os_id[2]; + u8 os_date[2]; + u8 os_level[2]; + u8 fabrication_data[2]; + u8 ic_serial_number[4]; + u8 ic_batch[2]; + u8 module_fabricator[2]; + u8 packing_data[2]; + u8 icc_manufacturer[2]; + u8 ic_embedding_data[2]; + u8 pre_personalizer[2]; + u8 ic_pre_personalization_data[2]; + u8 ic_pre_personalization_id[4]; + u8 ic_personalizaer[2]; + u8 ic_personalization_data[2]; + u8 ic_personalization_id[4]; +} global_platform_cplc_data_t; + int gp_select_aid(struct sc_card *card, const struct sc_aid *aid); int gp_select_card_manager(struct sc_card *card); int gp_select_isd_rid(struct sc_card *card); +int gp_get_cplc_data(struct sc_card *card, global_platform_cplc_data_t *cplc_data); #ifdef __cplusplus }