diff options
author | Jim Rees <rees@cvs.openbsd.org> | 2001-07-02 20:07:10 +0000 |
---|---|---|
committer | Jim Rees <rees@cvs.openbsd.org> | 2001-07-02 20:07:10 +0000 |
commit | 3bb4c653100b0557977753c622bb3f03269640b5 (patch) | |
tree | 781f7c657e6140053f301beba954a40f3f064013 | |
parent | adf9057e8e5d9b01ad93c03f8febd4119a51339e (diff) |
separate sectok from sc7816 and give each its own include file
change status word to a single word instead of two bytes
add sc7816 layer for backward compatibility
other minor changes
-rw-r--r-- | lib/libsectok/atr.c | 4 | ||||
-rw-r--r-- | lib/libsectok/cyberflex.c | 93 | ||||
-rw-r--r-- | lib/libsectok/ifdhandler.c | 10 | ||||
-rw-r--r-- | lib/libsectok/ifdhandler.h | 8 | ||||
-rw-r--r-- | lib/libsectok/input.c | 12 | ||||
-rw-r--r-- | lib/libsectok/r1r2.c | 140 | ||||
-rw-r--r-- | lib/libsectok/sc7816.c | 430 | ||||
-rw-r--r-- | lib/libsectok/scT1.c | 4 | ||||
-rw-r--r-- | lib/libsectok/scio.c | 33 | ||||
-rw-r--r-- | lib/libsectok/scrw.c | 16 | ||||
-rw-r--r-- | lib/libsectok/sectok.c | 409 | ||||
-rw-r--r-- | lib/libsectok/sectok.h | 216 | ||||
-rw-r--r-- | lib/libsectok/todos_atr.c | 4 |
13 files changed, 693 insertions, 686 deletions
diff --git a/lib/libsectok/atr.c b/lib/libsectok/atr.c index d4657af3ecd..10f8c59f442 100644 --- a/lib/libsectok/atr.c +++ b/lib/libsectok/atr.c @@ -1,4 +1,4 @@ -/* $Id: atr.c,v 1.5 2001/06/25 03:34:00 rees Exp $ */ +/* $Id: atr.c,v 1.6 2001/07/02 20:07:07 rees Exp $ */ /* copyright 1997, 1999, 2000, 2001 @@ -50,7 +50,7 @@ typedef long int32_t; #include <sys/types.h> #endif -#include "sectok.h" +#include "sc7816.h" /* Global interface bytes */ #define TA1 (tpb[0][0]) diff --git a/lib/libsectok/cyberflex.c b/lib/libsectok/cyberflex.c index 2de1d40cf58..31c95300956 100644 --- a/lib/libsectok/cyberflex.c +++ b/lib/libsectok/cyberflex.c @@ -1,4 +1,4 @@ -/* $Id: cyberflex.c,v 1.6 2001/06/28 21:27:54 rees Exp $ */ +/* $Id: cyberflex.c,v 1.7 2001/07/02 20:07:07 rees Exp $ */ /* copyright 2000 @@ -56,10 +56,10 @@ such damages. #define KEY_FILE_HEADER_SIZE 8 #define BLOCK_SIZE 8 -int cyberflex_create_file(int fd, int cla, unsigned char *fid, int size, int ftype, - int *r1p, int *r2p) +int +cyberflex_create_file(int fd, int cla, unsigned char *fid, int size, int ftype, int *swp) { - int i, n; + int i; unsigned char data[16]; size += 16; @@ -75,74 +75,63 @@ int cyberflex_create_file(int fd, int cla, unsigned char *fid, int size, int fty for (i = 9; i < 16; i++ ) data[i] = 0x00; /* ACL : cannot do anything without AUT0 */ - n = scwrite(fd, cla, 0xe0, 0, 0, 0x10, data, r1p, r2p); - if (n < 0 || (*r1p != 0x90 && *r1p != 0x61)) + sectok_apdu(fd, cla, 0xe0, 0, 0, 0x10, data, 0, NULL, swp); + if (!sectok_swOK(*swp)) return -1; - return sectok_selectfile(fd, cla, fid, r1p, r2p); + return sectok_selectfile(fd, cla, fid, swp); } int -cyberflex_delete_file(int fd, int cla, int f0, int f1, int *r1p, int *r2p) +cyberflex_delete_file(int fd, int cla, unsigned char *fid, int *swp) { - int n; - unsigned char buf[2]; - - buf[0] = f0; - buf[1] = f1; - - n = scwrite(fd, cla, 0xe4, 0, 0, 0x02, buf, r1p, r2p); - if (n < 0 || (*r1p != 0x90 && *r1p != 0x61)) { - /* error */ + sectok_apdu(fd, cla, 0xe4, 0, 0, 0x02, fid, 0, NULL, swp); + if (!sectok_swOK(*swp)) return -1; - } + return 0; } int cyberflex_load_rsa_pub(int fd, int cla, unsigned char *key_fid, - int key_len, unsigned char *key_data, int *r1p, int *r2p) + int key_len, unsigned char *key_data, int *swp) { - int rv; - - if (sectok_selectfile(fd, cla, root_fid, r1p, r2p) < 0) + if (sectok_selectfile(fd, cla, root_fid, swp) < 0) return -1; - if (sectok_selectfile(fd, cla, key_fid, r1p, r2p)) { - if (cyberflex_create_file(fd, cla, key_fid, key_len, 3, r1p, r2p) < 0) + if (sectok_selectfile(fd, cla, key_fid, swp) < 0 && *swp == STENOFILE) { + if (cyberflex_create_file(fd, cla, key_fid, key_len, 3, swp) < 0) return -1; } /* Write the key data */ - rv = scwrite(fd, cla, 0xd6, 0, 0, key_len, key_data, r1p, r2p); - if (rv < 0 || (*r1p != 0x90 && *r1p != 0x61)) + sectok_apdu(fd, cla, 0xd6, 0, 0, key_len, key_data, 0, NULL, swp); + if (!sectok_swOK(*swp)) return -1; - return rv; + return 0; } /* download RSA private key into 3f.00/00.12 */ int cyberflex_load_rsa_priv(int fd, int cla, unsigned char *key_fid, int nkey_elems, int key_len, unsigned char *key_elems[], - int *r1p, int *r2p) + int *swp) { - int i, j, rv, offset = 0, size; + int i, j, offset = 0, size; unsigned char data[MAX_KEY_FILE_SIZE]; static unsigned char key_file_header[KEY_FILE_HEADER_SIZE] = {0xC2, 0x06, 0xC1, 0x08, 0x13, 0x00, 0x00, 0x05}; static unsigned char key_header[3] = {0xC2, 0x41, 0x00}; /* select 3f.00 */ - rv = sectok_selectfile(fd, cla, root_fid, r1p, r2p); - if (rv < 0) return rv; + if (sectok_selectfile(fd, cla, root_fid, swp) < 0) + return -1; /* select 00.12 */ - rv = sectok_selectfile(fd, cla, key_fid, r1p, r2p); - if (rv < 0) { + if (sectok_selectfile(fd, cla, key_fid, swp) < 0 && *swp == STENOFILE) { /* rv != 0, 00.12 does not exist. create it. */ - printf ("private key file does not exist. create it.\n"); - if (cyberflex_create_file(fd, cla, key_fid, PRV_KEY_SIZE, 3, r1p, r2p) < 0) + if (cyberflex_create_file(fd, cla, key_fid, PRV_KEY_SIZE, 3, swp) < 0) return -1; } @@ -175,7 +164,7 @@ cyberflex_load_rsa_priv(int fd, int cla, unsigned char *key_fid, /* now send this to the card */ /* select private key file */ - if (sectok_selectfile(fd, cla, key_fid, r1p, r2p) < 0) + if (sectok_selectfile(fd, cla, key_fid, swp) < 0) return -1; /* update binary */ @@ -188,32 +177,24 @@ cyberflex_load_rsa_priv(int fd, int cla, unsigned char *key_fid, if (size - i > MAX_APDU_SIZE) send_size = MAX_APDU_SIZE; else send_size = size - i; - rv = scwrite(fd, cla, 0xd6, - i / 256, /* offset, upper byte */ - i % 256, /* offset, lower byte */ - send_size, - data + i, /* key file */ - r1p, r2p); + sectok_apdu(fd, cla, 0xd6, i >> 8, i & 0xff, send_size, data + i, 0, NULL, swp); - if (*r1p != 0x90 && *r1p != 0x61) + if (!sectok_swOK(*swp)) return -1; } - printf ("rsa key loading done! :)\n"); return 0; } int cyberflex_verify_AUT0(int fd, int cla, unsigned char *aut0, int aut0len) { - int n, r1, r2; + int sw; - n = scwrite(fd, cla, 0x2a, 0, 0, aut0len, aut0, &r1, &r2); - if (n < 0 || r1 != 0x90) { - if (n >= 0) - print_r1r2(r1, r2); + sectok_apdu(fd, cla, 0x2a, 0, 0, aut0len, aut0, 0, NULL, &sw); + if (!sectok_swOK(sw)) return -1; - } + return 0; } @@ -252,16 +233,16 @@ int cyberflex_inq_class(int fd) { unsigned char buf[32]; - int n, r1, r2; + int n, sw; - n = scread(fd, 0x00, 0xca, 0, 1, 0x16, buf, &r1, &r2); - if (n >= 0 && r1 == 0x90) + n = sectok_apdu(fd, 0x00, 0xca, 0, 1, 0, NULL, 0x16, buf, &sw); + if (sectok_swOK(sw)) return 0x00; - if (n >= 0 && r1 == 0x6d) { + if (n >= 0 && sectok_r1(sw) == 0x6d) { /* F0 card? */ - n = scread(fd, 0xf0, 0xca, 0, 1, 0x16, buf, &r1, &r2); - if (n >= 0 && r1 == 0x90) + sectok_apdu(fd, 0xf0, 0xca, 0, 1, 0, NULL, 0x16, buf, &sw); + if (sectok_swOK(sw)) return 0xf0; } diff --git a/lib/libsectok/ifdhandler.c b/lib/libsectok/ifdhandler.c index ad4a07ef3b2..3f0680f411a 100644 --- a/lib/libsectok/ifdhandler.c +++ b/lib/libsectok/ifdhandler.c @@ -1,4 +1,4 @@ -/* $Id: ifdhandler.c,v 1.4 2001/06/08 15:04:02 rees Exp $ */ +/* $Id: ifdhandler.c,v 1.5 2001/07/02 20:07:08 rees Exp $ */ /* copyright 2000 @@ -41,7 +41,7 @@ such damages. #include <string.h> #include <string.h> -#include "sectok.h" +#include "sc7816.h" #include "todos_scrw.h" #include "ifdhandler.h" @@ -69,7 +69,7 @@ IO_Create_Channel(u_long ChannelId) int i, ttyn; #ifdef DEBUG - fprintf (stderr, "IO_Create_Channel: ChannelId == %06x\n", ChannelId); + fprintf (stderr, "IO_Create_Channel: ChannelId == %06x\n", (int) ChannelId); #endif /* DEBUG */ if ((ChannelId & 0xffff0000) != 0x10000) @@ -161,7 +161,7 @@ IFD_Set_Capabilities(u_long Tag, u_char Value[]) cap_table[i].flags = (int)*((int *)Value); #ifdef DEBUG fprintf (stderr, "cap_table[%x].flags = %d\n", - Tag, cap_table[i].flags); + (int) Tag, cap_table[i].flags); #endif DEBUG return 0; @@ -222,7 +222,7 @@ IFD_Transmit_to_ICC(struct SCARD_IO_HEADER SendPci, int n, sw1, sw2; #ifdef DEBUG - printf("p3 %x ilen %x *olen %x\n", ibuf[4], ilen, *olen); + printf("p3 %x ilen %x *olen %x\n", ibuf[4], (int) ilen, (int) *olen); #endif ilen -= 5; diff --git a/lib/libsectok/ifdhandler.h b/lib/libsectok/ifdhandler.h index 578c53c488a..d1a0522d83b 100644 --- a/lib/libsectok/ifdhandler.h +++ b/lib/libsectok/ifdhandler.h @@ -1,4 +1,4 @@ -/* $Id: ifdhandler.h,v 1.2 2001/06/08 15:04:03 rees Exp $ */ +/* $Id: ifdhandler.h,v 1.3 2001/07/02 20:07:08 rees Exp $ */ /* copyright 2001 @@ -46,6 +46,12 @@ such damages. #define IFD_ICC_NOT_PRESENT 616 #define TAG_IFD_ATR 0x303 +/* Extra tags for things they forgot to put in the ifd interface */ +#define SCTAG_IFD_ATRLEN 0x6601 +#define SCTAG_IFD_CARDPRESENT 0x301 +#define SCTAG_OPEN_FLAGS 0x800 +#define SCTAG_RESET_FLAGS 0x801 + struct SCARD_IO_HEADER { u_long Protocol, Length; }; diff --git a/lib/libsectok/input.c b/lib/libsectok/input.c index 30f7c8280a3..971981095ac 100644 --- a/lib/libsectok/input.c +++ b/lib/libsectok/input.c @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.4 2001/06/26 22:47:24 rees Exp $ */ +/* $Id: input.c,v 1.5 2001/07/02 20:07:08 rees Exp $ */ /* copyright 2001 @@ -51,7 +51,7 @@ char *av[]; unsigned char obuf[256]; while (1) { - n = get_input(stdin, obuf, 1, sizeof obuf); + n = sectok_get_input(stdin, obuf, 1, sizeof obuf); if (!n) break; for (i = 0; i < n; i++) @@ -64,19 +64,19 @@ char *av[]; #ifndef __palmos__ int -get_input(FILE *f, unsigned char *obuf, int omin, int olen) +sectok_get_input(FILE *f, unsigned char *obuf, int omin, int olen) { int n = 0; char ibuf[1024]; while (n < omin && fgets(ibuf, sizeof ibuf, f) != NULL) - n += parse_input(ibuf, obuf + n, olen - n); + n += sectok_parse_input(ibuf, obuf + n, olen - n); return n; } #endif int -parse_input(char *ibuf, unsigned char *obuf, int olen) +sectok_parse_input(char *ibuf, unsigned char *obuf, int olen) { char *cp; unsigned char *up; @@ -137,7 +137,7 @@ parse_input(char *ibuf, unsigned char *obuf, int olen) void sectok_parse_fname(char *buf, unsigned char *fid) { - if (buf[0] == '/' || parse_input(buf, fid, 2) < 2) { + if (buf[0] == '/' || sectok_parse_input(buf, fid, 2) < 2) { /* root */ fid[0] = 0x3f; fid[1] = 0; diff --git a/lib/libsectok/r1r2.c b/lib/libsectok/r1r2.c index a2c303cb514..83927f2b8cd 100644 --- a/lib/libsectok/r1r2.c +++ b/lib/libsectok/r1r2.c @@ -1,4 +1,4 @@ -/* $Id: r1r2.c,v 1.3 2001/06/08 15:04:03 rees Exp $ */ +/* $Id: r1r2.c,v 1.4 2001/07/02 20:07:08 rees Exp $ */ /* copyright 1999 @@ -43,92 +43,110 @@ such damages. #include "sectok.h" -struct r1r2s { - int r1, r2; +static char *scsws(int sw); + +static struct r1r2s { + int sw; char *s; } r1r2s[] = { - {0x90, 0x00, "ok"}, - {0x61, 0xff, "ok; response available %x"}, - {0x62, 0x34, "no such method"}, - {0x62, 0x39, "out of memory"}, - {0x62, 0x55, "null pointer"}, - {0x62, 0x57, "array index out of bounds"}, - {0x62, 0x58, "index out of bounds"}, - {0x62, 0x81, "rec is corrupt"}, - {0x62, 0x83, "invalid file"}, - {0x63, 0x00, "auth failed"}, - {0x63, 0x81, "invalid key"}, - {0x67, 0xff, "invalid length; should be %x"}, - {0x69, 0x80, "bad param"}, - {0x69, 0x82, "unreadable"}, - {0x69, 0x83, "auth method blocked"}, - {0x69, 0x84, "data invalid"}, - {0x69, 0x85, "no file selected"}, - {0x69, 0x87, "busy/SM missing"}, - {0x69, 0x88, "SM wrong"}, - {0x6a, 0x80, "invalid file type"}, - {0x6a, 0x81, "function not supported"}, - {0x6a, 0x82, "file not found"}, - {0x6a, 0x83, "no such rec"}, - {0x6b, 0x00, "wrong mode"}, - {0x6c, 0xff, "wrong length; should be %x"}, - {0x6d, 0x00, "unknown instruction"}, - {0x6e, 0x00, "wrong class"}, - {0x6f, 0x14, "invalid applet state"}, - {0x6f, 0x15, "invalid state"}, - {0x6f, 0x19, "applet already running"}, - {0x6f, 0xb0, "uninitialized key"}, - {0x94, 0x81, "bad state"}, - {0x00, 0x00, NULL} + {0x9000, "ok"}, + + /* sectok errors */ + {0x0601, "no such tty"}, + {0x0602, "out of memory"}, + {0x0603, "timeout"}, + {0x0604, "slag!"}, + {0x0605, "card type not supported"}, + {0x0606, "no card in reader"}, + {0x0607, "not implemented"}, + {0x0608, "error loading driver"}, + {0x0609, "communications error"}, + {0x060a, "reader not open"}, + {0x060c, "config conflict"}, + {0x060d, "unknown error"}, + + /* card errors */ + {0x61ff, "ok; response available %x"}, + {0x6234, "no such method"}, + {0x6239, "out of memory"}, + {0x6255, "null pointer"}, + {0x6257, "array index out of bounds"}, + {0x6258, "index out of bounds"}, + {0x6281, "rec is corrupt"}, + {0x6283, "invalid file"}, + {0x6300, "auth failed"}, + {0x6381, "invalid key"}, + {0x67ff, "invalid length; should be %x"}, + {0x6980, "bad param"}, + {0x6982, "unreadable"}, + {0x6983, "auth method blocked"}, + {0x6984, "data invalid"}, + {0x6985, "no file selected"}, + {0x6987, "busy/SM missing"}, + {0x6988, "SM wrong"}, + {0x6a80, "invalid file type"}, + {0x6a81, "function not supported"}, + {0x6a82, "file not found"}, + {0x6a83, "no such rec"}, + {0x6b00, "wrong mode"}, + {0x6cff, "wrong length; should be %x"}, + {0x6d00, "unknown instruction"}, + {0x6e00, "wrong class"}, + {0x6f14, "invalid applet state"}, + {0x6f15, "invalid state"}, + {0x6f19, "applet already running"}, + {0x6fb0, "uninitialized key"}, + {0x9481, "bad state"}, + {0x0000, NULL} }; #ifdef TEST main(int ac, char *av[]) { - int r1, r2; + int sw; char *s; - if (ac != 3) { - fprintf(stderr, "usage: %s sw1 sw2 (in hex, please)\n", av[0]); + if (ac != 2) { + fprintf(stderr, "usage: %s sw (in hex, please)\n", av[0]); exit(1); } - sscanf(av[1], "%x", &r1); - sscanf(av[2], "%x", &r2); - print_r1r2(r1, r2); + sscanf(av[1], "%x", &sw); + sectok_print_sw(sw); exit(0); } #endif -void -print_r1r2(int r1, int r2) +void sectok_print_sw(int sw) { - printf("%s\n", get_r1r2s(r1, r2)); + printf("%s\n", sectok_get_sw(sw)); } -char * -get_r1r2s(int r1, int r2) +char *sectok_get_sw(int sw) { char *s; static char buf[64]; - s = scr1r2s(r1, r2); + s = scsws(sw); if (s) - sprintf(buf, "%02x %02x %s", r1, r2, s); + sprintf(buf, "%04x %s", sw, s); else - sprintf(buf, "%02x %02x", r1, r2); + sprintf(buf, "%04x", sw); return buf; } -char * -scr1r2s(int r1, int r2) +static char *scsws(int sw) { - int i; + int i, r1 = sectok_r1(sw), r2 = sectok_r2(sw), tr1, tr2; static char buf[64]; - for (i = 0; r1r2s[i].s; i++) - if (r1r2s[i].r1 == r1 && (r1r2s[i].r2 == r2 || r1r2s[i].r2 == 0xff)) + for (i = 0; r1r2s[i].s; i++) { + tr1 = sectok_r1(r1r2s[i].sw); + tr2 = sectok_r2(r1r2s[i].sw); + if (tr1 == r1 && (tr2 == r2 || tr2 == 0xff)) break; - if (r1r2s[i].r2 != 0xff) + } + + if (sectok_r2(r1r2s[i].sw) != 0xff) return r1r2s[i].s; sprintf(buf, r1r2s[i].s, r2); return buf; @@ -136,7 +154,7 @@ scr1r2s(int r1, int r2) #ifndef __palmos__ int -fdump_reply(FILE *f, unsigned char *p, int n, int r1, int r2) +sectok_fdump_reply(FILE *f, unsigned char *p, int n, int sw) { int i; @@ -144,14 +162,14 @@ fdump_reply(FILE *f, unsigned char *p, int n, int r1, int r2) fprintf(f, "%d:%x ", i + 1, p[i]); if (n) fprintf(f, "\n"); - if (r1) - fprintf(f, "%s\n", get_r1r2s(r1, r2)); + if (sw) + fprintf(f, "%s\n", sectok_get_sw(sw)); return n; } int -dump_reply(unsigned char *p, int n, int r1, int r2) +sectok_dump_reply(unsigned char *p, int n, int sw) { - return fdump_reply(stdout, p, n, r1, r2); + return sectok_fdump_reply(stdout, p, n, sw); } #endif diff --git a/lib/libsectok/sc7816.c b/lib/libsectok/sc7816.c index 4b067a42f22..7aa18e5a7a9 100644 --- a/lib/libsectok/sc7816.c +++ b/lib/libsectok/sc7816.c @@ -1,4 +1,4 @@ -/* $Id: sc7816.c,v 1.5 2001/06/26 16:26:14 deraadt Exp $ */ +/* $Id: sc7816.c,v 1.6 2001/07/02 20:07:08 rees Exp $ */ /* copyright 2000 @@ -38,53 +38,17 @@ such damages. * University of Michigan CITI, August 2000 */ -#include <sys/types.h> -#include <sys/time.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> -#include <dlfcn.h> #ifdef SCPERF #define SCPERF_FIRST_APPEARANCE #endif /* SCPERF */ #include "sectok.h" -#include "ifdhandler.h" - -#define MAX_READERS 32 -#define N_DEFAULT_READERS 4 - -#ifdef DL_READERS -static char defaultConfigFilePath[] = "/etc/reader.conf"; -static char defaultDriverPath[] = "/usr/local/pcsc/lib/libtodos_ag.so"; - -int DBUpdateReaders(char *readerconf, int (callback) (int rn, unsigned long channelId, char *driverFile)); - -/* the callback for DBUpdateReaders */ -int addReader(int rn, unsigned long channelID, char *driverFile); -void *lookupSym(void *handle, char *name); -#endif - -int openReader(int readerNum, int flags); - -typedef struct { - unsigned long channelID; - char *driverPath; - unsigned int driverLoaded; - /* for now, i'm only worry about the "bare essentials" */ - u_long (*open)(unsigned long channelID); - u_long (*close)(void); - u_long (*data)(struct SCARD_IO_HEADER junk, - unsigned char *cmdData, unsigned long cmdLen, - unsigned char *respData, unsigned long *respLen, - struct SCARD_IO_HEADER *moreJunk); - u_long (*power)(unsigned long command); - u_long (*getcapa)(unsigned long selector, unsigned char *buffer); - u_long (*setcapa)(unsigned long selector, unsigned char *buffer); - u_long (*cardpresent)(void); -} readerInfo; +#include "sc7816.h" char *scerrtab[] = { "ok", @@ -101,340 +65,81 @@ char *scerrtab[] = { "unknown error", }; -unsigned int numReaders; -readerInfo readers[MAX_READERS]; - -/* NI, 11/1/2000 : Now the body of scopen() is in scxopen() to allow - specifing a path to the config file or the driver. scopen() is - an entry function for scxopen() to maintain backward compatibility. */ -int -scopen(int ttyn, int flags, int *ep) -{ - return scxopen (ttyn, flags, ep, NULL, NULL); -} - -/* - if (config_path != NULL and driver_name != NULL) error; - if (config_path != NULL) use reader.conf there; - if (driver_path != NULL) use the specified driver; - if (config_path == NULL and driver_path == NULL) use /etc/reader.conf; - - Note that the config file is read only once, and drivers are only loaded once, - so config_path and driver_path are ignored on subsequent calls. -*/ - int -scxopen(int ttyn, int flags, int *ep, char *config_path, char *driver_path) +scxopen(int rn, int flags, int *ep, char *config_path, char *driver_path) { - int r = 0; - -#ifdef SCPERF - SetTime ("scopen() start"); -#endif /* SCPERF */ - - if (ttyn < 0 || ttyn >= MAX_READERS) { - r = SCENOTTY; - goto out; - } + int r, sw; -#ifdef DL_READERS - if (driver_path) { - /* caller specified a particular driver path to use */ - if (config_path) { - /* but also specified a config file, which is an error. */ - r = SCECNFFILES; - goto out; - } - if (!readers[ttyn].driverPath) { - /* need a driver */ - if (addReader(ttyn, (0x10000 + ttyn), driver_path) < 0) { - r = SCEDRVR; - goto out; - } - } - } + flags ^= STONOWAIT; - if (numReaders == 0) { - /* no drivers; read the config file */ - if (!config_path) - config_path = defaultConfigFilePath; - if (DBUpdateReaders(config_path, addReader) < 0) { - int i; - - if (config_path != defaultConfigFilePath) { - /* Something wrong with caller's config file path. */ - r = SCEDRVR; - goto out; - } - /* This usually means there is no reader.conf. Supply defaults. */ - for (i = 0; i < N_DEFAULT_READERS; i++) - addReader(i, (0x10000 | i), defaultDriverPath); - } - } -#else - numReaders = N_DEFAULT_READERS; -#endif + r = sectok_xopen(rn, flags, config_path, driver_path, &sw); - r = openReader(ttyn, flags); - - if (!r && (flags & SCODSR)) { - /* Wait for card present */ - while (!sccardpresent(ttyn)) - sleep(1); + if (ep) { + if (sectok_r1(sw) == 0x06) + *ep = sectok_r2(sw); + else + *ep = SCECOMM; } - out: -#ifdef SCPERF - SetTime ("scopen() end"); -#endif /* SCPERF */ - - if (ep) - *ep = r; - return r ? -1 : ttyn; + return r; } int -openReader(int readerNum, int flags) +scopen(int rn, int flags, int *ep) { - readerInfo *reader; - -#ifdef DEBUG - fprintf(stderr, "openReader %d\n", readerNum); -#endif - - if (readerNum < 0 || readerNum >= MAX_READERS) - return SCEDRVR; - reader = &readers[readerNum]; - - if (!reader->driverLoaded) { -#ifdef DL_READERS - void *libHandle; - - if (!reader->driverPath) - return SCEDRVR; - libHandle = dlopen(reader->driverPath, RTLD_LAZY); - if (!libHandle) { -#ifdef DEBUG - fprintf(stderr, "%s: %s\n", reader->driverPath, dlerror()); -#endif - return SCEDRVR; - } - reader->open = lookupSym(libHandle, "IO_Create_Channel"); - if (reader->open == NULL) - return SCEDRVR; - - reader->close = lookupSym(libHandle, "IO_Close_Channel"); - if (reader->close == NULL) - return SCEDRVR; - - reader->data = lookupSym(libHandle, "IFD_Transmit_to_ICC"); - if (reader->data == NULL) - return SCEDRVR; - - reader->power = lookupSym(libHandle, "IFD_Power_ICC"); - if (reader->power == NULL) - return SCEDRVR; - - reader->getcapa = lookupSym(libHandle, "IFD_Get_Capabilities"); - if (reader->getcapa == NULL) - return SCEDRVR; - - reader->setcapa = lookupSym(libHandle, "IFD_Set_Capabilities"); - if (reader->setcapa == NULL) - return SCEDRVR; - - reader->cardpresent = lookupSym(libHandle, "IFD_Is_ICC_Present"); -#else /* DL_READERS */ - reader->open = IO_Create_Channel; - reader->close = IO_Close_Channel; - reader->data = IFD_Transmit_to_ICC; - reader->power = IFD_Power_ICC; - reader->getcapa = IFD_Get_Capabilities; - reader->setcapa = IFD_Set_Capabilities; - reader->cardpresent = IFD_Is_ICC_Present; - reader->channelID = (0x10000 | readerNum); -#endif /* DL_READERS */ - - reader->driverLoaded = 1; - } - - /* send flags to the driver */ - reader->setcapa(SCTAG_OPEN_FLAGS, (u_char *)&flags); - /* if this returns an error, setcapa is not supported in this driver, - but that's OK. */ - - if (reader->open(reader->channelID)) - return SCECOMM; - else - return 0; + return scxopen(rn, flags, ep, NULL, NULL); } int -scclose(int ttyn) +scclose(int fd) { - readerInfo *reader = &readers[ttyn]; - - if (ttyn < 0 || ttyn >= MAX_READERS) - return -1; - - reader = &readers[ttyn]; - - if (!reader->driverLoaded) - return -1; - - return (reader->close()) ? -1 : 0; + return sectok_close(fd); } int -sccardpresent(int ttyn) +sccardpresent(int fd) { - readerInfo *reader = &readers[ttyn]; - unsigned long v; - - if (!reader->driverLoaded) - return 0; - - if (reader->cardpresent) - v = reader->cardpresent(); - else if (reader->getcapa(SCTAG_IFD_CARDPRESENT, (unsigned char *) &v)) - return 1; - - return (v == IFD_ICC_PRESENT || v == 0) ? 1 : 0; + return sectok_cardpresent(fd); } int -scxreset(int ttyn, int flags, unsigned char *atr, int *ep) +scxreset(int fd, int flags, unsigned char *atr, int *ep) { - readerInfo *reader = &readers[ttyn]; - int n = 0, r = SCEOK; - struct scparam param; - -#ifdef SCPERF - SetTime ("scxreset() start"); -#endif /* SCPERF */ - - if (!reader->driverLoaded) { - r = SCECLOSED; - goto out; - } - - if (!sccardpresent(ttyn)) { - r = SCENOCARD; - goto out; - } + int r, sw; - /* send flags to the driver */ - reader->setcapa(SCTAG_RESET_FLAGS, (u_char *)&flags); - /* if this returns an error, setcapa is not supported in this driver, - but that's OK. */ + r = sectok_reset(fd, flags, atr, &sw); - if (reader->power(IFD_RESET)) { -#ifdef DEBUG - fprintf(stderr, "power failed!\n"); -#endif - r = SCESLAG; - goto out; - } - - if (atr && reader->getcapa(TAG_IFD_ATR, atr)) { -#ifdef DEBUG - fprintf(stderr, "reset failed!\n"); -#endif - r = SCESLAG; - goto out; - } - - if (reader->getcapa(SCTAG_IFD_ATRLEN, (unsigned char *) &n) || n <= 0) { - /* can't get atr len, take a wild guess */ - if (atr) { - for (n = MAX_ATR_SIZE - 1; !atr[n]; n--) - ; - n--; - } else - n = MAX_ATR_SIZE; + if (ep) { + if (sectok_swOK(sw)) + *ep = SCEOK; + else if (sectok_r1(sw) == 0x06) + *ep = sectok_r2(sw); + else + *ep = SCESLAG; } - if (flags & SCRV) - parse_atr(-1, flags, atr, n, ¶m); - - out: - if (ep) - *ep = r; - -#ifdef SCPERF - SetTime ("scxreset() end"); -#endif /* SCPERF */ - - return n; + return r; } int -screset(int ttyn, unsigned char *atr, int *ep) +screset(int fd, unsigned char *atr, int *ep) { - return scxreset(ttyn, 0, atr, ep); + return scxreset(fd, 0, atr, ep); } int -scrw(int ttyn, int cla, int ins, int p1, int p2, int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *sw1p, int *sw2p) +scrw(int fd, int cla, int ins, int p1, int p2, int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *sw1p, int *sw2p) { - unsigned char cmd[6+255], rsp[255+2]; - unsigned long n; - int le; - readerInfo *reader = &readers[ttyn]; - struct SCARD_IO_HEADER garbage; - - if (reader->driverLoaded == 0) - return SCECLOSED; - - cmd[0] = cla; - cmd[1] = ins; - cmd[2] = p1; - cmd[3] = p2; - - ilen &= 0xff; - le = (255 < olen) ? 255 : olen; - - if (ilen && ibuf) { - /* Send "in" data */ - cmd[4] = ilen; - memcpy(&cmd[5], ibuf, ilen); - ilen += 5; - if (le) - cmd[ilen++] = le; - n = obuf ? sizeof rsp : 2; - if (reader->data(garbage, cmd, ilen, rsp, &n, NULL) || n < 2) - return -1; - if (rsp[n-2] == 0x61 && olen && obuf) { - /* Response available; get it (driver should do this but some don't) */ - cmd[1] = 0xc0; - cmd[2] = cmd[3] = 0; - cmd[4] = rsp[n-1]; - n = sizeof rsp; - if (reader->data(garbage, cmd, 5, rsp, &n, NULL)) - return -1; - } - } else { - /* Get "out" data */ - cmd[4] = olen; - n = sizeof rsp; - if (reader->data(garbage, cmd, 5, rsp, &n, NULL)) - return -1; - } - - if (n >= 2) { - *sw1p = rsp[n-2]; - *sw2p = rsp[n-1]; - n -= 2; - } - - if (n && olen) - memcpy(obuf, rsp, (n < olen) ? n : olen); + int n, sw; + n = sectok_apdu(fd, cla, ins, p1, p2, ilen, ibuf, olen, obuf, &sw); + *sw1p = sectok_r1(sw); + *sw2p = sectok_r2(sw); return n; } int -scwrite(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, int *sw1p, int *sw2p) +scwrite(int fd, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, int *sw1p, int *sw2p) { int rv; #ifdef SCPERF @@ -445,7 +150,7 @@ scwrite(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, sprintf (scperf_buf, "scwrite (ins %02x, p3 %02x) start", ins, p3); SetTime(scperf_buf); #endif /* SCPERF */ - rv = scrw(ttyn, cla, ins, p1, p2, p3, buf, 0, NULL, sw1p, sw2p); + rv = scrw(fd, cla, ins, p1, p2, p3, buf, 0, NULL, sw1p, sw2p); #ifdef SCPERF SetTime("scwrite() end"); @@ -454,7 +159,7 @@ scwrite(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, } int -scread(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, int *sw1p, int *sw2p) +scread(int fd, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, int *sw1p, int *sw2p) { int rv; #ifdef SCPERF @@ -465,7 +170,7 @@ scread(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, i sprintf (scperf_buf, "scread (ins %02x, p3 %02x) start", ins, p3); SetTime(scperf_buf); #endif /* SCPERF */ - rv = scrw(ttyn, cla, ins, p1, p2, 0, NULL, p3, buf, sw1p, sw2p); + rv = scrw(fd, cla, ins, p1, p2, 0, NULL, p3, buf, sw1p, sw2p); #ifdef SCPERF SetTime("scread() end"); @@ -473,39 +178,42 @@ scread(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, i return rv; } -#ifdef DL_READERS +#ifndef __palmos__ int -addReader(int rn, unsigned long channelID, char *driverFile) +parse_input(char *ibuf, unsigned char *obuf, int olen) { - readerInfo *reader; + return sectok_parse_input(ibuf, obuf, olen); +} - if (rn < 0 || rn >= MAX_READERS) - return -1; +int +get_input(FILE *f, unsigned char *obuf, int omin, int olen) +{ + return sectok_get_input(f, obuf, omin, olen); +} +#endif - reader = &readers[rn]; +void +print_r1r2(int r1, int r2) +{ + printf("%s\n", get_r1r2s(r1, r2)); +} - if (reader->driverPath) - return -1; +char * +get_r1r2s(int r1, int r2) +{ + return sectok_get_sw(sectok_mksw(r1, r2)); +} - reader->channelID = channelID; - reader->driverPath = strdup(driverFile); - reader->driverLoaded = 0; - numReaders++; - return 0; +#ifndef __palmos__ +int +fdump_reply(FILE *f, unsigned char *p, int n, int r1, int r2) +{ + return sectok_fdump_reply(f, p, n, sectok_mksw(r1, r2)); } -void * -lookupSym(void *handle, char *name) +int +dump_reply(unsigned char *p, int n, int r1, int r2) { -#ifdef __linux__ - return dlsym(handle, name); -#elif __sun - return dlsym(handle, name); -#else - char undername[32]; - - sprintf(undername, "_%s", name); - return dlsym(handle, undername); -#endif + return sectok_fdump_reply(stdout, p, n, sectok_mksw(r1, r2)); } -#endif /* DL_READERS */ +#endif diff --git a/lib/libsectok/scT1.c b/lib/libsectok/scT1.c index a1bc4059693..62b1a13602e 100644 --- a/lib/libsectok/scT1.c +++ b/lib/libsectok/scT1.c @@ -1,4 +1,4 @@ -/* $Id: scT1.c,v 1.3 2001/06/08 15:04:04 rees Exp $ */ +/* $Id: scT1.c,v 1.4 2001/07/02 20:07:08 rees Exp $ */ /* copyright 1997, 1999, 2000 @@ -50,7 +50,7 @@ such damages. #include <sys/time.h> #endif -#include "sectok.h" +#include "sc7816.h" #ifdef __palmos__ #undef printf diff --git a/lib/libsectok/scio.c b/lib/libsectok/scio.c index 81c4ddfc883..0234be28dff 100644 --- a/lib/libsectok/scio.c +++ b/lib/libsectok/scio.c @@ -1,4 +1,4 @@ -/* $Id: scio.c,v 1.4 2001/06/08 15:04:04 rees Exp $ */ +/* $Id: scio.c,v 1.5 2001/07/02 20:07:09 rees Exp $ */ /* copyright 1997 @@ -49,12 +49,13 @@ such damages. #include <termios.h> #include <signal.h> #include <fcntl.h> +#include <errno.h> -#include "sectok.h" +#include "sc7816.h" #include "todos_scrw.h" -int todos_scfdopen(int ttyn, int fd, int flags, int *ep); -int todos_sccts(int ttyn); +static int todos_scfdopen(int ttyn, int fd, int flags, int *ep); +static int todos_sccts(int ttyn); #ifdef __linux static char ttynametmpl[] = "/dev/cua%01d"; @@ -111,13 +112,15 @@ todos_scopen(int ttyn, int flags, int *ep) if ((ttyn = todos_scfdopen(ttyn, fd, flags, ep)) < 0) { close(fd); - return -2; + return -1; } /* Figure out which reader we have */ if (ioctl(fd, TIOCMGET, &i) < 0) { close(fd); - return 0; + if (ep) + *ep = SCENOTTY; + return -1; } #ifndef __sun /* Todos has RTS wired to RI, so set RTS and see if RI goes high */ @@ -136,8 +139,12 @@ todos_scopen(int ttyn, int flags, int *ep) if (flags & SCODSR) { /* Wait for card present */ - while (!todos_sccardpresent(ttyn)) + while (!todos_sccardpresent(ttyn)) { + errno = 0; sleep(1); + if (errno == EINTR) + return -1; + } } if (flags & SCOHUP) { @@ -219,7 +226,7 @@ todos_scsetspeed(int ttyn, int speed) return tcsetattr(sc[ttyn].fd, TCSADRAIN, &sc[ttyn].tio1); } -int +static int todos_scfdopen(int ttyn, int fd, int flags, int *ep) { struct termios t; @@ -275,7 +282,7 @@ todos_scfdopen(int ttyn, int fd, int flags, int *ep) /* The open may or may not have reset the card. Wait a while then flush anything that came in on the port. */ scsleep(250); - todos_scdrain(ttyn); + tcflush(sc[ttyn].fd, TCIFLUSH); return ttyn; } @@ -302,7 +309,7 @@ todos_scdsr(int ttyn) return ((i & TIOCM_DSR) ? 1 : 0); } -int +static int todos_sccts(int ttyn) { int fd = sc[ttyn].fd; @@ -453,9 +460,3 @@ scsleep(int ms) select(0, NULL, NULL, NULL, &tv); } - -void -todos_scdrain(int ttyn) -{ - tcflush(sc[ttyn].fd, TCIFLUSH); -} diff --git a/lib/libsectok/scrw.c b/lib/libsectok/scrw.c index b4633310358..fb248356ae4 100644 --- a/lib/libsectok/scrw.c +++ b/lib/libsectok/scrw.c @@ -1,4 +1,4 @@ -/* $Id: scrw.c,v 1.4 2001/06/08 15:04:05 rees Exp $ */ +/* $Id: scrw.c,v 1.5 2001/07/02 20:07:09 rees Exp $ */ /* copyright 1997, 1999, 2000 @@ -51,7 +51,7 @@ such damages. #ifdef SCPERF #define SCPERF_FIRST_APPEARANCE #endif /* SCPERF */ -#include "sectok.h" +#include "sc7816.h" #include "todos_scrw.h" /* external variable */ @@ -192,14 +192,16 @@ todos_scioT0(int ttyn, int io, int cla, int ins, int p1, int p2, int p3, unsigne ackxins = (ack ^ ins) & 0xfe; if (ackxins == 0xfe) { - /* xfer next data byte */ - if (todos_scioproc(ttyn, io, bp++) != SCEOK) { + if (n < p3) { + /* xfer next data byte */ + if (todos_scioproc(ttyn, io, bp++) != SCEOK) { #ifdef DEBUG - printf("%d ms timeout reading next data byte\n", scparam[ttyn].cwt); + printf("%d ms timeout reading next data byte\n", scparam[ttyn].cwt); #endif - return -1; + return -1; + } + n++; } - n++; } else if (ackxins == 0) { /* xfer all remaining data bytes */ diff --git a/lib/libsectok/sectok.c b/lib/libsectok/sectok.c index f23e93c840c..5a760fc723c 100644 --- a/lib/libsectok/sectok.c +++ b/lib/libsectok/sectok.c @@ -1,4 +1,4 @@ -/* $Id: sectok.c,v 1.3 2001/06/28 21:37:28 rees Exp $ */ +/* $Id: sectok.c,v 1.4 2001/07/02 20:07:09 rees Exp $ */ /* copyright 2000 @@ -37,17 +37,417 @@ such damages. * University of Michigan CITI, July 2001 */ +#include <sys/types.h> +#include <sys/time.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> +#include <dlfcn.h> +#include <errno.h> #include "sectok.h" +#include "ifdhandler.h" + +#define MAX_READERS 32 +#define N_DEFAULT_READERS 4 #define myisprint(x) ((x) >= '!' && (x) <= 'z') +#ifdef DL_READERS +static char defaultConfigFilePath[] = "/etc/reader.conf"; +static char defaultDriverPath[] = "/usr/local/pcsc/lib/libtodos_ag.so"; + +int DBUpdateReaders(char *readerconf, int (callback) (int rn, unsigned long channelId, char *driverFile)); + +/* the callback for DBUpdateReaders */ +static int addReader(int rn, unsigned long channelID, char *driverFile); +static void *lookupSym(void *handle, char *name); +#endif + +static int openReader(int readerNum, int flags); + +typedef struct { + unsigned long channelID; + char *driverPath; + unsigned int driverLoaded; + /* for now, i'm only worry about the "bare essentials" */ + u_long (*open)(unsigned long channelID); + u_long (*close)(void); + u_long (*data)(struct SCARD_IO_HEADER junk, + unsigned char *cmdData, unsigned long cmdLen, + unsigned char *respData, unsigned long *respLen, + struct SCARD_IO_HEADER *moreJunk); + u_long (*power)(unsigned long command); + u_long (*getcapa)(unsigned long selector, unsigned char *buffer); + u_long (*setcapa)(unsigned long selector, unsigned char *buffer); + u_long (*cardpresent)(void); +} readerInfo; + +unsigned int numReaders; +readerInfo readers[MAX_READERS]; + unsigned char root_fid[] = {0x3f, 0x00}; +/* + if (config_path != NULL and driver_name != NULL) error; + if (config_path != NULL) use reader.conf there; + if (driver_path != NULL) use the specified driver; + if (config_path == NULL and driver_path == NULL) use /etc/reader.conf; + + Note that the config file is read only once, and drivers are only loaded once, + so config_path and driver_path are ignored on subsequent calls. +*/ + +int +sectok_xopen(int rn, int flags, char *config_path, char *driver_path, int *swp) +{ + int r = 0; + +#ifdef SCPERF + SetTime ("scopen() start"); +#endif /* SCPERF */ + + if (rn < 0 || rn >= MAX_READERS) { + r = STENOTTY; + goto out; + } + +#ifdef DL_READERS + if (driver_path) { + /* caller specified a particular driver path to use */ + if (config_path) { + /* but also specified a config file, which is an error. */ + r = STECNFFILES; + goto out; + } + if (!readers[rn].driverPath) { + /* need a driver */ + if (addReader(rn, (0x10000 + rn), driver_path) < 0) { + r = STEDRVR; + goto out; + } + } + } + + if (numReaders == 0) { + /* no drivers; read the config file */ + if (!config_path) + config_path = defaultConfigFilePath; + if (DBUpdateReaders(config_path, addReader) < 0) { + int i; + + if (config_path != defaultConfigFilePath) { + /* Something wrong with caller's config file path. */ + r = STEDRVR; + goto out; + } + /* This usually means there is no reader.conf. Supply defaults. */ + for (i = 0; i < N_DEFAULT_READERS; i++) + addReader(i, (0x10000 | i), defaultDriverPath); + } + } +#else + numReaders = N_DEFAULT_READERS; +#endif + + r = openReader(rn, flags); + + if (sectok_swOK(r) && !(flags & STONOWAIT)) { + /* Wait for card present */ + while (!sectok_cardpresent(rn)) { + errno = 0; + sleep(1); + if (errno == EINTR) { + r = STENOCARD; + break; + } + } + } + + out: +#ifdef SCPERF + SetTime ("scopen() end"); +#endif /* SCPERF */ + + if (swp) + *swp = r; + return (!sectok_swOK(r) ? -1 : rn); +} + +int sectok_open(int rn, int flags, int *swp) +{ + return sectok_xopen(rn, flags, NULL, NULL, swp); +} + +static int +openReader(int readerNum, int flags) +{ + readerInfo *reader; + +#ifdef DEBUG + fprintf(stderr, "openReader %d\n", readerNum); +#endif + + if (readerNum < 0 || readerNum >= MAX_READERS) + return STEDRVR; + reader = &readers[readerNum]; + + if (!reader->driverLoaded) { +#ifdef DL_READERS + void *libHandle; + + if (!reader->driverPath) + return STEDRVR; + libHandle = dlopen(reader->driverPath, RTLD_LAZY); + if (!libHandle) { +#ifdef DEBUG + fprintf(stderr, "%s: %s\n", reader->driverPath, dlerror()); +#endif + return STEDRVR; + } + reader->open = lookupSym(libHandle, "IO_Create_Channel"); + if (reader->open == NULL) + return STEDRVR; + + reader->close = lookupSym(libHandle, "IO_Close_Channel"); + if (reader->close == NULL) + return STEDRVR; + + reader->data = lookupSym(libHandle, "IFD_Transmit_to_ICC"); + if (reader->data == NULL) + return STEDRVR; + + reader->power = lookupSym(libHandle, "IFD_Power_ICC"); + if (reader->power == NULL) + return STEDRVR; + + reader->getcapa = lookupSym(libHandle, "IFD_Get_Capabilities"); + if (reader->getcapa == NULL) + return STEDRVR; + + reader->setcapa = lookupSym(libHandle, "IFD_Set_Capabilities"); + if (reader->setcapa == NULL) + return STEDRVR; + + reader->cardpresent = lookupSym(libHandle, "IFD_Is_ICC_Present"); +#else /* DL_READERS */ + reader->open = IO_Create_Channel; + reader->close = IO_Close_Channel; + reader->data = IFD_Transmit_to_ICC; + reader->power = IFD_Power_ICC; + reader->getcapa = IFD_Get_Capabilities; + reader->setcapa = IFD_Set_Capabilities; + reader->cardpresent = IFD_Is_ICC_Present; + reader->channelID = (0x10000 | readerNum); +#endif /* DL_READERS */ + + reader->driverLoaded = 1; + } + + /* send flags to the driver */ + flags ^= STONOWAIT; + reader->setcapa(SCTAG_OPEN_FLAGS, (u_char *)&flags); + /* if this returns an error, setcapa is not supported in this driver, + but that's OK. */ + + if (reader->open(reader->channelID)) + return STECOMM; + else + return STEOK; +} + +int +sectok_close(int fd) +{ + readerInfo *reader = &readers[fd]; + + if (fd < 0 || fd >= MAX_READERS) + return -1; + + reader = &readers[fd]; + + if (!reader->driverLoaded) + return -1; + + return (reader->close()) ? -1 : 0; +} + +int +sectok_cardpresent(int fd) +{ + readerInfo *reader = &readers[fd]; + unsigned long v; + + if (!reader->driverLoaded) + return 0; + + if (reader->cardpresent) + v = reader->cardpresent(); + else if (reader->getcapa(SCTAG_IFD_CARDPRESENT, (unsigned char *) &v)) + return 1; + + return (v == IFD_ICC_PRESENT || v == 0) ? 1 : 0; +} + +int +sectok_reset(int fd, int flags, unsigned char *atr, int *swp) +{ + readerInfo *reader = &readers[fd]; + int n = 0, r = STEOK; + +#ifdef SCPERF + SetTime ("scxreset() start"); +#endif /* SCPERF */ + + if (!reader->driverLoaded) { + r = STECLOSED; + goto out; + } + + if (!sectok_cardpresent(fd)) { + r = STENOCARD; + goto out; + } + + /* send flags to the driver */ + reader->setcapa(SCTAG_RESET_FLAGS, (u_char *)&flags); + /* if this returns an error, setcapa is not supported in this driver, + but that's OK. */ + + if (reader->power(IFD_RESET)) { +#ifdef DEBUG + fprintf(stderr, "power failed!\n"); +#endif + r = STESLAG; + goto out; + } + + if (atr && reader->getcapa(TAG_IFD_ATR, atr)) { +#ifdef DEBUG + fprintf(stderr, "reset failed!\n"); +#endif + r = STESLAG; + goto out; + } + + if (reader->getcapa(SCTAG_IFD_ATRLEN, (unsigned char *) &n) || n <= 0) { + /* can't get atr len, take a wild guess */ + if (atr) { + for (n = MAX_ATR_SIZE - 1; !atr[n]; n--) + ; + n--; + } else + n = MAX_ATR_SIZE; + } + + out: + if (swp) + *swp = r; + +#ifdef SCPERF + SetTime ("scxreset() end"); +#endif /* SCPERF */ + + return n; +} + +#ifdef DL_READERS +static int +addReader(int rn, unsigned long channelID, char *driverFile) +{ + readerInfo *reader; + + if (rn < 0 || rn >= MAX_READERS) + return -1; + + reader = &readers[rn]; + + if (reader->driverPath) + return -1; + + reader->channelID = channelID; + reader->driverPath = strdup(driverFile); + reader->driverLoaded = 0; + numReaders++; + return 0; +} + +static void * +lookupSym(void *handle, char *name) +{ +#ifdef __linux__ + return dlsym(handle, name); +#elif __sun + return dlsym(handle, name); +#else + char undername[32]; + + sprintf(undername, "_%s", name); + return dlsym(handle, undername); +#endif +} +#endif /* DL_READERS */ + +int +sectok_apdu(int fd, int cla, int ins, int p1, int p2, + int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *swp) +{ + unsigned char cmd[6+255], rsp[255+2]; + unsigned long n; + int le; + readerInfo *reader = &readers[fd]; + struct SCARD_IO_HEADER garbage; + + if (reader->driverLoaded == 0) + return STECLOSED; + + cmd[0] = cla; + cmd[1] = ins; + cmd[2] = p1; + cmd[3] = p2; + + ilen &= 0xff; + le = (255 < olen) ? 255 : olen; + + if (ilen && ibuf) { + /* Send "in" data */ + cmd[4] = ilen; + memcpy(&cmd[5], ibuf, ilen); + ilen += 5; + if (le) + cmd[ilen++] = le; + n = obuf ? sizeof rsp : 2; + if (reader->data(garbage, cmd, ilen, rsp, &n, NULL) || n < 2) + return -1; + if (rsp[n-2] == 0x61 && olen && obuf) { + /* Response available; get it (driver should do this but some don't) */ + cmd[1] = 0xc0; + cmd[2] = cmd[3] = 0; + cmd[4] = rsp[n-1]; + n = sizeof rsp; + if (reader->data(garbage, cmd, 5, rsp, &n, NULL)) + return -1; + } + } else { + /* Get "out" data */ + cmd[4] = olen; + n = sizeof rsp; + if (reader->data(garbage, cmd, 5, rsp, &n, NULL)) + return -1; + } + + if (n >= 2) { + *swp = sectok_mksw(rsp[n-2], rsp[n-1]); + n -= 2; + } + + if (n && olen) + memcpy(obuf, rsp, (n < olen) ? n : olen); + + return n; +} + void sectok_fmt_fid(char *fname, int f0, int f1) { @@ -58,13 +458,12 @@ sectok_fmt_fid(char *fname, int f0, int f1) } int -sectok_selectfile(int fd, int cla, unsigned char *fid, int *r1p, int *r2p) +sectok_selectfile(int fd, int cla, unsigned char *fid, int *swp) { - int n, r1, r2; unsigned char obuf[256]; - n = scrw(fd, cla, 0xa4, 0, 0, 2, fid, sizeof obuf, obuf, &r1, &r2); - if (n < 0 || (r1 != 0x90 && r1 != 0x61)) + sectok_apdu(fd, cla, 0xa4, 0, 0, 2, fid, sizeof obuf, obuf, swp); + if (!sectok_swOK(*swp)) return -1; return 0; diff --git a/lib/libsectok/sectok.h b/lib/libsectok/sectok.h index 0438e9d3eb8..f112c1d265d 100644 --- a/lib/libsectok/sectok.h +++ b/lib/libsectok/sectok.h @@ -1,7 +1,7 @@ -/* $Id: sectok.h,v 1.10 2001/06/28 21:27:54 rees Exp $ */ +/* $Id: sectok.h,v 1.11 2001/07/02 20:07:09 rees Exp $ */ /* -copyright 1997, 2000 +copyright 2001 the regents of the university of michigan all rights reserved @@ -30,179 +30,71 @@ if it has been or is hereafter advised of the possibility of such damages. */ -/* SCPERF - performance evaluation */ -#ifdef SCPERF -#include <stdlib.h> -#include <sys/types.h> -#include <sys/time.h> -#endif /* SCPERF */ - -/* open flags */ -#define SCODSR 0x1 /* wait for dsr */ -#define SCODCD 0x2 /* wait for dcd */ -#define SCOHUP 0x4 /* send signal on card removal */ -#define SCOXCTS 0x8 /* wait for no cts (todos reader) */ -#define SCOXDTR 0x10 /* invert dtr (todos reader) */ -#define SCOINVRT 0x20 /* inverse convention */ +/* Open flags */ +#define STONOWAIT 0x1 /* don't wait for card present */ +#define STOHUP 0x4 /* send signal on card removal */ /* Reset flags */ -#define SCRV 0x1 /* be verbose */ -#define SCRLEN 0x2 /* determine length by examing atr */ -#define SCRTODOS 0x4 /* Todos reader */ -#define SCRFORCE 0x8 /* Talk to card even if atr is bad */ - -/* error codes */ -#define SCEOK 0 -#define SCENOTTY 1 /* no such tty */ -#define SCENOMEM 2 /* malloc (or similar) failed */ -#define SCTIMEO 3 /* time out */ -#define SCESLAG 4 /* slag (no atr) */ -#define SCENOSUPP 5 /* card type not supported */ -#define SCENOCARD 6 /* no card in reader */ -#define SCENOIMPL 7 -#define SCEDRVR 8 -#define SCECOMM 9 -#define SCECLOSED 10 -#define SCENOFILE 11 /* wrong config path or driver path */ -#define SCECNFFILES 12 /* both config path and driver path are +#define STRLEN 0x2 /* determine length by examing atr */ +#define STRFORCE 0x8 /* Talk to card even if atr is bad */ + +/* Errors */ +#define STEOK 0x9000 +#define STENOTTY 0x0601 /* no such tty */ +#define STENOMEM 0x0602 /* malloc (or similar) failed */ +#define STTIMEO 0x0603 /* time out */ +#define STESLAG 0x0604 /* slag (no atr) */ +#define STENOSUPP 0x0605 /* card type not supported */ +#define STENOCARD 0x0606 /* no card in reader */ +#define STENOIMPL 0x0607 +#define STEDRVR 0x0608 +#define STECOMM 0x0609 +#define STECLOSED 0x060a +#define STECNFFILES 0x060c /* both config path and driver path are specified. thus conflict. */ -#define SCEUNKNOWN 13 - -/* Extra tags for things they forgot to put in the ifd interface */ -#define SCTAG_IFD_ATRLEN 0x6601 -#define SCTAG_IFD_CARDPRESENT 0x301 -#define SCTAG_OPEN_FLAGS 0x800 -#define SCTAG_RESET_FLAGS 0x801 +#define STEUNKNOWN 0x060d +#define STENOFILE 0x6a82 -extern char *scerrtab[]; - -extern struct scparam { - int t, etu, cwt, bwt, n; -} scparam[]; +/* Useful macros */ +#define sectok_r1(sw) (((sw) >> 8) & 0xff) +#define sectok_r2(sw) ((sw) & 0xff) +#define sectok_mksw(r1, r2) (((r1) << 8) | (r2)) +#define sectok_swOK(sw) (sectok_r1(sw) == 0x90 || sectok_r1(sw) == 0x61) extern unsigned char root_fid[]; -/* forward declarations */ - -int scopen(int ttyn, int flags, int *ep); -int scxopen(int ttyn, int flags, int *ep, - char *config_path, char *driver_path); -int scsetflags(int ttyn, int flags, int mask); -int scrw(int ttyn, int cla, int ins, int p1, int p2, int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *sw1p, int *sw2p); -int scread(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, int *sw1p, int *sw2p); -int scwrite(int ttyn, int cla, int ins, int p1, int p2, int p3, unsigned char *buf, int *sw1p, int *sw2p); -int sccardpresent(int ttyn); -int scdsr(int ttyn); -int scclose(int ttyn); -int screset(int ttyn, unsigned char *atr, int *ep); -int scxreset(int ttyn, int flags, unsigned char *atr, int *ep); -int scdtr(int ttyn, int cmd); -int scgetc(int ttyn, unsigned char *cp, int ms); -int scputc(int ttyn, int ic); -int scgetblk(int ttyn, unsigned char *bp, int n, int bwt, int cwt); -int scputblk(int ttyn, unsigned char *bp, int n); -void scsleep(int ms); -void scdrain(int ttyn); -int scioT1(int ttyn, int cla, int ins, int p1, int p2, int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *sw1p, int *sw2p); -int scioT1Iblk(int ttyn, int ilen, unsigned char *ibuf, unsigned char *obuf); -int scioT1pkt(int ttyn, unsigned char *ibuf, unsigned char *obuf); -int parse_atr(int ttyn, int flags, unsigned char *atr, int len, struct scparam *param); -int parse_input(char *ibuf, unsigned char *obuf, int olen); -#ifndef __palmos__ -int get_input(FILE *f, unsigned char *obuf, int omin, int olen); -int fdump_reply(FILE *f, unsigned char *p, int n, int r1, int r2); -int dump_reply(unsigned char *p, int n, int r1, int r2); -#endif -void print_r1r2(int r1, int r2); -char *get_r1r2s(int r1, int r2); -char *scr1r2s(int r1, int r2); -char *lookup_cmdname(int ins); - -/* Common card routines */ +/* Common card functions */ +int sectok_open(int rn, int flags, int *swp); +int sectok_xopen(int rn, int flags, char *config_path, char *driver_path, int *swp); +int sectok_reset(int fd, int flags, unsigned char *atr, int *swp); +int sectok_apdu(int fd, int cla, int ins, int p1, int p2, + int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *swp); +int sectok_cardpresent(int fd); +int sectok_close(int fd); +int sectok_selectfile(int fd, int cla, unsigned char *fid, int *swp); + +/* Convenience functions */ void sectok_fmt_fid(char *fname, int f0, int f1); -int sectok_selectfile(int fd, int cla, unsigned char *fid, int *r1p, int *r2p); void sectok_parse_fname(char *buf, unsigned char *fid); +int sectok_parse_input(char *ibuf, unsigned char *obuf, int olen); +#ifndef __palmos__ +int sectok_get_input(FILE *f, unsigned char *obuf, int omin, int olen); +int sectok_fdump_reply(FILE *f, unsigned char *p, int n, int sw); +int sectok_dump_reply(unsigned char *p, int n, int sw); +#endif +void sectok_print_sw(int sw); +char *sectok_get_sw(int sw); +char *sectok_get_ins(int ins); -/* Cyberflex */ -int cyberflex_create_file(int fd, int cla, unsigned char *fid, int size, int ftype, - int *r1p, int *r2p); -int cyberflex_delete_file(int fd, int cla, int f0, int f1, int *r1p, int *r2p); +/* Cyberflex functions */ +int cyberflex_create_file(int fd, int cla, unsigned char *fid, int size, int ftype, int *swp); +int cyberflex_delete_file(int fd, int cla, unsigned char *fid, int *swp); int cyberflex_load_rsa_pub(int fd, int cla, unsigned char *key_fid, - int key_len, unsigned char *key_data, int *r1p, int *r2p); + int key_len, unsigned char *key_data, int *swp); int cyberflex_load_rsa_priv(int fd, int cla, unsigned char *key_fid, - int nkey_elems, int keylen, unsigned char *key_elems[], - int *r1p, int *r2p); + int nkey_elems, int key_len, unsigned char *key_elems[], + int *swp); int cyberflex_verify_AUT0(int fd, int cla, unsigned char *aut0, int aut0len); int cyberflex_inq_class(int fd); void cyberflex_fill_key_block (unsigned char *dst, int key_num, int alg_num, unsigned char *key); - -/* SCPERF - performance evaluation */ -#ifdef SCPERF -#ifdef SCPERF_FIRST_APPEARANCE - -#define MAX_EVENTS 1024 - -struct timeval perf_tv[MAX_EVENTS]; -char *perf_buf[MAX_EVENTS]; -int perf_num = 0; - -void print_time () -{ - int i; - - for (i = 0 ; i < perf_num ; i ++ ) { - printf ("%ld.%06ld: %s\n", - perf_tv[i].tv_sec, perf_tv[i].tv_usec, perf_buf[i]); - } - return; -} - -#define SetTime(x) \ - gettimeofday(&(perf_tv[perf_num]), NULL); \ - perf_buf[perf_num] = x; \ - perf_num++; \ - if (perf_num >= MAX_EVENTS) {\ - fprintf (stderr, "SetTime overflow %d\n", MAX_EVENTS); \ - exit (1); \ - } - -#else /* !SCPERF_FIRST_APPEARANCE */ -extern struct timeval perf_tv[]; -extern char *perf_buf[]; -extern int perf_num; - -#define MAX_EVENTS 1024 - -#define SetTime(x) \ - gettimeofday(&(perf_tv[perf_num]), NULL); \ - perf_buf[perf_num] = x; \ - perf_num++; \ - if (perf_num >= MAX_EVENTS) {\ - fprintf (stderr, "SetTime overflow %d\n", MAX_EVENTS); \ - exit (1); \ - } -#endif /* SCPERF_FIRST_APPEARANCE */ -void print_time (); -#else /* !SCPERF */ -#define SetTime(x) -#define print_time() ; -#endif /* SCPERF */ - -/* macros */ -#ifdef SCFS -#define ADEBMISC 0x00000001 /* misc debugging */ -#define MESSAGE1(x) arla_warnx (ADEBMISC,x) -#define MESSAGE2(x,y) arla_warnx (ADEBMISC,x,y) -#define MESSAGE3(x,y,z) arla_warnx (ADEBMISC,x,y,z) -#define MESSAGE4(x,y,z,u) arla_warnx (ADEBMISC,x,y,z,u) -#define MESSAGE5(x,y,z,u,v) arla_warnx (ADEBMISC,x,y,z,u,v) -#define MESSAGE6(x,y,z,u,v,w) arla_warnx (ADEBMISC,x,y,z,u,v,w) -#else -#define MESSAGE1(x) fprintf(stderr,x) -#define MESSAGE2(x,y) fprintf(stderr,x,y) -#define MESSAGE3(x,y,z) fprintf(stderr,x,y,z) -#define MESSAGE4(x,y,z,u) fprintf(stderr,x,y,z,u) -#define MESSAGE5(x,y,z,u,v) fprintf(stderr,x,y,z,u,v) -#define MESSAGE6(x,y,z,u,v,w) fprintf(stderr,x,y,z,u,v,w) -#endif /* SCFS */ diff --git a/lib/libsectok/todos_atr.c b/lib/libsectok/todos_atr.c index f71311ece4a..850f5d091c6 100644 --- a/lib/libsectok/todos_atr.c +++ b/lib/libsectok/todos_atr.c @@ -1,4 +1,4 @@ -/* $Id: todos_atr.c,v 1.5 2001/06/18 16:00:50 rees Exp $ */ +/* $Id: todos_atr.c,v 1.6 2001/07/02 20:07:09 rees Exp $ */ /* copyright 1997, 1999, 2000 @@ -51,7 +51,7 @@ typedef long int32_t; #include <sys/types.h> #endif -#include "sectok.h" +#include "sc7816.h" #include "todos_scrw.h" #ifdef __unix__ |