From f18ba7d98407890be1ba1d983910cae96952016a Mon Sep 17 00:00:00 2001 From: "viktor.tarasov" Date: Mon, 5 Jul 2010 12:54:23 +0000 Subject: [PATCH] pkcs15: decode 'supportedAlgorithms' in 'TokenInfo' git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4510 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/opensc.h | 10 ++++++ src/libopensc/pkcs15.c | 74 ++++++++++++++++++++++++++++++++++++++---- src/libopensc/pkcs15.h | 10 +++--- src/libopensc/types.h | 8 +++++ 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 9337a2bd..7d95488f 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -115,6 +115,14 @@ extern "C" { #define SC_EVENT_READER_DETACHED 0x0008 #define SC_EVENT_READER_EVENTS SC_EVENT_READER_ATTACHED|SC_EVENT_READER_DETACHED +struct sc_supported_algo_info { + unsigned int reference; + unsigned int mechanism; + unsigned int operations; + struct sc_object_id algo_id; + unsigned int algo_ref; +}; + typedef struct sc_security_env { unsigned long flags; int operation; @@ -124,6 +132,8 @@ typedef struct sc_security_env { struct sc_path file_ref; u8 key_ref[8]; size_t key_ref_len; + + struct sc_supported_algo_info supported_algos[SC_MAX_SUPPORTED_ALGORITHMS]; } sc_security_env_t; struct sc_algorithm_id { diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 2d2bca4f..848ed684 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -35,6 +35,31 @@ static const struct sc_asn1_entry c_asn1_twlabel[] = { { NULL, 0, 0, 0, NULL, NULL } }; +static const struct sc_asn1_entry c_asn1_algorithm_info[7] = { + { "reference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "algorithmPKCS#11", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "parameters", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "supportedOperations",SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, + { "objId", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { "algRef", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +/* + * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8 + */ +static const struct sc_asn1_entry c_asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1] = { + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + static const struct sc_asn1_entry c_asn1_toki[] = { { "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, { "serialNumber", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL }, @@ -61,9 +86,8 @@ static const struct sc_asn1_entry c_asn1_tokeninfo[] = { int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen) { - int r; + int r, ii; u8 serial[128]; - size_t i; size_t serial_len = sizeof(serial); u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE]; size_t mnfid_len = sizeof(mnfid); @@ -75,12 +99,33 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, struct sc_asn1_entry asn1_toki[14], asn1_tokeninfo[3], asn1_twlabel[3]; u8 preferred_language[3]; size_t lang_length = sizeof(preferred_language); + struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1], + asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7]; + size_t reference_len = sizeof(ti->supported_algos[0].reference); + size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism); + size_t operations_len = sizeof(ti->supported_algos[0].operations); + size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref); memset(last_update, 0, sizeof(last_update)); sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel); sc_copy_asn1_entry(c_asn1_toki, asn1_toki); sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo); sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0); + + for (ii=0; iisupported_algos[ii].reference, &reference_len, 0); + sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0); + sc_format_asn1_entry(asn1_algo_infos[ii] + 2, NULL, NULL, 0); + sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0); + sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1); + sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0); + sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 0); + } + sc_format_asn1_entry(asn1_toki + 0, &ti->version, NULL, 0); sc_format_asn1_entry(asn1_toki + 1, serial, &serial_len, 0); sc_format_asn1_entry(asn1_toki + 2, mnfid, &mnfid_len, 0); @@ -89,7 +134,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, sc_format_asn1_entry(asn1_toki + 5, &ti->flags, &flags_len, 0); sc_format_asn1_entry(asn1_toki + 6, &ti->seInfo, &ti->num_seInfo, 0); sc_format_asn1_entry(asn1_toki + 7, NULL, NULL, 0); - sc_format_asn1_entry(asn1_toki + 8, NULL, NULL, 0); + sc_format_asn1_entry(asn1_toki + 8, asn1_supported_algorithms, NULL, 0); sc_format_asn1_entry(asn1_toki + 9, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 10, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 11, last_update, &lupdate_len, 0); @@ -107,10 +152,10 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, if (ti->serial_number == NULL) return SC_ERROR_OUT_OF_MEMORY; ti->serial_number[0] = 0; - for (i = 0; i < serial_len; i++) { + for (ii = 0; ii < serial_len; ii++) { char byte[3]; - sprintf(byte, "%02X", serial[i]); + sprintf(byte, "%02X", serial[ii]); strcat(ti->serial_number, byte); } if (ti->manufacturer_id == NULL) { @@ -535,7 +580,7 @@ void sc_pkcs15_card_clear(sc_pkcs15_card_t *p15card) static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) { unsigned char *buf = NULL; - int err, ok = 0; + int err, ii, ok = 0; size_t len; sc_path_t tmppath; sc_card_t *card = p15card->card; @@ -690,6 +735,23 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) p15card->seInfo = tokeninfo.seInfo; p15card->num_seInfo = tokeninfo.num_seInfo; + memcpy(&p15card->supported_algos, &tokeninfo.supported_algos, sizeof(p15card->supported_algos)); + for (ii=0; iisupported_algos[ii].reference; ii++) + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "algo[%i]: ref:0x%X;mech:0x%X;op:0x%X;algo_ref:0x%X", ii, + p15card->supported_algos[ii].reference, p15card->supported_algos[ii].mechanism, + p15card->supported_algos[ii].operations, p15card->supported_algos[ii].algo_ref); + + if (!p15card->serial_number && card->serialnr.len) { + char *serial = calloc(1, card->serialnr.len*2 + 1); + size_t ii; + + for(ii=0;iiserialnr.len;ii++) + sprintf(serial + ii*2, "%02X", *(card->serialnr.value + ii)); + + p15card->serial_number = serial; + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "p15card->serial_number %s", p15card->serial_number); + } + ok = 1; end: if(buf != NULL) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index f078ede4..4b05f966 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -91,11 +91,6 @@ typedef struct sc_pkcs15_pin_info sc_pkcs15_pin_info_t; #define SC_PKCS15_ALGO_OP_HASH 0x40 #define SC_PKCS15_ALGO_OP_GENERATE_KEY 0x80 -struct sc_pkcs15_algorithm_info { - int reference; - int algorithm, supported_operations; -}; - /* A large integer, big endian notation */ struct sc_pkcs15_bignum { u8 * data; @@ -397,6 +392,8 @@ typedef struct sc_pkcs15_tokeninfo { char *preferred_language; sc_pkcs15_sec_env_info_t **seInfo; size_t num_seInfo; + + struct sc_supported_algo_info supported_algos[SC_MAX_SUPPORTED_ALGORITHMS]; } sc_pkcs15_tokeninfo_t; struct sc_pkcs15_operations { @@ -412,7 +409,8 @@ typedef struct sc_pkcs15_card { char *serial_number, *manufacturer_id; char *last_update; unsigned int flags; - struct sc_pkcs15_algorithm_info alg_info[1]; + + struct sc_supported_algo_info supported_algos[SC_MAX_SUPPORTED_ALGORITHMS]; sc_file_t *file_app; sc_file_t *file_tokeninfo, *file_odf, *file_unusedspace; diff --git a/src/libopensc/types.h b/src/libopensc/types.h index dd90966b..7c9d668e 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -41,11 +41,19 @@ typedef unsigned char u8; #define SC_MAX_OBJECT_ID_OCTETS 16 #define SC_MAX_PATH_SIZE 16 #define SC_MAX_PATH_STRING_SIZE (SC_MAX_PATH_SIZE * 2 + 1) + /* default max_send_size/max_recv_size */ /* GPK rounds down to a multiple of 4, other driver have their own limits */ #define SC_DEFAULT_MAX_SEND_SIZE 255 #define SC_DEFAULT_MAX_RECV_SIZE 256 +/* When changing this value, pay attention to the initialization of the ASN1 + * static variables that use this macro, like, for example, + * 'c_asn1_supported_algorithms' in + * src/libopensc/pkcs15.c, src/libopensc/pkcs15-prkey.c, ... + */ +#define SC_MAX_SUPPORTED_ALGORITHMS 8 + struct sc_object_id { int value[SC_MAX_OBJECT_ID_OCTETS];