From 22f067863a86672301fabe520a531cb7bc73dd4d Mon Sep 17 00:00:00 2001 From: "viktor.tarasov" Date: Sat, 13 Mar 2010 19:48:09 +0000 Subject: [PATCH] libopensc emu: more general implementation of the postponed DF parsing In previous version the card specific 'parse_df' handler was a part of 'sc_pkcs15_df'. Now the placehold ('sc_pkcs15_operations') created for the all card emulator specific operations . git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4109 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15-gemsafeV1.c | 2 +- src/libopensc/pkcs15-oberthur.c | 28 +++++++++++++--------------- src/libopensc/pkcs15-syn.c | 8 ++++---- src/libopensc/pkcs15.c | 29 ++++++++++++++--------------- src/libopensc/pkcs15.h | 14 +++++++++----- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index b9b28664..0ae304c4 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -379,7 +379,7 @@ sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type) if (!file) return NULL; sc_format_path("11001101", &file->path); - sc_pkcs15_add_df(p15card, type, &file->path, file, NULL); + sc_pkcs15_add_df(p15card, type, &file->path, file); sc_file_free(file); created++; } diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 3fb940c0..69982bfc 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -1,7 +1,7 @@ /* * PKCS15 emulation layer for Oberthur card. * - * Copyright (C) 2009, Viktor Tarasov + * Copyright (C) 2010, Viktor Tarasov * Copyright (C) 2005, Andrea Frigido * Copyright (C) 2005, Sirio Capizzi * Copyright (C) 2004, Antonino Iacono @@ -64,7 +64,7 @@ #define USAGE_PUB_SIGN (SC_PKCS15_PRKEY_USAGE_VERIFY | SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER) #define PIN_DOMAIN_LABEL "SCM" -static const unsigned char PinDomainID[3] = {0x53, 0x43, 0x4D}; +const unsigned char PinDomainID[3] = {0x53, 0x43, 0x4D}; #define AWP_PIN_DF "3F005011" #define AWP_TOKEN_INFO "3F0050111000" @@ -92,14 +92,13 @@ static int sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *, unsigned); static int sc_pkcs15emu_oberthur_add_data(struct sc_pkcs15_card *, unsigned, unsigned, int); int sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card *, struct sc_pkcs15emu_opt *); -int sc_pkcs15emu_oberthur_parse_df_ex(struct sc_pkcs15_card *, struct sc_pkcs15_df *); static int sc_oberthur_parse_tokeninfo (struct sc_pkcs15_card *, unsigned char *, size_t, int); static int sc_oberthur_parse_containers (struct sc_pkcs15_card *, unsigned char *, size_t, int); static int sc_oberthur_parse_publicinfo (struct sc_pkcs15_card *, unsigned char *, size_t, int); static int sc_oberthur_parse_privateinfo (struct sc_pkcs15_card *, unsigned char *, size_t, int); -static int sc_oberthur_parse_df_ex(struct sc_pkcs15_card *, struct sc_pkcs15_df *parse_df); +static int sc_awp_parse_df(struct sc_pkcs15_card *, struct sc_pkcs15_df *); struct crypto_container { unsigned int id_pub; @@ -126,7 +125,7 @@ static struct { int (*parser)(struct sc_pkcs15_card *, unsigned char *, size_t, int); int postpone_allowed; } oberthur_infos[] = { - // Never change the following order + /* Never change the following order */ { "Token info", AWP_TOKEN_INFO, NULL, 0, sc_oberthur_parse_tokeninfo, 0}, { "Containers MS", AWP_CONTAINERS_MS, NULL, 0, sc_oberthur_parse_containers, 0}, { "Public objects list", AWP_OBJECTS_LIST_PUB, NULL, 0, sc_oberthur_parse_publicinfo, 0}, @@ -516,7 +515,7 @@ sc_oberthur_parse_privateinfo (struct sc_pkcs15_card *p15card, sc_debug(ctx, "postpone adding of the private keys"); sc_format_path("5011A5A5", &path); - rv = sc_pkcs15_add_df(p15card, SC_PKCS15_PRKDF, &path, NULL, sc_oberthur_parse_df_ex); + rv = sc_pkcs15_add_df(p15card, SC_PKCS15_PRKDF, &path, NULL); SC_TEST_RET(ctx, rv, "Add PrkDF error"); no_more_private_keys = 1; } @@ -916,6 +915,8 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) SC_FUNC_CALLED(card->ctx, 1); sc_bin_to_hex(card->serialnr.value, card->serialnr.len, serial, sizeof(serial), 0); p15card->serial_number = strdup(serial); + + p15card->ops.parse_df = sc_awp_parse_df; sc_debug(ctx, "Oberthur init: serial %s", p15card->serial_number); @@ -1051,7 +1052,7 @@ sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card * p15card, static int -sc_oberthur_parse_df_ex(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) +sc_awp_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) { struct sc_context *ctx = p15card->card->ctx; unsigned char *buf = NULL; @@ -1073,14 +1074,11 @@ sc_oberthur_parse_df_ex(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) if (buf) free(buf); - if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { - rv = 0; - } - else { - SC_TEST_RET(ctx, rv, "Parse DF: private info parse error"); - df->enumerated = 1; - } + if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) + SC_FUNC_RETURN(ctx, 1, SC_SUCCESS); + + SC_TEST_RET(ctx, rv, "Parse DF: private info parse error"); + df->enumerated = 1; SC_FUNC_RETURN(ctx, 1, rv); } - diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 978ebd8c..7a8d7e8e 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -81,7 +81,7 @@ static struct { { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex}, { "tccardos", sc_pkcs15emu_tccardos_init_ex }, { "entersafe", sc_pkcs15emu_entersafe_init_ex }, - { "pteid", sc_pkcs15emu_pteid_init_ex }, + { "pteid", sc_pkcs15emu_pteid_init_ex }, { "oberthur", sc_pkcs15emu_oberthur_init_ex }, { NULL, NULL } }; @@ -310,7 +310,7 @@ static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, if (!file) return NULL; sc_format_path("11001101", &file->path); - sc_pkcs15_add_df(p15card, type, &file->path, file, NULL); + sc_pkcs15_add_df(p15card, type, &file->path, file); sc_file_free(file); created++; } @@ -436,9 +436,9 @@ sc_pkcs15emu_postponed_load(sc_pkcs15_card_t *p15card, unsigned long *loaded_mas sc_debug(ctx, "Type:%X,enumerated:%i", df->type, df->enumerated); if (df->enumerated) continue; - if (!df->parse_handler) + if (!p15card->ops.parse_df) continue; - r = df->parse_handler(p15card, df); + r = p15card->ops.parse_df(p15card, df); SC_TEST_RET(ctx, r, "DF parse error"); if (loaded_mask) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index adf8cc4c..d34d2c35 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -337,7 +337,7 @@ static int parse_odf(const u8 * buf, size_t buflen, struct sc_pkcs15_card *p15ca r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path); if (r < 0) return r; - r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path, NULL, NULL); + r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path, NULL); if (r) return r; } @@ -886,15 +886,8 @@ __sc_pkcs15_search_objects(sc_pkcs15_card_t *p15card, continue; /* Enumerate the DF's, so p15card->obj_list is * populated. */ - if (df->parse_handler) { - r = df->parse_handler(p15card, df); - SC_TEST_RET(p15card->card->ctx, r, "DF parsing failed"); - } - else { - r = sc_pkcs15_parse_df(p15card, df); - SC_TEST_RET(p15card->card->ctx, r, "DF parsing failed"); - df->enumerated = 1; - } + r = sc_pkcs15_parse_df(p15card, df); + SC_TEST_RET(p15card->card->ctx, r, "DF parsing failed"); } /* And now loop over all objects */ @@ -1353,8 +1346,7 @@ void sc_pkcs15_free_object(struct sc_pkcs15_object *obj) int sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, unsigned int type, const sc_path_t *path, - const sc_file_t *file, - int (*parse_handler)(struct sc_pkcs15_card *, struct sc_pkcs15_df *)) + const sc_file_t *file) { struct sc_pkcs15_df *p, *newdf; @@ -1367,7 +1359,6 @@ int sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, return SC_ERROR_OUT_OF_MEMORY; newdf->path = *path; newdf->type = type; - newdf->parse_handler = parse_handler; if (file != NULL) { sc_file_dup(&newdf->file, file); if (newdf->file == NULL) { @@ -1476,8 +1467,11 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *, const u8 **nbuf, size_t *nbufsize) = NULL; - if (df->parse_handler) - return df->parse_handler(p15card, df); + if (p15card->ops.parse_df) + return p15card->ops.parse_df(p15card, df); + + if (df->enumerated) + return SC_SUCCESS; switch (df->type) { case SC_PKCS15_PRKDF: @@ -1544,8 +1538,13 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, goto ret; } }; + + if (r > 0) + r = 0; ret: free(buf); + if (!r) + df->enumerated = 1; return r; } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 62c03cb6..6260bc67 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -366,8 +366,6 @@ struct sc_pkcs15_df { unsigned int type; int enumerated; - int (*parse_handler)(struct sc_pkcs15_card *, struct sc_pkcs15_df *); - struct sc_pkcs15_df *next, *prev; }; typedef struct sc_pkcs15_df sc_pkcs15_df_t; @@ -401,6 +399,10 @@ typedef struct sc_pkcs15_tokeninfo { size_t num_seInfo; } sc_pkcs15_tokeninfo_t; +struct sc_pkcs15_operations { + int (*parse_df)(struct sc_pkcs15_card *, struct sc_pkcs15_df *); +}; + typedef struct sc_pkcs15_card { sc_card_t *card; char *label; @@ -433,6 +435,9 @@ typedef struct sc_pkcs15_card { void *dll_handle; /* shared lib for emulated cards */ char *preferred_language; + + struct sc_pkcs15_operations ops; + } sc_pkcs15_card_t; #define SC_PKCS15_CARD_FLAG_READONLY 0x01 @@ -652,9 +657,8 @@ int sc_pkcs15_add_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj); void sc_pkcs15_remove_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj); -int sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, unsigned int type, - const sc_path_t *path, const struct sc_file *file, - int (*)(struct sc_pkcs15_card *, struct sc_pkcs15_df *)); +int sc_pkcs15_add_df(struct sc_pkcs15_card *, unsigned int, + const sc_path_t *, const struct sc_file *); void sc_pkcs15_remove_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df);