diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index d46b349c..c49b60fb 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1378,16 +1378,43 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card, { struct sc_pkcs15_data_info *data_object_info; struct sc_pkcs15_object *object; + struct sc_pkcs15_object *objs[32]; const char *label; - int r; + int r, i; + unsigned int tid = 0x01; if ((label = args->label) == NULL) label = "Data Object"; - /* Select an ID if the user didn't specify one, otherwise - * make sure it's unique */ - if ((r = select_id(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &args->id, NULL, NULL, NULL)) < 0) - return r; + if (!args->id.len) { + /* Select an ID if the user didn't specify one, otherwise + * make sure it's unique (even though data objects doesn't + * have a pkcs15 id we need one here to create a unique + * file id from the data file template */ + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32); + if (r < 0) + return r; + for (i = 0; i < r; i++) { + u8 cid; + struct sc_pkcs15_data_info *cinfo; + cinfo = (struct sc_pkcs15_data_info *) objs[i]->data; + if (!cinfo->path.len) + continue; + cid = cinfo->path.value[cinfo->path.len - 1]; + if (cid >= tid) + tid = cid + 1; + } + if (tid > 0xff) + /* too many data objects ... */ + return SC_ERROR_TOO_MANY_OBJECTS; + args->id.len = 1; + args->id.value[0] = tid; + } else { + /* in case the user specifies an id it should be at most + * one byte long */ + if (args->id.len > 1) + return SC_ERROR_INVALID_ARGUMENTS; + } /* Set the USER PIN reference from args */ r = set_user_pin_from_authid(p15card, profile, &args->auth_id); @@ -1396,7 +1423,6 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card, object = sc_pkcs15init_new_object(SC_PKCS15_TYPE_DATA_OBJECT, label, &args->auth_id, NULL); data_object_info = (sc_pkcs15_data_info_t *) object->data; - data_object_info->id = args->id; if (label != NULL) { strncpy(data_object_info->app_label, label, sizeof(data_object_info->app_label) - 1); diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 4f57784a..a4e1c1e3 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -87,7 +87,7 @@ const char *option_help[] = { "Stores card info to cache", "Reads certificate with ID ", "Lists certificates", - "Reads data object with label ", + "Reads data object with applicationName or OID ", "Lists data objects", "Lists PIN codes", "Unblock PIN code", @@ -274,25 +274,33 @@ int read_certificate(void) int read_data_object(void) { - int r, i, count; - struct sc_pkcs15_id id; + int r, i, count, oid_len = 0; struct sc_pkcs15_object *objs[32]; + struct sc_object_id oid; - id.len = SC_PKCS15_MAX_ID_SIZE; - sc_pkcs15_hex_string_to_id(opt_data, &id); - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32); if (r < 0) { fprintf(stderr, "Data object enumeration failed: %s\n", sc_strerror(r)); return 1; } count = r; + + r = parse_application_id(&oid, opt_data); + if (r == SC_SUCCESS) { + while (oid.value[oid_len] >= 0) oid_len++; + } + for (i = 0; i < count; i++) { struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data; struct sc_pkcs15_data *data_object; - if (memcmp(opt_data, &cinfo->app_label, strlen(opt_data)) != 0) - continue; + if (oid_len) { + if (memcmp(oid.value, cinfo->app_oid.value, sizeof(int) * oid_len)) + continue; + } else { + if (memcmp(opt_data, &cinfo->app_label, strlen(opt_data))) + continue; + } if (verbose) printf("Reading data object with label '%s'\n", opt_data); @@ -312,9 +320,7 @@ int read_data_object(void) int list_data_objects(void) { int r, i, count; - struct sc_pkcs15_id id; struct sc_pkcs15_object *objs[32]; - id.len = SC_PKCS15_MAX_ID_SIZE; r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32); if (r < 0) { @@ -341,6 +347,7 @@ int list_data_objects(void) printf("\n"); } else printf("NONE\n"); + printf("Path : %s\n", sc_print_path(&cinfo->path)); r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object); if (r) { fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r)); diff --git a/src/tools/util.c b/src/tools/util.c index 5944ae7f..88584116 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -272,22 +272,31 @@ warn(const char *fmt, ...) } -void parse_application_id(struct sc_object_id *oid, char *oid_str) +int parse_application_id(struct sc_object_id *oid, char *oid_str) { - int ii; - char *nb; + int ii, ret = SC_ERROR_INVALID_ARGUMENTS; + char *p, *q; if (!oid) - return; - + return ret; + /* init oid */ for (ii=0; iivalue[ii] = -1; - nb = strtok(oid_str, "."); - for (ii=0; nb && ii < SC_MAX_OBJECT_ID_OCTETS; ii++) { - oid->value[ii] = strtol(nb, NULL, 10); - nb = strtok(NULL, "."); + if (!(p = oid_str)) + return ret; + + for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++) { + oid->value[ii] = strtol(p, &q, 10); + if (!*q) + break; + if (!(q[0] == '.' && isdigit(q[1]))) { + return ret; + } + p = q + 1; } + + return SC_SUCCESS; } diff --git a/src/tools/util.h b/src/tools/util.h index d5df5709..14d1bab6 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -40,7 +40,7 @@ void fatal(const char *fmt, ...); /* All singing all dancing card connect routine */ int connect_card(struct sc_context *, struct sc_card **, int reader_id, int slot_id, int wait, int verbose); -void parse_application_id(struct sc_object_id *oid, char *oid_str); +int parse_application_id(struct sc_object_id *oid, char *oid_str); #ifdef __cplusplus }