diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index d3d49e0a..51f5e264 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -281,3 +281,4 @@ sc_pkcs15init_update_any_df sc_pkcs15init_update_certificate sc_pkcs15init_update_file sc_pkcs15init_verify_secret +sc_pkcs15init_sanity_check diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 7856f245..703cc1ce 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -138,6 +138,8 @@ struct sc_pkcs15init_operations { struct sc_pkcs15_tokeninfo *); int (*emu_write_info)(struct sc_profile *, struct sc_pkcs15_card *, struct sc_pkcs15_object *); + + int (*sanity_check)(struct sc_profile *, struct sc_pkcs15_card *); }; /* Do not change these or reorder these */ @@ -363,6 +365,8 @@ extern int sc_pkcs15_create_pin_domain(struct sc_profile *, struct sc_pkcs15_car extern int sc_pkcs15init_get_pin_reference(struct sc_pkcs15_card *, struct sc_profile *, unsigned, int); +extern int sc_pkcs15init_sanity_check(struct sc_pkcs15_card *, struct sc_profile *); + extern struct sc_pkcs15init_operations *sc_pkcs15init_get_gpk_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cryptoflex_ops(void); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index c0a2aebd..838adb11 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1021,7 +1021,8 @@ sc_pkcs15_create_pin_domain(struct sc_profile *profile, struct sc_file *df = profile->df_info->file; int r; - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "create PIN domain (path:%s,ID:%s)", sc_print_path(&df->path), sc_pkcs15_print_id(id)); + sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "create PIN domain (path:%s,ID:%s)", + sc_print_path(&df->path), sc_pkcs15_print_id(id)); /* Instantiate PIN directory just below the application DF */ r = sc_profile_instantiate_template(profile, "pin-domain", &df->path, "pin-dir", id, ret); if (r >= 0) { @@ -3475,6 +3476,23 @@ sc_pkcs15init_get_label(struct sc_profile *profile, const char **res) } +/* + * Card specific sanity check procedure. + */ +int +sc_pkcs15init_sanity_check(struct sc_pkcs15_card *p15card, struct sc_profile *profile) +{ + struct sc_context *ctx = p15card->card->ctx; + int rv = SC_ERROR_NOT_SUPPORTED; + + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + if (profile->ops->sanity_check) + rv = profile->ops->sanity_check(profile, p15card); + + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv); +} + + static int sc_pkcs15init_qualify_pin(struct sc_card *card, const char *pin_name, unsigned int pin_len, struct sc_pkcs15_pin_info *pin_info) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 436308f0..5cebbd36 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -95,6 +95,7 @@ static int do_finalize_card(sc_card_t *, struct sc_profile *); static int do_read_data_object(const char *name, u8 **out, size_t *outlen); static int do_store_data_object(struct sc_profile *profile); +static int do_sanity_check(struct sc_profile *profile); static int init_keyargs(struct sc_pkcs15init_prkeyargs *); static void init_gost_params(struct sc_pkcs15init_keyarg_gost_params *, EVP_PKEY *); @@ -133,6 +134,7 @@ enum { OPT_PUK_ID, OPT_PUK_LABEL, OPT_VERIFY_PIN, + OPT_SANITY_CHECK, OPT_PIN1 = 0x10000, /* don't touch these values */ OPT_PUK1 = 0x10001, @@ -155,6 +157,7 @@ const struct option options[] = { { "store-data", required_argument, NULL, 'W' }, { "delete-objects", required_argument, NULL, 'D' }, { "change-attributes", required_argument, NULL, 'A' }, + { "sanity-check", no_argument, NULL, OPT_SANITY_CHECK}, { "reader", required_argument, NULL, 'r' }, { "pin", required_argument, NULL, OPT_PIN1 }, @@ -211,6 +214,7 @@ static const char * option_help[] = { "Store a data object", "Delete object(s) (use \"help\" for more information)", "Change attribute(s) (use \"help\" for more information)", + "Card specific sanity check and possibly update procedure", "Specify which reader to use", "Specify PIN", @@ -268,6 +272,7 @@ enum { ACTION_FINALIZE_CARD, ACTION_DELETE_OBJECTS, ACTION_CHANGE_ATTRIBUTES, + ACTION_SANITY_CHECK, ACTION_MAX }; @@ -286,6 +291,7 @@ static const char *action_names[] = { "finalizing card", "delete object(s)", "change attribute(s)", + "check card's sanity", }; #define MAX_CERTS 4 @@ -520,6 +526,9 @@ main(int argc, char **argv) case ACTION_FINALIZE_CARD: r = do_finalize_card(card, profile); break; + case ACTION_SANITY_CHECK: + r = do_sanity_check(profile); + break; default: util_fatal("Action not yet implemented\n"); } @@ -1139,6 +1148,15 @@ do_store_data_object(struct sc_profile *profile) return r; } +/* + * Run card specific sanity check procedure + */ +static int +do_sanity_check(struct sc_profile *profile) +{ + return sc_pkcs15init_sanity_check(p15card, profile); +} + static int cert_is_root(sc_pkcs15_cert_t *c) { return (c->subject_len == c->issuer_len) && @@ -2604,6 +2622,9 @@ handle_option(const struct option *opt) case OPT_VERIFY_PIN: opt_verify_pin = 1; break; + case OPT_SANITY_CHECK: + this_action = ACTION_SANITY_CHECK; + break; default: util_print_usage_and_die(app_name, options, option_help); }