diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 8859c460..b66da790 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -174,12 +174,15 @@ int sc_decipher(struct sc_card *card, const u8 * crgram, int crgram_len, int sc_compute_signature(struct sc_card *card, const u8 * data, int data_len, u8 * out, int outlen); +/* Possibly only on Setec cards */ +int sc_list_files(struct sc_card *card, u8 * buf, int buflen); + +int sc_file_valid(const struct sc_file *file); const char *sc_strerror(int error); +void sc_hex_dump(const u8 *buf, int len); +void sc_print_binary(const u8 *buf, int len); int sc_debug; - -void sc_hex_dump(const u8 *buf, int len); - const char *sc_version; #endif diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index ccd6fff9..550883e6 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -233,9 +233,8 @@ int sc_pkcs15_init(struct sc_card *card, memcpy(tmppath.value, "\x2F\x00", 2); tmppath.len = 2; - err = - sc_select_file(card, &p15card->file_dir, &tmppath, - SC_SELECT_FILE_BY_PATH); + err = sc_select_file(card, &p15card->file_dir, &tmppath, + SC_SELECT_FILE_BY_PATH); if (err) goto error; err = sc_read_binary(card, 0, buf, p15card->file_dir.size); diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 63fc69f6..18b21103 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -49,6 +49,8 @@ static int convert_sw_to_errorcode(u8 * sw) case 0x87: return SC_ERROR_INVALID_ARGUMENTS; } + case 0x6D: + return SC_ERROR_NOT_SUPPORTED; } return SC_ERROR_UNKNOWN; } @@ -56,21 +58,29 @@ static int convert_sw_to_errorcode(u8 * sw) void sc_hex_dump(const u8 *buf, int count) { int i; - int printch = 0; + + for (i = 0; i < count; i++) { + unsigned char c = buf[i]; + + printf("%02X", c); + } + printf("\n"); + fflush(stdout); +} + +void sc_print_binary(const u8 *buf, int count) +{ + int i; for (i = 0; i < count; i++) { unsigned char c = buf[i]; const char *format; - if (printch) { - if (!isalnum(c) && !ispunct(c) && !isspace(c)) - format = "\\x%02X"; - else - format = "%c"; - } else - format = "%02X"; + if (!isalnum(c) && !ispunct(c) && !isspace(c)) + format = "\\x%02X"; + else + format = "%c"; printf(format, c); } - printf("\n"); fflush(stdout); } @@ -344,6 +354,8 @@ int sc_select_file(struct sc_card *card, return r; if (apdu.resplen < 2) return SC_ERROR_UNKNOWN_RESPONSE; + if (file != NULL) + memset(file, 0, sizeof(*file)); switch (apdu.resp[0]) { case 0x6A: switch (apdu.resp[1]) { @@ -355,16 +367,17 @@ int sc_select_file(struct sc_card *card, case 0x6F: break; case 0x90: + case 0x00: /* proprietary coding */ return 0; default: fprintf(stderr, "SELECT FILE returned SW1=%02X, SW2=%02X.\n", apdu.resp[0], apdu.resp[1]); + /* FIXME */ return SC_ERROR_UNKNOWN_RESPONSE; } if (file == NULL) return 0; - memset(file, 0, sizeof(*file)); if (pathtype == SC_SELECT_FILE_BY_PATH) { memcpy(&file->path.value, path, pathlen); file->path.len = pathlen; @@ -829,3 +842,31 @@ int sc_get_random(struct sc_card *card, u8 *rnd, int len) } return 0; } + +int sc_list_files(struct sc_card *card, u8 *buf, int buflen) +{ + struct sc_apdu apdu; + int r; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xAA, 0, 0); + apdu.resp = buf; + apdu.resplen = buflen; + apdu.le = 0; + r = sc_transmit_apdu(card, &apdu); + if (r) + return r; + if (apdu.resplen < 2) + return -1; /* FIXME */ + if (apdu.resplen == 2) + return convert_sw_to_errorcode(apdu.resp); + apdu.resplen -= 2; + + return apdu.resplen; +} + +int sc_file_valid(const struct sc_file *file) +{ + assert(file != NULL); + + return file->magic == SC_FILE_MAGIC; +} diff --git a/src/tests/hst-test.c b/src/tests/hst-test.c index 2a0b4049..43732c7f 100644 --- a/src/tests/hst-test.c +++ b/src/tests/hst-test.c @@ -38,28 +38,6 @@ int enum_private_keys() return 0; } -int sc_list_files(struct sc_card *card, u8 *buf, int buflen) -{ - struct sc_apdu apdu; - int r; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xAA, 0, 0); - apdu.resp = buf; - apdu.resplen = buflen; - apdu.le = 0; - r = sc_transmit_apdu(card, &apdu); - if (r) - return r; - if (apdu.resplen < 2) - return -1; - if (apdu.resplen == 2) -// FIXME return convert_sw_to_errorcode(apdu.resp); - return -1; - apdu.resplen -= 2; - - return apdu.resplen; -} - int enum_dir(struct sc_path path, int depth) { struct sc_file file; @@ -79,40 +57,49 @@ int enum_dir(struct sc_path path, int depth) if (r && (r & 1) == 1) printf(" "); } - if (file.namelen) - printf("[%s] ", file.name); - switch (file.type) { - case 0: - tmps = "wEF"; - break; - case 1: - tmps = "iEF"; - break; - case 7: - tmps = "DF"; - break; - default: - tmps = "unknown"; - break; - } - printf("type: %-3s ", tmps); - if (file.type != 7) - printf("ef structure: %d ", file.ef_structure); - printf("size: %d\n", file.size); - if (file.type == 0 && 0) { - r = sc_read_binary(card, 0, buf, file.size); - if (r > 0) - sc_hex_dump(buf, r); + if (sc_file_valid(&file)) { + if (file.namelen) { + printf("["); + sc_print_binary(file.name, file.namelen); + printf("] "); + } + switch (file.type) { + case 0: + tmps = "wEF"; + break; + case 1: + tmps = "iEF"; + break; + case 7: + tmps = "DF"; + break; + default: + tmps = "unknown"; + break; + } + printf("type: %-3s ", tmps); + if (file.type != 7) + printf("ef structure: %d ", file.ef_structure); + printf("size: %d\n", file.size); + if (file.type == 0 && 0) { + r = sc_read_binary(card, 0, buf, file.size); + if (r > 0) + sc_hex_dump(buf, r); + } + } else { + printf("\n"); } - if (file.type == 7) { + if (!sc_file_valid(&file) || file.type == 7) { int i; - + r = sc_list_files(card, files, sizeof(files)); - if (r <= 0) + if (r <= 0) { + fprintf(stderr, "sc_list_files() failed: %s\n", sc_strerror(r)); return r; + } for (i = 0; i < r/2; i++) { struct sc_path tmppath; - + memcpy(&tmppath, &path, sizeof(path)); memcpy(tmppath.value + tmppath.len, files + 2*i, 2); tmppath.len += 2; @@ -120,7 +107,7 @@ int enum_dir(struct sc_path path, int depth) } } return 0; -} +} int test() {