diff options
author | Yuval Kashtan <ykashtan@redhat.com> | 2010-07-04 17:12:20 +0300 |
---|---|---|
committer | Yuval Kashtan <ykashtan@redhat.com> | 2010-07-04 17:12:20 +0300 |
commit | b82112f289aa8d8ec8866e6f3f18df974c2cbc81 (patch) | |
tree | e1abfe5c84045449996e7a9086785c49fe8eb282 |
initial commit
-rw-r--r-- | SCClient.c | 204 | ||||
-rw-r--r-- | scard_common.h | 16 |
2 files changed, 220 insertions, 0 deletions
diff --git a/SCClient.c b/SCClient.c new file mode 100644 index 0000000..cc52aae --- /dev/null +++ b/SCClient.c @@ -0,0 +1,204 @@ +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> + +#include <wintypes.h> +#include <pcsclite.h> +#include <winscard.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include "scard_common.h" + +#define APDUBufSize 65535 + +int +PrintByteArray ( + BYTE *arrBytes, + unsigned int nSize +) { + int i; + for (i=0; i < nSize; i++) { + printf ("%X ", arrBytes[i]); + } + printf ("\n"); +} + +void +PrintUsage () { + printf ("SCardClient <host> <port>\n"); +} + +int +main ( + int argc, + char *argv[] +) { + int sock; + struct sockaddr_in servaddr; + + SCRMsgHeader mhHeader; + + LONG rv; + SCARDCONTEXT hContext; + SCARDHANDLE hCard; + DWORD dwActiveProtocol, dwSendLength, dwRecvLength; + SCARD_IO_REQUEST pioRecvPci; + BYTE pbRecvBuffer[APDUBufSize]; + BYTE pbSendBuffer[APDUBufSize]; + //BYTE pbSendBuffer[] = { 0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 }; + + if (argc != 3) { + PrintUsage(); + exit (4); + } + + sock = socket ( + AF_INET, + SOCK_STREAM, + 0 + ); + if (sock < 0) { + /* Error */ + printf ("Error opening socket!\n"); + } + + memset (&servaddr, 0, sizeof (struct sockaddr_in)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr (argv[1]); + servaddr.sin_port = htons (atoi(argv[2])); + + if ( + connect ( + sock, + &servaddr, + sizeof(servaddr) + ) < 0 + ) { + /* Error */ + printf ("Could not connect\n"); + return (5); + } +printf ("Connected (sizeof Header=%d)!\n", sizeof (mhHeader)); + rv = SCardEstablishContext ( + SCARD_SCOPE_SYSTEM, + NULL, + NULL, + &hContext + ); + if (rv != SCARD_S_SUCCESS) { + printf ("SCardEstablishContext error (%d)\n", rv); + } + + rv = SCardConnect ( + hContext, + "Athena ASE IIIe 00 00", + SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0, + &hCard, + &dwActiveProtocol + ); + + if (rv != SCARD_S_SUCCESS) { + printf ("SCardConnect Error (%d)\n", rv); + exit (1); + } else { + printf ("!hCard=%x!\n", hCard); + } + + do { + rv = read ( + sock, + &mhHeader, + sizeof (mhHeader) + ); + if (rv < 0) { + /* Error */ + printf ("header read error\n"); + return (8); + } +printf ("Header: type=%d, nLength=%d", mhHeader.type, mhHeader.nLength); + switch (mhHeader.type) { + case SCard_APDU: + rv = read ( + sock, + pbSendBuffer, + mhHeader.nLength + ); + if (rv < 0) { + /* Error */ + printf ("read error\n"); + close (sock); + return (8); + } +printf ("recv APDU: "); +PrintByteArray (pbSendBuffer, mhHeader.nLength); + /* Transmit recieved APDU */ + dwSendLength = mhHeader.nLength; + dwRecvLength = sizeof(pbRecvBuffer); + rv = SCardTransmit ( + hCard, + SCARD_PCI_T0, + pbSendBuffer, + dwSendLength, + &pioRecvPci, + pbRecvBuffer, + &dwRecvLength + ); + if (rv != SCARD_S_SUCCESS) { + printf ("SCardTransmit Error (%d)\n", rv); + exit (12); + } + mhHeader.nLength = dwRecvLength; +printf ("send APDU: "); +PrintByteArray (pbRecvBuffer, mhHeader.nLength); + rv = write ( + sock, + &mhHeader, + sizeof (mhHeader) + ); + if (rv < 0) { + /* Error */ + printf ("write header error\n"); + close (sock); + return (16); + } + rv = write ( + sock, + pbRecvBuffer, + dwRecvLength + ); + if (rv < 0) { + /* Error */ + printf ("write error\n"); + close (sock); + return (16); + } + break; + default: + printf ("Default\n"); + } + } while (rv >= 0); + + + dwSendLength = sizeof(pbSendBuffer); + dwRecvLength = sizeof(pbRecvBuffer); + rv = SCardTransmit ( + hCard, + SCARD_PCI_T0, + pbSendBuffer, + dwSendLength, + &pioRecvPci, + pbRecvBuffer, + &dwRecvLength + ); + if (rv != SCARD_S_SUCCESS) { + printf ("SCardTransmit Error (%d)\n", rv); + exit (2); + } + + PrintByteArray (pbRecvBuffer, sizeof (pbRecvBuffer)); + return (0); +} diff --git a/scard_common.h b/scard_common.h new file mode 100644 index 0000000..c84bf5b --- /dev/null +++ b/scard_common.h @@ -0,0 +1,16 @@ +#ifndef _SCARD_COMMON_H +#define _SCARD_COMMON_H + +typedef enum { + SCard_ATR, + SCard_APDU, + SCard_Remove, + SCard_Quit +} MsgType; + +typedef struct SCRMsgHeader { + MsgType type; + unsigned int nLength; +} SCRMsgHeader; + +#endif |