From 6fc954cbc63c07c03ce3c7180d0c894d7e2dc73b Mon Sep 17 00:00:00 2001 From: "viktor.tarasov" Date: Thu, 21 Jan 2010 09:41:40 +0000 Subject: [PATCH] pkcs15init: new profile type BSO at the profile level the difference between EF and BSO is: - BSO path is always the path of the host DF and do not indexated when template is instanciated; - EF path is always ending with file-id that is always indexated when template is instanciated. New non-static 'sc_profile_get_file_instance' procedure to instanciate non-template entries. In profile.c get_uint() accepts hexadecimals. In CardOS profile (I venture to) increase the xDF sizes and change ACL to permit the key re-importing. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3919 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/opensc.h | 1 + src/pkcs15init/cardos.profile | 17 +++++---- src/pkcs15init/oberthur.profile | 6 ++- src/pkcs15init/pkcs15-cardos.c | 4 -- src/pkcs15init/pkcs15-lib.c | 16 +++++++- src/pkcs15init/profile.c | 66 +++++++++++++++++++++++++++++---- src/pkcs15init/profile.h | 2 + 7 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 6c099b68..52a71489 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -61,6 +61,7 @@ extern "C" { #define SC_FILE_TYPE_DF 0x04 #define SC_FILE_TYPE_INTERNAL_EF 0x03 #define SC_FILE_TYPE_WORKING_EF 0x01 +#define SC_FILE_TYPE_BSO 0x10 /* EF structures */ #define SC_FILE_EF_UNKNOWN 0x00 diff --git a/src/pkcs15init/cardos.profile b/src/pkcs15init/cardos.profile index f6d5d751..45be7884 100644 --- a/src/pkcs15init/cardos.profile +++ b/src/pkcs15init/cardos.profile @@ -34,16 +34,21 @@ filesystem { # Prevent unauthorized updates of basic security # objects via PUT DATA OCI. - ACL = UPDATE=NEVER; + # ACL = UPDATE=NEVER; + ACL = UPDATE=$PIN; # Bump the size of the EF(PrKDF) - with split # keys, we may need a little more room. EF PKCS15-PrKDF { - size = 384; + size = 1024; } EF PKCS15-PuKDF { - size = 384; + size = 768; + } + + EF PKCS15-CDF { + size = 1536; } # This template defines files for keys, certificates etc. @@ -52,11 +57,9 @@ filesystem { # combined with the last octet of the object's pkcs15 id # to form a unique file ID. template key-domain { - # This is a dummy entry - pkcs15-init insists that - # this is present - EF private-key { - file-id = FFFF; + BSO private-key { } + EF public-key { file-id = 3003; structure = transparent; diff --git a/src/pkcs15init/oberthur.profile b/src/pkcs15init/oberthur.profile index 58828eef..3e96aa65 100644 --- a/src/pkcs15init/oberthur.profile +++ b/src/pkcs15init/oberthur.profile @@ -56,7 +56,7 @@ filesystem { ACL = CREATE=CHV4, CRYPTO=NEVER, PIN-DEFINE=CHV4, PIN-RESET=CHV4; file-id = 5011; size = 40; - + DF private-DF { ACL = *=NEVER; ACL = CREATE=CHV1, CRYPTO=CHV1, FILES=NONE, DELETE=NONE; @@ -70,6 +70,7 @@ filesystem { EF template-private-key { file-id = 3000; type = internal-ef; + structure = 0xA3; # READ acl used instead of DECRYPT/SIGN ACL = UPDATE=CHV1, READ=CHV1; } @@ -95,7 +96,7 @@ filesystem { ACL = WRITE=CHV1, UPDATE=CHV1, READ=CHV1; } } - + DF public-DF { ACL = CREATE=NONE, CRYPTO=NONE, FILES=NONE, DELETE=NONE; file-id = 9001; @@ -117,6 +118,7 @@ filesystem { EF template-public-key { file-id = 1000; type = internal-ef; + structure = 0xA1; ACL = *=NONE; } diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index c9fab1ee..c9357bce 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -222,14 +222,10 @@ static int cardos_select_key_reference(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *key_info) { - struct sc_file *df = profile->df_info->file; - if (key_info->key_reference < CARDOS_KEY_ID_MIN) key_info->key_reference = CARDOS_KEY_ID_MIN; if (key_info->key_reference > CARDOS_KEY_ID_MAX) return SC_ERROR_TOO_MANY_OBJECTS; - - key_info->path = df->path; return 0; } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 1e86720f..64d6a781 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1823,7 +1823,6 @@ sc_pkcs15init_store_data(struct sc_pkcs15_card *p15card, r = sc_profile_get_file_by_path(profile, path, &file); SC_TEST_RET(ctx, r, "Failed to get file by path"); } else { - /* Get the number of objects of this type already on this card */ idx = sc_pkcs15_get_objects(p15card, object->type & SC_PKCS15_TYPE_CLASS_MASK, @@ -2427,6 +2426,9 @@ select_object_path(sc_pkcs15_card_t *p15card, sc_profile_t *profile, SC_FUNC_RETURN(ctx, 3, SC_SUCCESS); SC_TEST_RET(ctx, r, "Template instantiation error"); + if (file->type == SC_FILE_TYPE_BSO) + break; + sc_debug(ctx, "path from instantiated template %s", sc_print_path(&file->path)); for (ii=0; iip15_data) { + sc_pkcs15_pincache_entry_t *entry = pro->p15_data->pin_cache[0]; + if(entry) { + if (*pinsize >= entry->len) { + *pinsize = entry->len; + memcpy(pinbuf, entry->pin, entry->len); + goto found; + } + } + } +#endif /* Try to get the cached secret, e.g. CHV1 */ r = sc_keycache_get_key(path, type, reference, pinbuf, *pinsize); if (r >= 0) { diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 3348980b..d624fdf5 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -120,6 +120,7 @@ static struct map fileTypeNames[] = { { "EF", SC_FILE_TYPE_WORKING_EF }, { "INTERNAL-EF",SC_FILE_TYPE_INTERNAL_EF }, { "DF", SC_FILE_TYPE_DF }, + { "BSO", SC_FILE_TYPE_BSO }, { NULL, 0 } }; static struct map fileStructureNames[] = { @@ -253,7 +254,7 @@ init_file(unsigned int type) } file->type = type; file->status = SC_FILE_STATUS_ACTIVATED; - if (file->type != SC_FILE_TYPE_DF) + if (file->type != SC_FILE_TYPE_DF && file->type != SC_FILE_TYPE_BSO) file->ef_structure = SC_FILE_EF_TRANSPARENT; return file; } @@ -507,6 +508,34 @@ sc_profile_get_file(struct sc_profile *profile, return 0; } +int +sc_profile_get_file_instance(struct sc_profile *profile, const char *name, + int index, sc_file_t **ret) +{ + struct file_info *fi; + struct sc_file *file; + int r; + + if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL) + return SC_ERROR_FILE_NOT_FOUND; + sc_file_dup(&file, fi->file); + if (file == NULL) + return SC_ERROR_OUT_OF_MEMORY; + + file->id += index; + file->path.value[file->path.len - 2] = (file->id >> 8) & 0xFF; + file->path.value[file->path.len - 1] = file->id & 0xFF; + + r = sc_profile_add_file(profile, name, file); + if (r) + return r; + + if (ret) + *ret = file; + + return SC_SUCCESS; +} + int sc_profile_get_path(struct sc_profile *profile, const char *name, sc_path_t *ret) @@ -567,7 +596,7 @@ sc_profile_instantiate_template(sc_profile_t *profile, struct file_info *fi, *base_file, *match = NULL; #ifdef DEBUG_PROFILE - printf("Instantiate template\n"); + printf("Instantiate %s in template %s\n", file_name, template_name); #endif for (info = profile->template_list; info; info = info->next) { if (!strcmp(info->name, template_name)) @@ -665,7 +694,8 @@ sc_profile_instantiate_file(sc_profile_t *profile, file_info *ft, } fi->file->path = parent->file->path; fi->file->id += skew; - sc_append_file_id(&fi->file->path, fi->file->id); + if (fi->file->type != SC_FILE_TYPE_BSO && fi->file->type != SC_FILE_TYPE_DF) + sc_append_file_id(&fi->file->path, fi->file->id); append_file(profile, fi); @@ -901,6 +931,22 @@ process_ef(struct state *cur, struct block *info, } +static int +process_bso(struct state *cur, struct block *info, + const char *name, scconf_block *blk) +{ + struct state state; + + init_state(cur, &state); + if (name == NULL) { + parse_error(cur, "No name given for BSO object."); + return 1; + } + if (!(state.file = new_file(cur, name, SC_FILE_TYPE_BSO))) + return 1; + return process_block(&state, info, name, blk); +} + /* * In the template the difference between any two file-ids * should be greater then TEMPLATE_FILEID_MIN_DIFF. @@ -915,14 +961,14 @@ template_sanity_check(struct state *cur, struct sc_profile *templ) int fi_id = fi_path.value[fi_path.len - 2] * 0x100 + fi_path.value[fi_path.len - 1]; - if (fi_id == 0xFFFF) + if (fi->file->type == SC_FILE_TYPE_BSO) continue; for (ffi = templ->ef_list; ffi; ffi = ffi->next) { struct sc_path ffi_path = ffi->file->path; int dlt, ffi_id = ffi_path.value[ffi_path.len - 2] * 0x100 + ffi_path.value[ffi_path.len - 1]; - if (ffi_id == 0xFFFF) + if (ffi->file->type == SC_FILE_TYPE_BSO) continue; dlt = fi_id > ffi_id ? fi_id - ffi_id : ffi_id - fi_id; @@ -1086,7 +1132,9 @@ new_file(struct state *cur, const char *name, unsigned int type) assert(file); if (file->type != (int)type) { parse_error(cur, "inconsistent file type (should be %s)", - (file->type == SC_FILE_TYPE_DF)? "DF" : "EF"); + file->type == SC_FILE_TYPE_DF + ? "DF" : file->type == SC_FILE_TYPE_BSO + ? "BS0" : "EF"); if (strncasecmp(name, "PKCS15-", 7) || !strcasecmp(name+7, "AppDF")) sc_file_free(file); @@ -1551,6 +1599,7 @@ static struct command fs_commands[] = { static struct block fs_blocks[] = { { "DF", process_df, fs_commands, fs_blocks }, { "EF", process_ef, fs_commands, fs_blocks }, + { "BSO", process_bso, fs_commands, fs_blocks }, { "template", process_tmpl, fs_commands, fs_blocks }, { NULL, NULL, NULL, NULL } @@ -1824,7 +1873,10 @@ get_uint(struct state *cur, const char *value, unsigned int *vp) { char *ep; - *vp = strtoul(value, &ep, 0); + if (strstr(value, "0x") == value) + *vp = strtoul(value + 2, &ep, 16); + else + *vp = strtoul(value, &ep, 0); if (*ep != '\0') { parse_error(cur, "invalid integer argument \"%s\"\n", value); diff --git a/src/pkcs15init/profile.h b/src/pkcs15init/profile.h index fdabe3ce..5e5f2da1 100644 --- a/src/pkcs15init/profile.h +++ b/src/pkcs15init/profile.h @@ -148,6 +148,8 @@ int sc_profile_instantiate_template(struct sc_profile *, sc_file_t **); int sc_profile_add_file(struct sc_profile *, const char *, sc_file_t *); +int sc_profile_get_file_instance(struct sc_profile *, const char *, + int, sc_file_t **); #ifdef __cplusplus }