summaryrefslogtreecommitdiff
path: root/lib/libsectok
diff options
context:
space:
mode:
authorJim Rees <rees@cvs.openbsd.org>2001-07-02 20:07:10 +0000
committerJim Rees <rees@cvs.openbsd.org>2001-07-02 20:07:10 +0000
commit3bb4c653100b0557977753c622bb3f03269640b5 (patch)
tree781f7c657e6140053f301beba954a40f3f064013 /lib/libsectok
parentadf9057e8e5d9b01ad93c03f8febd4119a51339e (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
Diffstat (limited to 'lib/libsectok')
-rw-r--r--lib/libsectok/atr.c4
-rw-r--r--lib/libsectok/cyberflex.c93
-rw-r--r--lib/libsectok/ifdhandler.c10
-rw-r--r--lib/libsectok/ifdhandler.h8
-rw-r--r--lib/libsectok/input.c12
-rw-r--r--lib/libsectok/r1r2.c140
-rw-r--r--lib/libsectok/sc7816.c430
-rw-r--r--lib/libsectok/scT1.c4
-rw-r--r--lib/libsectok/scio.c33
-rw-r--r--lib/libsectok/scrw.c16
-rw-r--r--lib/libsectok/sectok.c409
-rw-r--r--lib/libsectok/sectok.h216
-rw-r--r--lib/libsectok/todos_atr.c4
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, &param);
-
- 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__