Attached is a patch to the the opensc-0.11.1-r3057 snapshot to update
the MuscleCard driver for OpenSC to use an msc_id struct rather than
int/bytes and messing around with byte-swapping for that.

Tested items:
 * OpenSC-explorer
   * List
   * Change Directory
   * Read file
 * PKCS15:
   * Clear
   * Init
   * Load Cert
   * Load Key
   * Read cert
   * Read OpenSSH Key
   * On-Card key generation
 * PKCS11 Crypto ops/test
   No PKCS11 perso tested.

-- 
Thomas Harning Jr.
Authentication Engineer @ Identity Alliance
/* Support patch for MuscleCard Applet from musclecard.com 
 *
 * Copyright (C) 2006, Identity Alliance, Thomas Harning <[EMAIL PROTECTED]>
 */
=== src/libopensc/muscle.c
==================================================================
--- src/libopensc/muscle.c	(revision 994)
+++ src/libopensc/muscle.c	(revision 997)
@@ -67,7 +67,7 @@
 		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 @@
 	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 @@
 	
 	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_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 @@
 	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 @@
 	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 @@
 	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 @@
 }
 
 /* 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 @@
 	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 @@
 	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 @@
 	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 @@
 			}
 			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 @@
 	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 @@
 	/* 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 @@
 	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 @@
 		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 @@
 		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 @@
 	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 @@
 			     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);
 }
=== src/libopensc/muscle.h
==================================================================
--- src/libopensc/muscle.h	(revision 994)
+++ src/libopensc/muscle.h	(revision 997)
@@ -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);
=== src/libopensc/card-muscle.c
==================================================================
--- src/libopensc/card-muscle.c	(revision 994)
+++ src/libopensc/card-muscle.c	(revision 997)
@@ -28,18 +28,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-/* 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 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 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 @@
 	/* 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 @@
 	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 @@
 	
 	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 @@
 {
 	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 @@
 	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 @@
 		
 		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 @@
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 	}
 	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 @@
 	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;
=== src/libopensc/muscle-filesystem.c
==================================================================
--- src/libopensc/muscle-filesystem.c	(revision 994)
+++ src/libopensc/muscle-filesystem.c	(revision 997)
@@ -57,12 +57,12 @@
 	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 @@
 	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 @@
 	}
 }
 
-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_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 */
=== src/libopensc/muscle-filesystem.h
==================================================================
--- src/libopensc/muscle-filesystem.h	(revision 994)
+++ src/libopensc/muscle-filesystem.h	(revision 997)
@@ -25,8 +25,17 @@
 
 #include <opensc/types.h>
 
+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 @@
 
 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);
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to