diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index a057044e..7b8a6af3 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -592,6 +592,8 @@ void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key) { if (key->subject.value) free(key->subject.value); + if (key->cmap_record.guid) + free(key->cmap_record.guid); sc_pkcs15_free_key_params(&key->params); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 499fef9a..f33a1bca 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1801,9 +1801,6 @@ void sc_pkcs15_free_object(struct sc_pkcs15_object *obj) free(obj->data); } - if (obj->md_guid != NULL) - free(obj->md_guid); - sc_pkcs15_free_object_content(obj); free(obj); @@ -2556,16 +2553,17 @@ sc_pkcs15_get_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object if (p15card->ops.get_guid) return p15card->ops.get_guid(p15card, obj, out, out_size); - if (obj->md_guid) { - if (out_size < strlen(obj->md_guid)) - return SC_ERROR_BUFFER_TOO_SMALL; - memset(out, 0, out_size); + if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) { + struct sc_pkcs15_prkey_info *info = (struct sc_pkcs15_prkey_info *)obj->data; - if (out_size > strlen(obj->md_guid)) - out_size = strlen(obj->md_guid); - memcpy(out, obj->md_guid, out_size); + if (info->cmap_record.guid && strlen(info->cmap_record.guid)) { + if (out_size < strlen(info->cmap_record.guid) + 1) + return SC_ERROR_BUFFER_TOO_SMALL; + memset(out, 0, out_size); + memcpy(out, info->cmap_record.guid, strlen(info->cmap_record.guid)); - return SC_SUCCESS; + return SC_SUCCESS; + } } rv = sc_pkcs15_get_object_id(obj, &id); diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index eae6c105..9a7d6169 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -77,11 +77,11 @@ typedef struct sc_pkcs15_id sc_pkcs15_id_t; ( SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL) #define SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL \ - ( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \ + ( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \ | SC_PKCS15_PIN_FLAG_INITIALIZED ) #define SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL \ - ( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \ + ( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \ | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL) #define SC_PKCS15_PIN_TYPE_BCD 0 @@ -387,6 +387,31 @@ struct sc_pkcs15_key_params { void (*free_params)(void *); }; +/* From Windows Smart Card Minidriver Specification + * Version 7.06 + * + * #define MAX_CONTAINER_NAME_LEN 39 + * #define CONTAINER_MAP_VALID_CONTAINER 1 + * #define CONTAINER_MAP_DEFAULT_CONTAINER 2 + * typedef struct _CONTAINER_MAP_RECORD + * { + * WCHAR wszGuid [MAX_CONTAINER_NAME_LEN + 1]; + * BYTE bFlags; + * BYTE bReserved; + * WORD wSigKeySizeBits; + * WORD wKeyExchangeKeySizeBits; + * } CONTAINER_MAP_RECORD, *PCONTAINER_MAP_RECORD; + */ +#define SC_MD_MAX_CONTAINER_NAME_LEN 39 +#define SC_MD_CONTAINER_MAP_VALID_CONTAINER 0x01 +#define SC_MD_CONTAINER_MAP_DEFAULT_CONTAINER 0x02 +struct sc_md_cmap_record { + char *guid; + unsigned flags; + unsigned key_size_sign; + unsigned key_size_keyexchange; +}; + struct sc_pkcs15_prkey_info { struct sc_pkcs15_id id; /* correlates to public certificate id */ unsigned int usage, access_flags; @@ -402,6 +427,9 @@ struct sc_pkcs15_prkey_info { struct sc_pkcs15_key_params params; struct sc_path path; + + /* Used by minidriver and its on-card support */ + struct sc_md_cmap_record cmap_record; }; typedef struct sc_pkcs15_prkey_info sc_pkcs15_prkey_info_t; @@ -498,10 +526,6 @@ struct sc_pkcs15_object { struct sc_pkcs15_object *next, *prev; /* used only internally */ struct sc_pkcs15_der content; - - /* Used by minidriver and its on-card support */ - char *md_guid; - unsigned md_flags; }; typedef struct sc_pkcs15_object sc_pkcs15_object_t; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 118f1dcf..6bdd3eb8 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -1082,7 +1082,7 @@ md_set_cardid(PCARD_DATA pCardData, struct md_file *file) } memcpy(sn_bin, vs->p15card->tokeninfo->serial_number, sn_len); } - + for (offs=0; offs < MD_CARDID_SIZE; ) { wr = MD_CARDID_SIZE - offs; if (wr > sn_len) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 14000d4c..92dabb87 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1296,10 +1296,11 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr key_info = (struct sc_pkcs15_prkey_info *) object->data; if (keygen_args->prkey_args.guid) { - object->md_guid = strdup(keygen_args->prkey_args.guid); - if (!object->md_guid) + key_info->cmap_record.guid = strdup(keygen_args->prkey_args.guid); + if (!key_info->cmap_record.guid) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate guid"); - sc_log(ctx, "new key GUID: '%s'", object->md_guid); + sc_log(ctx, "new key GUID: '%s'", key_info->cmap_record.guid); + key_info->cmap_record.flags = SC_MD_CONTAINER_MAP_VALID_CONTAINER; } /* Set up the PuKDF info. The public key will be filled in @@ -1407,7 +1408,6 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, keyargs, &key, keybits, &object); LOG_TEST_RET(ctx, r, "Failed to initialize private key object"); - /*key_info = (struct sc_pkcs15_prkey_info *) object->data;*/ r = sc_pkcs15init_encode_prvkey_content(p15card, &key, object); LOG_TEST_RET(ctx, r, "Failed to encode public key"); @@ -1430,10 +1430,13 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil LOG_TEST_RET(ctx, r, "Failed to add new private key PKCS#15 object"); if (keyargs->guid) { - object->md_guid = strdup(keyargs->guid); - if (!object->md_guid) + struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data; + + key_info->cmap_record.guid = strdup(keyargs->guid); + if (!key_info->cmap_record.guid) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate guid"); - sc_log(ctx, "new key GUID: '%s'", object->md_guid); + sc_log(ctx, "new key GUID: '%s'", key_info->cmap_record.guid); + key_info->cmap_record.flags = SC_MD_CONTAINER_MAP_VALID_CONTAINER; } if (!r && profile->ops->emu_store_data) { diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index b32369da..a6273af3 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -207,17 +207,16 @@ static void print_common_flags(const struct sc_pkcs15_object *obj) printf("\tObject Flags : [0x%X]", obj->flags); for (i = 0; i < NELEMENTS(common_flags); i++) { if (obj->flags & (1 << i)) { - printf(", %s", common_flags[i]); + printf(", %s", common_flags[i]); } - } - printf("\n"); + } + printf("\n"); } static void print_cert_info(const struct sc_pkcs15_object *obj) { struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) obj->data; struct sc_pkcs15_cert *cert_parsed = NULL; - char guid[39]; int rv; printf("X.509 Certificate [%s]\n", obj->label); @@ -226,10 +225,6 @@ static void print_cert_info(const struct sc_pkcs15_object *obj) printf("\tPath : %s\n", sc_print_path(&cert_info->path)); printf("\tID : %s\n", sc_pkcs15_print_id(&cert_info->id)); - rv = sc_pkcs15_get_guid(p15card, obj, 0, guid, sizeof(guid)); - if (!rv) - printf("\tGUID : %s\n", guid); - print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES); rv = sc_pkcs15_read_certificate(p15card, cert_info, &cert_parsed); @@ -411,7 +406,7 @@ static int read_data_object(void) 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; + struct sc_pkcs15_data *data_object = NULL; if (!sc_format_oid(&oid, opt_data)) { if (!sc_compare_oid(&oid, &cinfo->app_oid)) @@ -538,9 +533,10 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&obj->auth_id)); printf("\tID : %s\n", sc_pkcs15_print_id(&prkey->id)); - if (!sc_pkcs15_get_guid(p15card, obj, 0, guid, sizeof(guid))) + if (!sc_pkcs15_get_guid(p15card, obj, 0, guid, sizeof(guid))) { printf("\tGUID : %s\n", guid); - + printf("\tMD cmap flags : 0x%X\n", prkey->cmap_record.flags); + } }