summaryrefslogtreecommitdiff
path: root/lib/libsectok/sc7816.c
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/sc7816.c
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/sc7816.c')
-rw-r--r--lib/libsectok/sc7816.c430
1 files changed, 69 insertions, 361 deletions
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