From b3822c349b9b4c3e837298cd0d1e333faa09a604 Mon Sep 17 00:00:00 2001 From: aj Date: Thu, 30 Nov 2006 08:14:16 +0000 Subject: [PATCH] update the MuscleCard driver for OpenSC to use an msc_id struct rather than int/bytes and messing around with byte-swapping for that. (by Thomas Harning) git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3067 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-muscle.c | 149 ++++++++++++++++-------------- src/libopensc/muscle-filesystem.c | 74 +++++++-------- src/libopensc/muscle-filesystem.h | 16 +++- src/libopensc/muscle.c | 66 +++++++------ src/libopensc/muscle.h | 14 +-- 5 files changed, 174 insertions(+), 145 deletions(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index fb33547d..1f5d2ce2 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -28,18 +28,6 @@ #include #include -/* ATR Values pulled from the Muscle Card library's 'bundle' */ -#if 0 -/* UNUSED */ -static struct sc_atr_table muscle_atrs[] = { - { "3B:75:13:00:00:9C:02:02:01:02", NULL, "Muscle card", SC_CARD_TYPE_MUSCLE_GENERIC, 0, NULL }, - { "3B:65:00:00:9C:02:02:01:02", NULL, "Muscle card", SC_CARD_TYPE_MUSCLE_GENERIC, 0, NULL }, - { "3B:3B:94:00:90:65:AF:03:0D:01:74:83:0F:90:00", NULL, "Muscle card", SC_CARD_TYPE_MUSCLE_GENERIC, 0, NULL }, - { "3F:6D:00:00:80:31:80:65:B0:05:01:02:5E:83:00:90:00", NULL, "Muscle card", SC_CARD_TYPE_MUSCLE_GENERIC, 0, NULL }, - { NULL, NULL, NULL, 0, 0, NULL } -}; -#endif - static struct sc_card_operations muscle_ops; static struct sc_card_driver muscle_drv = { "Muscle Card Driver", @@ -72,7 +60,15 @@ static u8 muscleAppletId[] = { 0xA0, 0x00,0x00,0x00, 0x01, 0x01 }; static int muscle_match_card(sc_card_t *card) { /* Use SELECT APPLET, since its a more deterministic way of detection */ - return msc_select_applet(card, muscleAppletId, 5); + int i; + /* Since we send an APDU, the card's logout function may be called... + * however it's not always properly nulled out... */ + card->ops->logout = NULL; + + sc_ctx_suppress_errors_on(card->ctx); + i = msc_select_applet(card, muscleAppletId, 5); + sc_ctx_suppress_errors_off(card->ctx); + return i; } /* Since Musclecard has a different ACL system then PKCS15 @@ -119,7 +115,8 @@ static void muscle_parse_acls(const sc_file_t* file, unsigned short* read, unsig static int muscle_create_directory(sc_card_t *card, sc_file_t *file) { mscfs_t *fs = MUSCLE_FS(card); - u8 objectId[4]; + msc_id objectId; + u8* oid = objectId.id; unsigned id = file->id; unsigned short read = 0, write = 0, delete = 0; int objectSize; @@ -130,14 +127,14 @@ static int muscle_create_directory(sc_card_t *card, sc_file_t *file) /* No nesting directories */ if(fs->currentPath[0] != 0x3F || fs->currentPath[1] != 0x00) return SC_ERROR_NOT_SUPPORTED; - objectId[0] = ((id & 0xFF00) >> 8) & 0xFF; - objectId[1] = id & 0xFF; - objectId[2] = objectId[3] = 0; + oid[0] = ((id & 0xFF00) >> 8) & 0xFF; + oid[1] = id & 0xFF; + oid[2] = oid[3] = 0; objectSize = file->size; muscle_parse_acls(file, &read, &write, &delete); - r = msc_create_object(card, bebytes2ulong(objectId), objectSize, read, write, delete); + r = msc_create_object(card, objectId, objectSize, read, write, delete); mscfs_clear_cache(fs); if(r >= 0) return 0; return r; @@ -149,7 +146,7 @@ static int muscle_create_file(sc_card_t *card, sc_file_t *file) mscfs_t *fs = MUSCLE_FS(card); int objectSize = file->size; unsigned short read = 0, write = 0, delete = 0; - unsigned int objectId; + msc_id objectId; int r; if(file->type == SC_FILE_TYPE_DF) return muscle_create_directory(card, file); @@ -160,7 +157,7 @@ static int muscle_create_file(sc_card_t *card, sc_file_t *file) muscle_parse_acls(file, &read, &write, &delete); - mscfs_lookup_local(fs, file->id, (u8*)&objectId); + mscfs_lookup_local(fs, file->id, &objectId); r = msc_create_object(card, objectId, objectSize, read, write, delete); mscfs_clear_cache(fs); if(r >= 0) return 0; @@ -171,19 +168,21 @@ static int muscle_read_binary(sc_card_t *card, unsigned int index, u8* buf, size { mscfs_t *fs = MUSCLE_FS(card); int r; - u8 objectId[4]; + msc_id objectId; + u8* oid = objectId.id; mscfs_file_t *file; r = mscfs_check_selection(fs, -1); if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); file = &fs->cache.array[fs->currentFileIndex]; - memcpy(objectId, file->objectId, 4); + objectId = file->objectId; +// memcpy(objectId.id, file->objectId.id, 4); if(!file->ef) { - objectId[0] = objectId[2]; - objectId[1] = objectId[3]; - objectId[2] = objectId[3] = 0; + oid[0] = oid[2]; + oid[1] = oid[3]; + oid[2] = oid[3] = 0; } - r = msc_read_object(card, bebytes2ulong(objectId), index, buf, count); + r = msc_read_object(card, objectId, index, buf, count); SC_FUNC_RETURN(card->ctx, 0, r); } @@ -192,49 +191,52 @@ static int muscle_update_binary(sc_card_t *card, unsigned int index, const u8* b mscfs_t *fs = MUSCLE_FS(card); int r; mscfs_file_t *file; - u8 objectId[4]; + msc_id objectId; + u8* oid = objectId.id; r = mscfs_check_selection(fs, -1); if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); file = &fs->cache.array[fs->currentFileIndex]; - memcpy(objectId, file->objectId, 4); + objectId = file->objectId; + //memcpy(objectId.id, file->objectId.id, 4); if(!file->ef) { - objectId[0] = objectId[2]; - objectId[1] = objectId[3]; - objectId[2] = objectId[3] = 0; + oid[0] = oid[2]; + oid[1] = oid[3]; + oid[2] = oid[3] = 0; } if(file->size < index + count) { int newFileSize = index + count; u8* buffer = malloc(newFileSize); if(buffer == NULL) SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY); - r = msc_read_object(card, bebytes2ulong(objectId), 0, buffer, file->size); + r = msc_read_object(card, objectId, 0, buffer, file->size); /* TODO: RETREIVE ACLS */ if(r < 0) goto update_bin_free_buffer; - r = msc_delete_object(card, bebytes2ulong(objectId), 0); + r = msc_delete_object(card, objectId, 0); if(r < 0) goto update_bin_free_buffer; - r = msc_create_object(card, bebytes2ulong(objectId), newFileSize, 0,0,0); + r = msc_create_object(card, objectId, newFileSize, 0,0,0); if(r < 0) goto update_bin_free_buffer; memcpy(buffer + index, buf, count); - r = msc_update_object(card, bebytes2ulong(objectId), 0, buffer, newFileSize); + r = msc_update_object(card, objectId, 0, buffer, newFileSize); if(r < 0) goto update_bin_free_buffer; file->size = newFileSize; update_bin_free_buffer: free(buffer); SC_FUNC_RETURN(card->ctx, 0, r); } else { - r = msc_update_object(card, bebytes2ulong(objectId), index, buf, count); + r = msc_update_object(card, objectId, index, buf, count); } //mscfs_clear_cache(fs); return r; } +/* TODO: Evaluate correctness */ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) { mscfs_t *fs = MUSCLE_FS(card); - u8 *id = file_data->objectId; - int objectId = bebytes2ulong(id); + msc_id id = file_data->objectId; + u8* oid = id.id; int r; if(!file_data->ef) { @@ -245,32 +247,44 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) if (card->ctx->debug >= 2) { sc_debug(card->ctx, "DELETING Children of: %02X%02X%02X%02X\n", - id[0],id[1],id[2],id[3]); + oid[0],oid[1],oid[2],oid[3]); } for(x = 0; x < fs->cache.size; x++) { - u8 *objectId; + msc_id objectId; childFile = &fs->cache.array[x]; objectId = childFile->objectId; - if(0 == memcmp(id + 2, objectId, 2)) { + if(0 == memcmp(oid + 2, objectId.id, 2)) { if (card->ctx->debug >= 2) { sc_debug(card->ctx, "DELETING: %02X%02X%02X%02X\n", - objectId[0],objectId[1],objectId[2],objectId[3]); + objectId.id[0],objectId.id[1],objectId.id[2],objectId.id[3]); } r = muscle_delete_mscfs_file(card, childFile); if(r < 0) SC_FUNC_RETURN(card->ctx, 2,r); } } - objectId = objectId >> 16; + oid[0] = oid[2]; + oid[1] = oid[3]; + oid[2] = oid[3] = 0; + // ??? objectId = objectId >> 16; } - - r = msc_delete_object(card, objectId, 1); + if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4)) + || (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4))) { + sc_ctx_suppress_errors_on(card->ctx); + } + r = msc_delete_object(card, id, 1); /* Check if its the root... this file generally is virtual * So don't return an error if it fails */ - if((0 == memcmp(id, "\x3F\x00\x00\x00", 4)) - || (0 == memcmp(id, "\x3F\x00\x3F\x00", 4))) + if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4)) + || (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4))) + sc_ctx_suppress_errors_off(card->ctx); return 0; - if(r < 0) SC_FUNC_RETURN(card->ctx, 2,r); + + if(r < 0) { + printf("ID: %02X%02X%02X%02X\n", + oid[0],oid[1],oid[2],oid[3]); + SC_FUNC_RETURN(card->ctx, 2,r); + } return 0; } @@ -328,6 +342,7 @@ static int select_item(sc_card_t *card, const sc_path_t *path_in, sc_file_t ** f int pathlen = path_in->len; int r = 0; int objectIndex; + u8* oid; mscfs_check_cache(fs); r = mscfs_loadFileInfo(fs, path_in->value, path_in->len, &file_data, &objectIndex); @@ -337,15 +352,16 @@ static int select_item(sc_card_t *card, const sc_path_t *path_in, sc_file_t ** f if(requiredType >= 0 && requiredType != file_data->ef) { SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_INVALID_ARGUMENTS); } + oid = file_data->objectId.id; /* Is it a file or directory */ if(file_data->ef) { - fs->currentPath[0] = file_data->objectId[0]; - fs->currentPath[1] = file_data->objectId[1]; - fs->currentFile[0] = file_data->objectId[2]; - fs->currentFile[1] = file_data->objectId[3]; + fs->currentPath[0] = oid[0]; + fs->currentPath[1] = oid[1]; + fs->currentFile[0] = oid[2]; + fs->currentFile[1] = oid[3]; } else { - fs->currentPath[0] = file_data->objectId[pathlen - 2]; - fs->currentPath[1] = file_data->objectId[pathlen - 1]; + fs->currentPath[0] = oid[pathlen - 2]; + fs->currentPath[1] = oid[pathlen - 1]; fs->currentFile[0] = 0; fs->currentFile[1] = 0; } @@ -356,7 +372,7 @@ static int select_item(sc_card_t *card, const sc_path_t *path_in, sc_file_t ** f file = sc_file_new(); file->path = *path_in; file->size = file_data->size; - file->id = (file_data->objectId[2] << 8) | file_data->objectId[3]; + file->id = (oid[2] << 8) | oid[3]; memcpy(file->name, path, pathlen); file->namelen = pathlen; if(!file_data->ef) { @@ -415,6 +431,9 @@ static int muscle_init(sc_card_t *card) int r = 0; muscle_private_t *priv; + r = sc_get_default_driver()->ops->init(card); + if(r) return r; + card->name = "Muscle Card"; card->drv_data = malloc(sizeof(muscle_private_t)); if(!card->drv_data) { @@ -430,12 +449,7 @@ static int muscle_init(sc_card_t *card) } priv->fs->udata = card; priv->fs->listFile = _listFile; - //r = autodetect_class(card); - card->cla = 0xB0; - if (r) { - sc_error(card->ctx, "unable to determine the right class byte\n"); - return SC_ERROR_INVALID_CARD; - } + card->flags |= SC_CARD_FLAG_ONBOARD_KEY_GEN; card->flags |= SC_CARD_FLAG_RNG; card->caps |= SC_CARD_CAP_RNG; @@ -467,18 +481,17 @@ static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) mscfs_check_cache(priv->fs); for(x = 0; x < fs->cache.size; x++) { - u8 *objectId; - objectId = fs->cache.array[x].objectId; + u8* oid= fs->cache.array[x].objectId.id; if (card->ctx->debug >= 2) { sc_debug(card->ctx, "FILE: %02X%02X%02X%02X\n", - objectId[0],objectId[1],objectId[2],objectId[3]); + oid[0],oid[1],oid[2],oid[3]); } - if(0 == memcmp(fs->currentPath, objectId, 2)) { - buf[0] = objectId[2]; - buf[1] = objectId[3]; + if(0 == memcmp(fs->currentPath, oid, 2)) { + buf[0] = oid[2]; + buf[1] = oid[3]; if(buf[0] == 0x00 && buf[1] == 0x00) continue; /* No directories/null names outside of root */ buf += 2; - count+=1; + count+=2; } } return count; diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 4ae4efae..08137b4c 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -57,12 +57,12 @@ void mscfs_clear_cache(mscfs_t* fs) { fs->cache.size = 0; } -int mscfs_is_ignored(mscfs_t* fs, u8* objectId) +static int mscfs_is_ignored(mscfs_t* fs, msc_id objectId) { int ignored = 0; const u8** ptr = ignoredFiles; while(ptr && *ptr && !ignored) { - if(0 == memcmp(objectId, *ptr, 4)) + if(0 == memcmp(objectId.id, *ptr, 4)) ignored = 1; ptr++; } @@ -102,11 +102,12 @@ int mscfs_update_cache(mscfs_t* fs) { while(1) { if(!mscfs_is_ignored(fs, file.objectId)) { /* Check if its a directory in the root */ - if(file.objectId[2] == 0 && file.objectId[3] == 0) { - file.objectId[2] = file.objectId[0]; - file.objectId[3] = file.objectId[1]; - file.objectId[0] = 0x3F; - file.objectId[1] = 0x00; + u8* oid = file.objectId.id; + if(oid[2] == 0 && oid[3] == 0) { + oid[2] = oid[0]; + oid[3] = oid[1]; + oid[0] = 0x3F; + oid[1] = 0x00; file.ef = 0; } else { file.ef = 1; /* File is a working elementary file */ @@ -130,56 +131,58 @@ void mscfs_check_cache(mscfs_t* fs) } } -int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, u8 objectId[4], int isDirectory) +int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, msc_id* objectId, int isDirectory) { + u8* oid = objectId->id; if ((pathlen & 1) != 0) /* not divisble by 2 */ return MSCFS_INVALID_ARGS; if(isDirectory) { /* Directory must be right next to root */ if((0 == memcmp(path, "\x3F\x00", 2) && pathlen == 4) || (0 == memcmp(fs->currentPath, "\x3F\x00", 2) && pathlen == 2)) { - objectId[0] = path[pathlen - 2]; - objectId[1] = path[pathlen - 1]; - objectId[2] = objectId[3] = 0; + oid[0] = path[pathlen - 2]; + oid[1] = path[pathlen - 1]; + oid[2] = oid[3] = 0; } else { return MSCFS_INVALID_ARGS; } } - objectId[0] = fs->currentPath[0]; - objectId[1] = fs->currentPath[1]; + oid[0] = fs->currentPath[0]; + oid[1] = fs->currentPath[1]; /* Chop off the root in the path */ if(pathlen > 2 && memcmp(path, "\x3F\x00", 2) == 0) { path += 2; pathlen -= 2; - objectId[0] = 0x3F; - objectId[1] = 0x00; + oid[0] = 0x3F; + oid[1] = 0x00; } /* Limit to a single directory */ if(pathlen > 4) return MSCFS_INVALID_ARGS; /* Reset to root */ if(0 == memcmp(path, "\x3F\x00", 2) && pathlen == 2) { - objectId[0] = objectId[2] = path[0]; - objectId[1] = objectId[3] = path[1]; + oid[0] = oid[2] = path[0]; + oid[1] = oid[3] = path[1]; } else if(pathlen == 2) { /* Path preserved for current-path */ - objectId[2] = path[0]; - objectId[3] = path[1]; + oid[2] = path[0]; + oid[3] = path[1]; } else if(pathlen == 4) { - objectId[0] = path[0]; - objectId[1] = path[1]; - objectId[2] = path[2]; - objectId[3] = path[3]; + oid[0] = path[0]; + oid[1] = path[1]; + oid[2] = path[2]; + oid[3] = path[3]; } return 0; } -int mscfs_lookup_local(mscfs_t* fs, const int id, u8 objectId[4]) +int mscfs_lookup_local(mscfs_t* fs, const int id, msc_id* objectId) { - objectId[0] = fs->currentPath[0]; - objectId[1] = fs->currentPath[1]; - objectId[2] = (id >> 8) & 0xFF; - objectId[3] = id & 0xFF; + u8* oid = objectId->id; + oid[0] = fs->currentPath[0]; + oid[1] = fs->currentPath[1]; + oid[2] = (id >> 8) & 0xFF; + oid[3] = id & 0xFF; return 0; } @@ -195,33 +198,30 @@ int mscfs_check_selection(mscfs_t *fs, int requiredItem) int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, int pathlen, mscfs_file_t **file_data, int* idx) { - u8 fullPath[4]; + msc_id fullPath; int x; assert(fs != NULL && path != NULL && file_data != NULL); - mscfs_lookup_path(fs, path, pathlen, fullPath, 0); + mscfs_lookup_path(fs, path, pathlen, &fullPath, 0); /* Obtain file information while checking if it exists */ mscfs_check_cache(fs); if(idx) *idx = -1; for(x = 0; x < fs->cache.size; x++) { - u8 *objectId; + msc_id objectId; *file_data = &fs->cache.array[x]; objectId = (*file_data)->objectId; - if(0 == memcmp(objectId, fullPath, 4)) { + if(0 == memcmp(objectId.id, fullPath.id, 4)) { if(idx) *idx = x; break; } *file_data = NULL; } - if(*file_data == NULL && (0 == memcmp("\x3F\x00\x00\x00", fullPath, 4) || 0 == memcmp("\x3F\x00\x3F\x00", fullPath, 4 ))) { + if(*file_data == NULL && (0 == memcmp("\x3F\x00\x00\x00", fullPath.id, 4) || 0 == memcmp("\x3F\x00\x3F\x00", fullPath.id, 4 ))) { static mscfs_file_t ROOT_FILE; ROOT_FILE.ef = 0; ROOT_FILE.size = 0; /* Faked Root ID */ - ROOT_FILE.objectId[0] = 0x3F; - ROOT_FILE.objectId[1] = 0x00; - ROOT_FILE.objectId[2] = 0x3F; - ROOT_FILE.objectId[3] = 0x00; + ROOT_FILE.objectId = rootId; ROOT_FILE.read = 0; ROOT_FILE.write = 0x02; /* User Pin access */ diff --git a/src/libopensc/muscle-filesystem.h b/src/libopensc/muscle-filesystem.h index 19febe92..c2b5e139 100644 --- a/src/libopensc/muscle-filesystem.h +++ b/src/libopensc/muscle-filesystem.h @@ -25,8 +25,17 @@ #include +typedef struct msc_id { + u8 id[4]; +} msc_id; + + +static msc_id inputId = { { 0xFF, 0xFF, 0xFF, 0xFF } }; +static msc_id outputId = { { 0xFF, 0xFF, 0xFF, 0xFE } }; +static msc_id rootId = { { 0x3F, 0x00, 0x3F, 0x00 } }; + typedef struct mscfs_file { - u8 objectId[4]; + msc_id objectId; size_t size; unsigned short read, write, delete; int ef; @@ -55,10 +64,9 @@ int mscfs_update_cache(mscfs_t* fs); void mscfs_check_cache(mscfs_t* fs); -int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, u8 objectId[4], int -isDirectory); +int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, msc_id* objectId, int isDirectory); -int mscfs_lookup_local(mscfs_t* fs, const int id, u8 objectId[4]); +int mscfs_lookup_local(mscfs_t* fs, const int id, msc_id* objectId); /* -1 any, 0 DF, 1 EF */ int mscfs_check_selection(mscfs_t *fs, int requiredItem); int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, int pathlen, mscfs_file_t **file_data, int* index); diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 2ee27b7d..fce82830 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -67,7 +67,7 @@ int msc_list_objects(sc_card_t* card, u8 next, mscfs_file_t* file) { sc_error(card->ctx, "expected 14 bytes, got %d.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } - memcpy(file->objectId, fileData, 4); + memcpy(file->objectId.id, fileData, 4); file->size = bebytes2ulong(fileData + 4); file->read = bebytes2ushort(fileData + 8); file->write = bebytes2ushort(fileData + 10); @@ -76,7 +76,7 @@ int msc_list_objects(sc_card_t* card, u8 next, mscfs_file_t* file) { return 1; } -int msc_partial_read_object(sc_card_t *card, unsigned int le_objectId, int offset, u8 *data, size_t dataLength) +int msc_partial_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength) { u8 buffer[9]; sc_apdu_t apdu; @@ -86,7 +86,7 @@ int msc_partial_read_object(sc_card_t *card, unsigned int le_objectId, int offse if (card->ctx->debug >= 2) sc_debug(card->ctx, "READ: Offset: %x\tLength: %i\n", offset, dataLength); - ulong2bebytes(buffer, le_objectId); + memcpy(buffer, objectId.id, 4); ulong2bebytes(buffer + 4, offset); buffer[8] = (u8)dataLength; apdu.data = buffer; @@ -117,7 +117,7 @@ int msc_partial_read_object(sc_card_t *card, unsigned int le_objectId, int offse } -int msc_read_object(sc_card_t *card, unsigned int objectId, int offset, u8 *data, size_t dataLength) +int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength) { int r; size_t i; @@ -128,7 +128,7 @@ int msc_read_object(sc_card_t *card, unsigned int objectId, int offset, u8 *data return dataLength; } -int msc_zero_object(sc_card_t *card, unsigned int objectId, size_t dataLength) +int msc_zero_object(sc_card_t *card, msc_id objectId, size_t dataLength) { u8 zeroBuffer[MSC_MAX_WRITE_UNIT]; size_t i; @@ -140,7 +140,7 @@ int msc_zero_object(sc_card_t *card, unsigned int objectId, size_t dataLength) return 0; } -int msc_create_object(sc_card_t *card, unsigned int objectId, size_t objectSize, unsigned short read, unsigned short write, unsigned short deletion) +int msc_create_object(sc_card_t *card, msc_id objectId, size_t objectSize, unsigned short read, unsigned short write, unsigned short deletion) { u8 buffer[14]; sc_apdu_t apdu; @@ -152,7 +152,7 @@ int msc_create_object(sc_card_t *card, unsigned int objectId, size_t objectSize, apdu.data = buffer, apdu.datalen = 14; - ulong2bebytes(buffer, objectId); + memcpy(buffer, objectId.id, 4); ulong2bebytes(buffer + 4, objectSize); ushort2bebytes(buffer + 8, readAcl); ushort2bebytes(buffer + 10, writeAcl); @@ -179,7 +179,7 @@ int msc_create_object(sc_card_t *card, unsigned int objectId, size_t objectSize, } /* Update up to 246 bytes */ -int msc_partial_update_object(sc_card_t *card, unsigned int le_objectId, int offset, const u8 *data, size_t dataLength) +int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, const u8 *data, size_t dataLength) { u8 buffer[256]; sc_apdu_t apdu; @@ -189,7 +189,8 @@ int msc_partial_update_object(sc_card_t *card, unsigned int le_objectId, int off apdu.lc = dataLength + 9; if (card->ctx->debug >= 2) sc_debug(card->ctx, "WRITE: Offset: %x\tLength: %i\n", offset, dataLength); - ulong2bebytes(buffer, le_objectId); + + memcpy(buffer, objectId.id, 4); ulong2bebytes(buffer + 4, offset); buffer[8] = (u8)dataLength; memcpy(buffer + 9, data, dataLength); @@ -216,7 +217,7 @@ int msc_partial_update_object(sc_card_t *card, unsigned int le_objectId, int off return dataLength; } -int msc_update_object(sc_card_t *card, unsigned int objectId, int offset, const u8 *data, size_t dataLength) +int msc_update_object(sc_card_t *card, msc_id objectId, int offset, const u8 *data, size_t dataLength) { int r; size_t i; @@ -227,16 +228,14 @@ int msc_update_object(sc_card_t *card, unsigned int objectId, int offset, const return dataLength; } -int msc_delete_object(sc_card_t *card, unsigned int objectId, int zero) +int msc_delete_object(sc_card_t *card, msc_id objectId, int zero) { sc_apdu_t apdu; - u8 buf[4]; int r; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x52, 0x00, zero ? 0x01 : 0x00); apdu.lc = 4; - ulong2bebytes(buf, objectId); - apdu.data = buf; + apdu.data = objectId.id; apdu.datalen = 4; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -460,10 +459,12 @@ int msc_get_challenge(sc_card_t *card, short dataLength, short seedLength, u8 *s } SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED); } - r = msc_read_object(card, 0xFFFFFFFFul, 2, outputData, dataLength); + r = msc_read_object(card, inputId, 2, outputData, dataLength); if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); - r = msc_delete_object(card, 0xFFFFFFFFul,0); + sc_ctx_suppress_errors_on(card->ctx); + msc_delete_object(card, inputId,0); + sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, r); } } @@ -566,7 +567,7 @@ int msc_extract_rsa_public_key(sc_card_t *card, if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); /* Read keyType, keySize, and what should be the modulus size */ - r = msc_read_object(card, 0xFFFFFFFFul, fileLocation, buffer, 5); + r = msc_read_object(card, inputId, fileLocation, buffer, 5); fileLocation += 5; if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); @@ -575,7 +576,7 @@ int msc_extract_rsa_public_key(sc_card_t *card, /* Read the modulus and the exponent length */ assert(*modLength + 2 < buffer_size); - r = msc_read_object(card, 0xFFFFFFFFul, fileLocation, buffer, *modLength + 2); + r = msc_read_object(card, inputId, fileLocation, buffer, *modLength + 2); fileLocation += *modLength + 2; if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); @@ -584,7 +585,7 @@ int msc_extract_rsa_public_key(sc_card_t *card, memcpy(*modulus, buffer, *modLength); *expLength = (buffer[*modLength] << 8) | buffer[*modLength + 1]; assert(*expLength < buffer_size); - r = msc_read_object(card, 0xFFFFFFFFul, fileLocation, buffer, *expLength); + r = msc_read_object(card, inputId, fileLocation, buffer, *expLength); if(r < 0) { free(*modulus); *modulus = NULL; SC_FUNC_RETURN(card->ctx, 0, r); @@ -831,7 +832,6 @@ int msc_import_key(sc_card_t *card, keySize = data->keySize; int bufferSize = 0; u8 *buffer, *p; - unsigned int objectId; u8 apduBuffer[6]; sc_apdu_t apdu; int r; @@ -876,24 +876,28 @@ int msc_import_key(sc_card_t *card, CPYVAL(dp1); CPYVAL(dq1); } - objectId = 0xFFFFFFFEul; - - r = msc_create_object(card, objectId, bufferSize, 0x02, 0x02, 0x02); + + sc_ctx_suppress_errors_on(card->ctx); + r = msc_create_object(card, outputId, bufferSize, 0x02, 0x02, 0x02); if(r < 0) { if(r == SC_ERROR_FILE_ALREADY_EXISTS) { - r = msc_delete_object(card, objectId, 0); + r = msc_delete_object(card, outputId, 0); if(r < 0) { + sc_ctx_suppress_errors_off(card->ctx); free(buffer); SC_FUNC_RETURN(card->ctx, 2, r); } - r = msc_create_object(card, objectId, bufferSize, 0x02, 0x02, 0x02); + r = msc_create_object(card, outputId, bufferSize, 0x02, 0x02, 0x02); if(r < 0) { + sc_ctx_suppress_errors_off(card->ctx); free(buffer); SC_FUNC_RETURN(card->ctx, 2, r); } } } - r = msc_update_object(card, objectId, 0, buffer, bufferSize); + sc_ctx_suppress_errors_off(card->ctx); + + r = msc_update_object(card, outputId, 0, buffer, bufferSize); free(buffer); if(r < 0) return r; @@ -909,7 +913,7 @@ int msc_import_key(sc_card_t *card, r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - msc_delete_object(card, objectId, 0); + msc_delete_object(card, outputId, 0); return 0; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -919,11 +923,15 @@ int msc_import_key(sc_card_t *card, apdu.sw1, apdu.sw2); } /* no error checks.. this is last ditch cleanup */ - msc_delete_object(card, objectId, 0); + sc_ctx_suppress_errors_on(card->ctx); + msc_delete_object(card, outputId, 0); + sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, r); } /* no error checks.. this is last ditch cleanup */ - msc_delete_object(card, objectId, 0); + sc_ctx_suppress_errors_on(card->ctx); + msc_delete_object(card, outputId, 0); + sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED); } diff --git a/src/libopensc/muscle.h b/src/libopensc/muscle.h index a5a00603..f3bd20a3 100644 --- a/src/libopensc/muscle.h +++ b/src/libopensc/muscle.h @@ -29,14 +29,14 @@ #include "muscle-filesystem.h" int msc_list_objects(sc_card_t* card, u8 next, mscfs_file_t* file); -int msc_partial_read_object(sc_card_t *card, unsigned int le_objectId, int offset, u8 *data, size_t dataLength); -int msc_read_object(sc_card_t *card, unsigned int objectId, int offset, u8 *data, size_t dataLength); -int msc_create_object(sc_card_t *card, unsigned int objectId, size_t objectSize, unsigned short read, unsigned short write, unsigned short deletion); -int msc_partial_update_object(sc_card_t *card, unsigned int le_objectId, int offset, const u8 *data, size_t dataLength); -int msc_update_object(sc_card_t *card, unsigned int objectId, int offset, const u8 *data, size_t dataLength); -int msc_zero_object(sc_card_t *card, unsigned int objectId, size_t dataLength); +int msc_partial_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength); +int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength); +int msc_create_object(sc_card_t *card, msc_id objectId, size_t objectSize, unsigned short read, unsigned short write, unsigned short deletion); +int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, const u8 *data, size_t dataLength); +int msc_update_object(sc_card_t *card, msc_id objectId, int offset, const u8 *data, size_t dataLength); +int msc_zero_object(sc_card_t *card, msc_id objectId, size_t dataLength); -int msc_delete_object(sc_card_t *card, unsigned int objectId, int zero); +int msc_delete_object(sc_card_t *card, msc_id objectId, int zero); int msc_select_applet(sc_card_t *card, u8 *appletId, size_t appletIdLength); int msc_verify_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLength, int *tries);