diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 0bd2e720..2846d34d 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -128,6 +128,7 @@ sc_pkcs15_erase_pubkey sc_pkcs15_find_cert_by_id sc_pkcs15_find_data_object_by_app_oid sc_pkcs15_find_data_object_by_id +sc_pkcs15_find_data_object_by_name sc_pkcs15_find_object_by_id sc_pkcs15_find_pin_by_auth_id sc_pkcs15_find_pin_by_reference diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 82e57f79..8e6ec5c2 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1005,6 +1005,17 @@ static int compare_obj_path(sc_pkcs15_object_t *obj, const sc_path_t *path) return 0; } +static int compare_obj_data_name(sc_pkcs15_object_t *obj, const char *app_label, const char *label) +{ + struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) obj->data; + + if (obj->type != SC_PKCS15_TYPE_DATA_OBJECT) + return 0; + + return !strcmp(cinfo->app_label, app_label) && + !strcmp(obj->label, label); +} + static int compare_obj_key(struct sc_pkcs15_object *obj, void *arg) { struct sc_pkcs15_search_key *sk = (struct sc_pkcs15_search_key *) arg; @@ -1021,6 +1032,13 @@ static int compare_obj_key(struct sc_pkcs15_object *obj, void *arg) return 0; if (sk->path && !compare_obj_path(obj, sk->path)) return 0; + if ( + sk->app_label && sk->label && + !compare_obj_data_name(obj, sk->app_label, sk->label) + ) { + return 0; + } + return 1; } @@ -1146,6 +1164,28 @@ int sc_pkcs15_find_data_object_by_app_oid(struct sc_pkcs15_card *p15card, return 0; } +int sc_pkcs15_find_data_object_by_name(struct sc_pkcs15_card *p15card, + const char *app_label, + const char *label, + struct sc_pkcs15_object **out) +{ + sc_pkcs15_search_key_t sk; + int r; + + memset(&sk, 0, sizeof(sk)); + sk.app_label = app_label; + sk.label = label; + + r = __sc_pkcs15_search_objects(p15card, 0, SC_PKCS15_TYPE_DATA_OBJECT, + compare_obj_key, &sk, + out, 1); + if (r < 0) + return r; + if (r == 0) + return SC_ERROR_OBJECT_NOT_FOUND; + return 0; +} + int sc_pkcs15_find_prkey_by_id_usage(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id, unsigned int usage, diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index df3a09c4..38feea9c 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -476,6 +476,10 @@ int sc_pkcs15_find_data_object_by_id(struct sc_pkcs15_card *p15card, int sc_pkcs15_find_data_object_by_app_oid(struct sc_pkcs15_card *p15card, const struct sc_object_id *app_oid, struct sc_pkcs15_object **out); +int sc_pkcs15_find_data_object_by_name(struct sc_pkcs15_card *p15card, + const char *app_label, + const char *label, + struct sc_pkcs15_object **out); void sc_pkcs15_free_data_object(struct sc_pkcs15_data *data_object); int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card, @@ -662,6 +666,8 @@ typedef struct sc_pkcs15_search_key { unsigned int match_reference : 1; int reference; + const char * app_label; + const char * label; } sc_pkcs15_search_key_t; int sc_pkcs15_search_objects(sc_pkcs15_card_t *, sc_pkcs15_search_key_t *, diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 2a23a1a5..17ee26c0 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1233,11 +1233,19 @@ do_delete_objects(struct sc_profile *profile, unsigned int myopt_delete_flags) if (myopt_delete_flags & SC_PKCS15INIT_TYPE_DATA) { struct sc_object_id app_oid; sc_pkcs15_object_t *obj; - if (opt_application_id == NULL) - util_fatal("Specify the --application-id for the data object to be deleted\n"); - sc_format_oid(&app_oid, opt_application_id); - r = sc_pkcs15_find_data_object_by_app_oid(p15card, &app_oid, &obj); + if (opt_application_id != NULL) { + sc_format_oid(&app_oid, opt_application_id); + + r = sc_pkcs15_find_data_object_by_app_oid(p15card, &app_oid, &obj); + } + else if (opt_application_name != NULL && opt_label != NULL) { + r = sc_pkcs15_find_data_object_by_name(p15card, opt_application_name, opt_label, &obj); + } + else { + util_fatal("Specify the --application-id or --application-name and --label for the data object to be deleted\n"); + } + if (r >= 0) { r = sc_pkcs15init_delete_object(p15card, profile, obj); if (r >= 0)